1.Spring容器

Spring容器最基本的接口就是BeanFactory, 负责配置,创建和管理bean。我们通常不直接使用BeanFactory接口,而是使用其子接口ApplicationContext.

接口ApplicationContext常用实现类是FileSystemXmlApplicationContext和ClassPathXmlApplicationContext等。后者最常用。

ApplicationContext的实例就是一个容器,Spring容器的意义在于创建和初始化类对象,管理类的依赖关系。

2.ApplicationContext的事件机制

AppicationContext的事件机制是观察者模式的实现,按以下方式可以实现。

  • 首先我们需要自定义一个事件类,此事件类是需要继承ApplicationEvent类
  • 然后我们定义一个监听类,监听类作为一个Spring容器中的bean,同时需要实现ApplicationListner接口
  • 然后我们就可以使用ApplicationContext的实例发布事件,相应监听类的实例(bean)负责监听具体的事件

下面是一个简单的例子,

事件类,必须继承ApplicationEvent,是否为Spring容器的bean无所谓,

 package spi;

 import org.springframework.context.ApplicationEvent;

 public class EmailEvent extends ApplicationEvent {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
private String text;
public EmailEvent(Object source) {
super(source);
}
public EmailEvent(Object source, String address, String text) {
super(source);
this.address = address;
this.text = text;
}
}

监听类,必须作为Spring容器的bean,同时需要实现ApplicationListener接口,重写onApplicationEvent方法

 package spi;

 import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener; public class EmailNotifier implements ApplicationListener { @Override
public void onApplicationEvent(ApplicationEvent evt) {
if (evt instanceof EmailEvent) {
EmailEvent emailEvent = (EmailEvent)evt;
System.out.println("邮件地址:"+emailEvent.getAddress());
System.out.println("邮件内容:"+emailEvent.getText());
} else {
System.out.println("其他事件:"+evt);
}
} }

将监听类配置进Spring容器配置文件中,并没有什么特殊之处,

<bean class="spi.EmailNotifier" />

下面写一个测试类,

     public static void test2() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
EmailEvent ele = new EmailEvent("test", "test@test.com", "this is a test");
ctx.publishEvent(ele);
}

执行测试类,发现我们不仅监听到了想要监听的事件EmailEvent,同时还有一个系统事件ContextRefreshedEvent也被监听到了,输出如下,

 其他事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.support.ClassPathXmlApplicationContext@1873eb2: startup date [Fri Feb 03 01:19:21 CST 2017]; root of context hierarchy]
邮件地址:test@test.com
邮件内容:this is a test

3.ApplicationContext的国际化支持

ApplicationContext接口继承了MessageSource接口,因此具有国际化功能。MessageSource接口提供了getMessage(...)方法用来进行字符串转换。

Spring要实现国际化,需要将MessageSource的实例配置成Spring容器中的bean,在bean的属性(即依赖注入)中配置国际化文件,

     <!-- ApplicationContext的实例将会查找是否有messageSource的实例并初始化它 -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<!-- 这里即依赖注入 -->
<property name="basenames">
<list>
<!-- 在这里添加国际化配置文件 -->
<value>message</value>
</list>
</property>
</bean>

为此我们需要创建两份国际化配置文件,第一份为英语,文件名 message_en_US.properties,内容如下,

 str1=welcome,{0}
str2=now is : {0}

第二份为中文,文件名为message.properties,内容如下,

 str1=欢迎,{0}
str2=现在时间是:{0}

由于这个文件包含了非西欧字符,因此我们用java自带的native2ascii进行转换,命令为

 cd C:\Program Files (x86)\Java\jdk1..0_79\bin\
native2ascii C:\PROJECT\JavaBasic\PROJECT_JavaBasic\src\message.properties C:\PROJECT\JavaBasic\PROJECT_JavaBasic\src\message_zh_CN.properties

转换后得到message_zh_CN.properties文件即可。

接着写一个测试类,

     public static void test3() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
String str1 = ctx.getMessage("str1", new String[]{"孙悟空"},
Locale.getDefault(Locale.Category.FORMAT));
String str2 = ctx.getMessage("str2", new Object[]{new Date()},
Locale.getDefault(Locale.Category.FORMAT));
System.out.println(str1);
System.out.println(str2); String str3 = ctx.getMessage("str1", new String[]{"孙悟空"},
Locale.US);
String str4 = ctx.getMessage("str2", new Object[]{new Date()},
Locale.US);
System.out.println(str3);
System.out.println(str4);
}

我们分别在中文环境和英文环境测试了两个字符串str1和str2,得到结果如下,

 欢迎,孙悟空
现在时间是:17-2-3 上午1:31
welcome,孙悟空
now is : 2/3/17 1:31 AM

上面的文字“孙悟空”因为是直接写在代码里面,不属于properties配置文件的,因此在中英文结果都保留原来的文字。

4.让Bean获取Spring容器

如果需要让Bean主动获取它所在的Spring容器的引用,可以让该Bean实现BeanFactoryAware接口,并实现setBeanFactory(BeanFactory beanFactory)方法。

下面是一个例子,

 package spi;

 import java.util.Locale;

 import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; public class GetContextViaBean implements ApplicationContextAware {
private ApplicationContext ctx;
@Override
public void setApplicationContext(ApplicationContext ctx)
throws BeansException {
this.ctx = ctx;
}
public void SayHi(String name) {
System.out.println(ctx.getMessage("str1", new String[]{name}, Locale.US));
} }

将这个类作为一个普通bean配置进Spring中,

<bean id="getContextViaBean" class="spi.GetContextViaBean" />

下面写一个测试类,来实现前面的国际化的功能,

     public static void test4() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
GetContextViaBean bean = ctx.getBean("getContextViaBean", GetContextViaBean.class);
bean.SayHi("孙悟空");
}

执行结果为,

 welcome,孙悟空

与前面国际化方式相比,其实本质上没有区别,只不过前面的国际化是在测试类中,直接使用ApplicationContext的实例调用MessageSource的getMessage()方法,

而这里是在Bean中,主动去获取所在容器(ApplicationContext)的引用,并在beanzhong通过ApplicationContext的引用调用了MessageSource的getMessage()方法。

Spring中的容器的更多相关文章

  1. Spring 中 IoC 容器简介

    IoC 是一种通过描述来生成或者获取对象的技术,可以说 Spring 是一种基于 IoC 容器编程的框架 在一个系统中可以生成各种对象,并且这些对象都需要进行管理.为了描述这些对象关系,我们需要一个容 ...

  2. spring中IOC容器注册和获取bean的实例

    spring中常用的功能主要的是ioc和aop,此处主要说明下,实例注册和使用的方法,此为学习后的笔记记录总结 1.使用xml文件配置 在idea中创建maven工程,然后创建实例Person,然后在 ...

  3. 深入了解Spring中的容器

    1.创建Bean的3种方式 1.1使用构造器创建bean实例 这是最常见的方式,如果不采用构造注入,bean类需要有默认构造函数.如果采用构造注入,则需要配置xml文件的<constructor ...

  4. spring中获取容器中的Bean为什么前转成接口而不是实现类

    简单介绍一下上下文,userService是服务层接口有一个save方法,userServiceImpl是该接口的实现类重写了save方法. applicationContext.xml如图: 后台代 ...

  5. 半夜思考之查漏补缺, Spring 中的容器后处理器

    之前学 Spring 的时候 , 还没听过容器后处理器 , 但是一旦写出来 , 就会觉得似曾相识 . 容器配置器通常用于对 Spring 容器进行处理 , 并且总是在容器实例化任何其他 Bean 之前 ...

  6. Spring中Ioc容器的注入方式

    1 通过setter方法注入 bean类: package com.test; public class UserServiceImplement implements IUserService { ...

  7. 挖坟之Spring.NET IOC容器初始化

    因查找ht项目中一个久未解决spring内部异常,翻了一段时间源码.以此文总结springIOC,容器初始化过程. 语言背景是C#.网上有一些基于java的spring源码分析文档,大而乱,乱而不全, ...

  8. Spring之IOC容器

    在前面博客中介绍什么是依赖注入时有提到:依赖注入是组件之间依赖关系由容器在运行期决定,即由容器动态的将某个依赖关系注入到组件之中.那什么是容器?既然Spring框架实现了IOC,那Spring中的容器 ...

  9. Spring中常见的设计模式——单例模式

    一.单例模式的应用场景 单例模式(singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.J2EE中的ServletContext,ServletCon ...

随机推荐

  1. luogu2437 蜜蜂路线

    题目大意 一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:蜜蜂从蜂房M开始爬到蜂房N,M<N,有多少种爬行路线?M,N<=1000 题解 看到M ...

  2. Linux - 设置SFTP服务用户目录权限

    我们有时会遇到这样的需求,限制一个Linux用户,让他只能在指定的目录下进行添加.修改.删除操作,并且只能使用sftp登录服务器,不能用ssh操作.这些可以通过配置sftp服务实现. 创建新用户www ...

  3. 国内物联网平台初探(七) ——Ablecloud物联网自助开发和大数据云平台

    平台定位 面向IoT硬件厂商,提供设备联网与管理.远程查看控制.定制化云端功能开发.海量硬件数据存储与分析等基础设施,加速硬件实现联网智能化. 架构 服务 云端服务一体化开发引擎 业内独创一体化开发引 ...

  4. python spark 求解最大 最小 平均

    rdd = sc.parallelizeDoubles(testData); Now we’ll calculate the mean of our dataset.   1 LOGGER.info( ...

  5. 【POJ 2286】 The Rotation Game

    [题目链接] http://poj.org/problem?id=2286 [算法] IDA* [代码] #include <algorithm> #include <bitset& ...

  6. 对象设计解耦的方法IOC和DI

    耦合关系不仅会出现在对象与对象之间,也会出现在软件系统的各模块之间,以及软件系统和硬件系统之间.如何降低系统之间.模块之间和对象之间的耦合度,是软件工程永远追求的目标之一.为了解决对象之间的耦合度过高 ...

  7. <T extends Serializable>这是什么意思呢?看明白这个,你的问题就自然而然的明白了!

    1.转自:https://blog.csdn.net/liwenqiang758/article/details/8131185 自己动手丰衣足食!!! 泛型是Java SE 1.5的新特性,泛型的本 ...

  8. Hadoop MapReduce编程 API入门系列之分区和合并(十四)

    不多说,直接上代码. 代码 package zhouls.bigdata.myMapReduce.Star; import java.io.IOException; import org.apache ...

  9. 用户注册登录验证 多版本集合 + hashlib加密

    #!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2018/5/6 0006 12:22# @Author : Anthony.Waa# @S ...

  10. pc端和移动端的轮播图实现(只是结构,内容以后慢慢补充)

    轮播图 PC端 移动端 原生js的写法 图片顺序 8123456781 设置计时器 当过度完成之后判断index是否到达两边界限,是的话设置位移 手指touchstart时,获取位置,暂停计时器 手指 ...