bean被载入到容器中时,它的生命周期就开始了:
- 容器寻找bean的定义信息并实例化。
- 使用依赖注入,spring按bean定义信息配置bean的所有属性。
- 若bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递bean的ID。
- 若bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。
- 若BeanPostProcessor(bean后置处理器)和bean关联,则它们的
postProcessBeforeInitialization()方法被调用。 - 若bean指定了ini-method方法、,它将被调用。
- 最后,若有BeanPostProcessor和bean关联,则它们的postProcessAfterInitialization()方法被调用。
将bean从工厂中删掉有两种方法:
- 若bean实现了DisposableBean接口,distroy()方法被调用。
- 如果指定了定制的销毁方法,就调用这个方法。
Bean在Spring Bean应用上下文中的生命周期:
Bean在Spring Bean工厂中的生命周期:
Spring bean生命周期demo 源码下载
基本装配:
在spring容器内拼凑bean叫做装配。装配bean的时候,需要告诉容器哪些bean以及容器如何使用依赖注入将它们配合在一起。
- 使用XML装配
xml是最常见的spring应用系统配置源。几种spring容器都支持使用xml装配bean。
包括:
- XmlBeanFactory:调用ClassPathResource载入上下文定义文件(比如applicationContext.xml)。
- ClassPathXmlApplicationContext:从类路径载入上下文定义文件。
- XmlWebApplicationContext:从web应用上下文中载入定义文件。
上下文定义文件的根元素是.有多个子元素。每个元素定义了一个bean如何被装配到spring容器中。
<beans>
<bean id="foo" class="...Foo"/>
<bean id="bar" class="...Bar"/>
</beans>
添加一个bean
对bean的最基本的配置包括bean的ID和他的全称类名。
<bean id="foo" class="...Foo"/>
基本装配-scope
prototype、singleton、request 、session、global-session
spring中的bean缺省情况下是单例模式。始终返回一个实例。若想返回不同的实例的话需要定义成原型模式。
bean的singleton属性告诉上下文该bean是否为单例的。缺省为true。若为false的话,为原型bean。
<bean id="foo" class="...Foo" singleton="false"/>
实例化与销毁
1、spring实例化bean或销毁bean时,有时需要作一些处理工作,因此 spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法。
class="Foo" init-method destory-method>
@PostConstruct
public void ini(){
// do something
}
@PreDestroy
public void destroy(){
// do something
2、 Spring也提供了两个接口来实现相同的功能:
InitializingBean和DisposableBean.
InitializingBean接口提供了一个afterPropertiesSet()方法。
DisposableBean接口提供了destroy().
不推荐使用该接口,它将你的bean和springAPI邦定在一起。
通过set方法注入依赖
元素的子元素指明了使用它们的set方法来注入。可以注入任何东西,从基本类型到集合类,甚至是应用系统的bean。
1、简单bean配置
配置bean的简单属性,基本数据类型和string。
<bean id="foo" class="...Foo">
<property name="name">
<value>tom</value>
</property>
</bean>
2、引用其它bean
3、内部bean
<bean id="foo" class="...Foo">
<property name="bar">
<bean class="...Bar">
</property>
</bean>
这种方式的缺点是你无法在其它地方重用这个bar实例,原因是它是专门为foo而用。
基本装配:
- 继承
- 继承配置
- 覆盖父 Bean配置
可以设置 的abstract 属性为 true, Spring 不会实例化该Bean
<bean id="gradate" parent="student" class=“...Gradate">
装配集合
若bean的属性是集合类型,按如下处理:
1、装配List和数组:
<property name="barlist">
<list>
<value>bar1</value>
<ref bean="bar2"/>
</list>
</property>
2、装配set:
<property name="barlist">
<set>
<ref bean="bar2"/>
</set>
</property>
set使用方法和list一样,不同的是对象被装配到set中,而list是装配到List或数组中装配。
3、装配map:
<property name="barlist">
<map>
<entry key="key1" value="bar1"
<entry key="key2 value-ref="xxx"
</map>
</property>
key值必须是string的,key-ref可以是其他bean
4、装配Properties:
<property name="barlist">
<props>
<prop key="key1">bar1</prop>
<prop key="key2">bar2</prop>
</props>
</property>
若bean的属性是集合类型,按如下处理:
1、设置null:
<property name="barlist">
<null/>
</property>
2、Set注入的替代:
set注入是一种直接方式,也可通过构造函数设置一些属性值。
<constructor-arg index="0" type="java.lang.String" value="小明" />
<constructor-arg index="1" type="int" value="20"/>
<constructor-arg index="2" type="double" value="34.5"
set注入的缺点是无法清晰表达哪些属性是必须的,哪些是可选的,构造注入的优势是通过构造强制依赖关系,不可能实例化不完全的或无法使用的bean。
如果属性是类类型,则使用 ref=“”
自动装配
<bean id="foo" class="...Foo" autowire="autowire type">
有四种自动装配类型:
- byName寻找和属性名相同的bean,若找不到,则装不上。
- byType:寻找和属性类型相同的bean,找不到,装不上,找到多个抛异常。
- constructor:查找和bean的构造参数一致的一个或
多个bean,若找不到或找到多个,抛异常。按照参数的类型装配 - autodetect: (3)和(2)之间选一个方式。不确定性的处理与(3)和(2)一致。
- no : 不自动装配,这是autowrite的默认值.
- defualt : 这个需要在
<beans defualt-autorwire=“指定”
使用byType和constructor自动装配时,若找到多个符合条件的bean,会报异常,因此最好的方式是不用自动组装。
混合使用手动和自动组装
id="bar" class="...Bar" autowire="byName">
<property name="cousedao">
<ref bean="somebean" />
</property>
</bean>
缺省自动组装
默认不是自动组装。
通过:
<beans default-autowire="byName">
可将bean设置为自动组装。
spring2.5提供了<context:annotation-config/>
配置.
该配置可激活在类中探测到的各种注解,
- @Required
- @Autowire
- @PostConstrct
- @PreDestroy
- @Resource
- @EJB
- @PersistenceContext
- @WebServiceRef
等等,也可以选择为这些注解激活单独的后处理器.
例如:
- AutowiredAnnotationBeanPostProcessor(处理自动装配)
- CommonAnnotationBeanPostProcessor(生命周期等)
注意:该标记不能激活事务处理.需要使用tx:annotation-driven
使用spring的特殊bean
让spring特殊对待这些bean。使它们可以:
- 通过配置后加工bean,涉及到Bean和Bean工厂生命周期。
- 改变依赖注入,将字符串转换成其它类型。
- 从属性文本装载信息,包括信息国际化。
- 监听并处理其它bean及spring发布的系统消息。
- 知道自己在spring中的唯一表识。
对bean进行后处理
BeanPostProcessor接口提供机会来修改bean。
public interface BeanPostProcessor{
//Bean初始化(调用afterPropertiesSet()以及Bean的指
//定initmethod方法)之前被调用。
Object postProcessorBeforeInitialation(…);
//在初始化之后马上调用
注册后处理Bean
如果使用的是Bean工厂,需要调用工厂的addBeanPostProcessor()来注册.
factory.addBeanPostProcessor(…);
如果使用的是上下文同其他Bean一样:
<bean id="" class="……"
BeanPostProcessor在bean载入后,对bean进行一些后处理工作。而BeanFactoryPostProcessor在bean工厂载入所有bean的定义后,实例化bean之前,对Bean工厂做一些后处理工作。
public interface BeanFactoryPostProcessor{
public void postProcessorBeanFactory(…);
}
如果使用的是应用上下文不需要将他注册为Bean工厂后处理器。上下文会自动注册它。按照正常的Bean声明即可。
作者:jiankunking