Spring框架的IoC
本文来源:主要参考并整理《Spring专业开发指南》第1章--第5章内容。
《Spring专业开发指南》:Rob Harrop,Jan Machacek著,Redsaga翻译小组译,电子工业出版社出版。
1.IoC简介
IoC提供了这样的服务,使一个组件能够在它的整个生命周期中访问它的依赖和服务。
IoC被分解为依赖注入和依赖查找两种子类型。
依赖注入的方式:构造器注入、Setter注入、基于注解的注入。
Spring的依赖注入容器的核心是Bean工厂。Bean工厂负责管理组件和它们之间的依赖关系。
BeanFactory的两个主要实现:DefaultListableBeanFactory、XmlBeanFactory(派生自DefaultListableBeanFactory并进行了扩展)。两者分别用到PropertiesBeanDefinitionReader和XmlBeanDefinitionReader来加载配置文件。
2.Bean的配置
使用构造器注入配置bean:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bean1" name = "firstBean" class="com.yourcompany.spring.beans.FirstBean" >
<constructor-arg value="testbean"></constructor-arg>
</bean>
</beans>
使用Setter注入:
需要在<bean>标记下指定<property>标记。可以使用<ref>标记将一个bean的引用分配个一个属性。
<beans >
<bean id="bean1" name = "firstBean" class="com.yourcompany.spring.beans.FirstBean" >
<constructor-arg value="testbean"></constructor-arg>
</bean>
<bean id="bean2" class="com.yourcompany.spring.beans.SecondBean">
<property name="bean1">
<ref bean="firstBean" />
</property>
</bean>
</beans>
实例化模式
Spring中所有的Bean默认都被创建为单例实例。
非单例实例需要使用singleton="false"指定。
<bean id="bean1" name = "firstBean" class="com.yourcompany.spring.beans.FirstBean" singleton="false">
<constructor-arg value="testbean"></constructor-arg>
</bean>
解析依赖控制实例化顺序
<bean id="bean1" name = "firstBean" class="com.yourcompany.spring.beans.FirstBean" > </bean>
<bean id="bean2" class="com.yourcompany.spring.beans.SecondBean" depends-on="bean1"> </bean>
3.Bean的生命周期管理
两个重要的生命周期事件:post-initialization和pre-destruction。
post-initialization在Spring完成bean全部属性值设定,及结束让bean执行的依赖关系检查后触发。
pre-destruction在Spring销毁bean实例之前触发。
Spring提供interface-based、method-based两种机制。
interface-based机制下,通过实现InitializingBean接口,由接口的afterPropertiesSet 方法处理post-initialization事件。通过实现接口DisposableBean,由接口的destroy方法处理pre-destruction事件。
method-based机制下,在bean的<bean>标签的init-method属性指定post-initialization事件回调方法,destroy-method属性指定pre-destruction事件回调方法。
Spring中destruction回调需记得在应用程序关闭之前主动调用destroySingletons。如果程序有多个退出点,可以使用Shutdown Hook,在它的run方法里调用ConfigurableListableBeanFactory的destroySingletons方法。
4.方法注入
Spring的Method Injection功能有两种相关形式:Lookup Method Injection和(查找方法注入)Method Replacement(方法替代)。
Lookup Method Injection解决单例bean实例对非单例实例依赖的问题。
Method Replacement则可任意替换bean方法的实现,同时无需修改bean方法的源码。
5.FactoryBean
FactoryBean扮演其塔bean的工厂的bean。像其他bean一样进行配置。不过Spring使用FactoryBean时返回FactoryBean.getObject()方法的调用结果,而不是返回FactoryBean。
6.ApplicationContext
Spring的ApplicationContext是对BeanFactory的扩展,减少了交互所需代码量,增加了一些新特性。例如所有注册在ApplicationContext里的BeanFactoryPostProcessor都会自动执行。在构建Web应用时,Spring会提供支持类自动把ApplicationContext加载到应用程序中。ApplicationContext还提供了国际化、额外的生命周期接口、经改良的基础性组件自动装配、应用程序事件等特性。
6.1 ApplicationContext的实现
1)FileSystemXmlApplicationContext,可以载入位于文件系统任意位置的配置文件;
2)ClasspathXmlApplicationContext,可载入位于classpath里的配置;
3)XmlWebApplicationContext,仅供web应用环境中使用。
bean实现BeanFactoryAware接口之后就能取得其BeanFactory的引用。
同样bean实现ApplicationContextAware接口之后就能取得其ApplicationContext的引用。
6.2 应用程序事件
ApplicationContext的另一特性是将自己作为代理发布和接收事件。使用ApplicationContext的publishEvent(MessageEvent)这样的方法发布事件。
事件是继承自ApplicationEvent的类。只要实现了ApplicationListener接口,任何bean都能监听到事件(Spring会自动把实现丐姐库的bean注册为监听者)。