您的位置:首页 > 编程语言 > Java开发

Spring学习笔记二: Bean装配及生命周期

2016-07-14 20:46 756 查看
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的两个生命周期方法。

<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,会报异常,因此最好的方式是不用自动组装。

混合使用手动和自动组装

<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(…);
//在初始化之后马上调用
Object postProcessorAfterInitialization(…);
}


注册后处理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 出处:http://blog.csdn.net/jiankunking

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: