1
、容器
容器是Spring框架的核心。Spring容器使用IoC管理所有组成应用系统的组件,包括在协作组建之间建立关联。
1.1
、BeanFactory
Bean工厂(由BeanFactory接口定义)是最简单的容器,负责创建和分发Bean
在Spring中有几种BeanFactory的实现,XmlBeanFactory根据XML文件中的定义装载Bean
BeanFactory factory=new XmlBeanFactory(new FileInputStream(beans.xml))
这时,Bean工厂还没有实例化Bean。Bean是被延迟载入到Bean工厂中的,就是说,Bean工厂会立即把Bean定义信息载入进来,但是Bean只有在被需要的时候才被实例化
MyBean mybean=(MyBean) factory.getBean(“myBean”)
当getBean()方法被调用的时候,工厂就会实例化Bean并使用依赖注入开始设置Bean的属性,这样就在Spring容器中开始了Bean的生命周期
1.2
、ApplicationContext
ApplicationContext有很多实现,FileSystemXmlApplicationContext从文件系统的XML文件载入上下文定义信息
2
、Bean
的生命周期
在传统的Java应用中,Bean的生命周期非常简单。Java的关键字new用来实例化Bean,这样就够用了。Bean的生命周期在Spring容器中更加细致。
理解Spring Bean的生命周期非常重要,因为要利用Spring提供的机会来定制Bean的创建过程
3
、基本装配
在Spring容器内拼凑Bean叫做装配。装配Bean的时候需要告诉容器需要哪些Bean以及容器如何使用依赖注入将它们配合在一起
3.1
、使用XML
装配
理论上,Bean装配可以从任何配置源获得,包括属性文件、关系数据库
XML是最常见的Spring应用系统配置源
几种Spring容器都支持使用XML装配Bean,包括:
XmlBeanFactory
FileSystemXmlApplicationContext
这些面向XML的容器都使用XML文件来定义Bean。上下文定义文件的根元素是<beans>。<beans>有多个<bean>子元素。每个<bean>元素定义了一个Bean如何被装配到Spring容器中
原型与单实例:
Spring中的Bean缺省情况下是单实例模式。在容器中分配Bean的时候,它总是返回同一个实例
原型模式意味着定义一个Bean蓝图,而不是一个单一的Bean。每次从上下文请求一个Bean的时候得到一个不同的实例。BeanBean的实例都是按照这个蓝图创建的
实例化和销毁:
在Bean的定义中设置自己的init-method,这个方法在Bean被实例化的时候马上被调用,同样,也可以设置自己的destroy-method,这个方法在Bean从容器中删除之前调用
3.2
、通过Set
方法注入
注入依赖是一种基于标准命名规范的设置Bean属性的技术,JavaBean规范规定使用对应的set和get方法来设置和获得Bean的属性值
<bean>元素的子元素<property>指明了使用它们的set方法来注入。在<property>元素中,可以定义要配置的属性以及要注入的值
引用其他Bean:
使用<property>元素的子元素<ref>来设置指向其他Bean的属性
内部Bean:
另一种不常使用的装配Bean引用的方法是在<property>元素中嵌入一个<bean>元素
装配集合:
Spring支持多种类型的集合作为属性
Set注入的替代:
Set注入是一种装配Bean属性的直接方式。Set注入的一个缺点是它假设了多有的可变属性都可以通过set方法访问到
3.3
、通过构造函数注入依赖
构造函数注入通过<bean>元素下的<constructor-arg>元素来指定实例化这个bean的时候需要传递的参数。<constructor-arg>与<property>元素的区别是:<constructor-arg>元素没有name属性
解决构造函数参数的不确定性:
有两种方法解决构造函数的不确定性,通过序号或类型
<constructor-arg>元素的index属性,用来指定构造函数的顺序
<constructor-arg>元素的type属性来确切的指定每个<constructor-arg>中参数的类型
3.4
、自动装配
可以让Spring自动装配,只要设置需要自动装配的<bean>的autowire属性
4
、使用Spring
的特殊Bean
有些Bean通过实现特定的接口,可以让Spring特殊对待这些Bean——当作是Spring框架自身的一部分
4.1
、对Bean
进行后处理
Spring提供了两次机会切入到Bean的生命周期中,检察或修改它的配置,这叫做后处理
在Bean被创建以及装配之后,BeanPostProcessor接口提供了两次机会来修改这个Bean
PostProcessBeforeInitialization()方法在Bean初始化(也就是调用afterPropertiesSet()以及Bean指定的initmethod方法)之前被调用,PostProcessAfterInitialization()方法在初始化之后马上被调用
注册后处理Bean:
对于Bean工厂,调用工厂的addBeanPostProcessor()方法来注册BeanPostProcessor
对于应用上下文,只需像注册其他Bean那样注册后处理Bean,容器会自动识别BeanPostProcessor,并在每个Bean初始化的时候调用它的处理方法
4.2
、对Bean
工厂进行后处理
BeanFactoryPostProcessor在Bean工厂载入所有Bean的定义后,实例化所有Bean之前,对Bean工厂做一些后处理工作
使用应用上下文容器,只需要像普通Bean那样配置BeanFactoryPostProcessor,容器会自动将其注册为一个Bean工厂的后处理器。在Bean工厂容器中无法使用BeanFactoryPostProcessor
4.3
、分散配置
使用ApplicationContext当作Spring容器,在Spring中分离属性配置是很简单的。使用Spring的PropertyPlaceholderConfigurer告诉Spring从外部属性文件装载一些配置信息
4.4
、定制属性编辑器
java.beans.PropertyEditor接口提供了将字符串映射成非String类型的方法,有一个好用的该接口的实现——java.beans. PropertyEditorSupport,它有两个方法:
getAsText()方法返回一个表示属性值的字符串
setAxText(String value)将传递进来的字符串赋给Bean的属性
使用Spring的CustomEditorConfigurer注册自定义编辑器
4.5
、解析文本信息
Java对文本国际化的支持,使得能够定义一个或多个属性文件保存应用系统中需要显示的文本。每种语言应该有一个缺省的文本文件
Spring的ApplicationContext通过MessageSource接口为容器提供参数化信息支持:
Spring提供了一个现成的MessageSource实现,ResourceBundleMessageSource只是调用Java自己的ResourceBundle来解析信息。要使用ResourceBundleMessageSource,需要在Bean装配文件中添加配置信息
不需要通过messageSource注入到应用系统的Bean中,而是使用Application自己的getMessage()方法
4.6
、监听事件
在应用系统的生命周期中,应用上下文会发布很多事件,告诉感兴趣的监听器发生了什么事情。这些事件类都是ApplicationEvent的子类
如果需要一个Bean对系统事件做出回应,就要实现ApplicationListener接口,这个接口要求Bean实现onApplicationEvent()方法,这个方法负责处理系统事件
为了告诉Spring有一个系统事件监听器,需要像注册其他Bean那样注册这个Bean
当容器将这个Bean载入到应用上下文后,容器会注意到这个Bean实现了ApplicationListener接口,当有事件发布的时候,调用这个Bean的onApplicationEvent()方法
4.7
、发布事件
应用系统可以发布自己的事件,任何时间都是由ApplicationListener的实现来处理
ApplicationContext有个publishEvent()方法可以发布ApplicationEvent。任何一个注册到应用上下文的ApplicationListener都会通过onApplicationEvent()方法得到事件
4.8
、感知其他的Bean
Spring容器通过BeanNameAware接口告诉Bean它的注册名称,这个接口只有一个setBeanName()方法,用它获得装配文件中<bean>的id或name属性中设置的名字
Spring的ApplicationContextAware和BeanFactoryAware接口允许Bean可以知道它所在的容器。这两个接口分别定义了setApplicationContext()方法和setBeanFactory()方法。Spring容器将检测Bean是否实现了这两个接口中的任何一个,并且为其提供BeanFactory和ApplicationContext
5
、小结
Spring框架的核心是Spring容器,Spring有几种容器的实现,但是他们总共分为两类。BeanFactory是最简单的容器,它提供了基本的依赖注入和Bean装配服务。但是需要更多高级框架服务时,需要使用Spring的ApplicationContext容器
通常在Spring容器中使用XML文件完成装配,这个XML文件包含了应用系统的所有组件的配置信息,以及帮助容器实现Bean依赖装配的相关信息