Spring中bean的生命周期和方法注入和事务

  1.Bean生命周期

 

  可以在依赖注入过程之后或销毁之前执行特性行为(反射)

依赖注入过程:

  1:Bean的建立:容器寻找Bean的定义信息并将其实例化。

  2:属性注入:使用依赖注入,Spring按照Bean定义信息配置Bean所有属性

  3:BeanNameAware的setBeanName():如果Bean类有实现org.springframework.beans.BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。

  4:BeanFactoryAware的setBeanFactory():如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。

  5:BeanPostProcessors的ProcessBeforeInitialization()如果有org.springframework.beans.factory.config.BeanPostProcessors和Bean关联,那么其postProcessBeforeInitialization()方法将被将被调用。

  6:initializingBean的afterPropertiesSet():如果Bean类已实现org.springframework.beans.factory.InitializingBean接口,则执行他的afterProPertiesSet()方法

  7:Bean定义文件中定义init-method:可以在Bean定义文件中使用"init-method"属性设定方法名称。

  8:BeanPostProcessors的ProcessaAfterInitialization(),如果有任何的BeanPostProcessors实例与Bean实例关联,则执行BeanPostProcessors实例的ProcessaAfterInitialization()方法

销毁过程:

  1:DisposableBean的destroy(),在容器(ApplictionContext)关闭时,如果Bean类实现org.springframework.beans.factory.DisposableBean接口,则执行他的destroy()方法

  2:Bean定义文件中定义destroy-method,在容器关闭时,可以在Bean定义文件中使用"destroy-method"属性设定方法名称。

  2.方法注入

  在大部分情况下,容器中的bean都是singleton类型的。如果一个singleton bean要引用另外一个singleton bean,或者一个非singleton bean要引用另外一个非singleton bean时,通常情况下将一个bean定义为另一个bean的property值就可以了。

  不过对于具有不同生命周期的bean来说这样做就会有问题了,比如在调用一个singleton类型bean A的某个方法时,需要引用另一个非singleton(prototype)类型的bean B,对于bean A来说,容器只会创建一次,这样就没法在需要的时候每次让容器为bean A提供一个新的的bean B实例

  对于上面的问题Spring提供了三种解决方案: 

    • 放弃控制反转。通过实现ApplicationContextAware接口让bean A能够感知bean 容器,并且在需要的时候通过使用getBean("B")方式向容器请求一个新的bean B实例。
    • Lookup方法注入。Lookup方法注入利用了容器的覆盖受容器管理的bean方法的能力,从而返回指定名字的bean实例。
    • 自定义方法的替代方案。该注入能使用bean的另一个方法实现去替换自定义的方法。

  第一种方法,实现接口,造成了和Spring API耦合,严重污染了代码。第三种不常用。

  通常,采用方法注入。

  使用这种方式很简单,因为Spring已经为我们做了很大一部分工作,我们要做的就是bean配置和业务类。 

    • 首先修改CommandManager类为abstract的,修改createCommand方法也为abstract的。
    • 去掉ApplicationContextAware的实现及相关set方法和applicationContext变量定义
    • 修改bean配置文件,在commandManager Bean中增加<lookup-method name="createCommand" bean="asyncCommand"/>。
    • 其他保持不变

  这样,每次调用createCommand方法时都是生成一个新的实例,避免一直使用最早注入的Bean实例。

  实际上,Spring使用了CGLIB的库,使用动态代理来生成一个目标单例类的子类,重写lookup的方法(其中生成新的类)。

  3.Spring事务

  以方法为单位,进行事物控制;抛出异常,事物回滚。
  最小的执行单位为方法。决定执行成败是通过是否抛出异常来判断的,抛出异常即执行失败
  声明式事务(declarative transaction management)是Spring提供的对程序事务管理的方式之一。
  Spring的声明式事务顾名思义就是采用声明的方式来处理事务。这里所说的声明,就是指在配置文件中申明。用在Spring配置文件中声明式的处理事务来代替代码式的处理事务。这样的好处是,事务管理不侵入开发的组件,具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话,也只需要在定义文件中重新配置即可;在不需要事务管理的时候,只要在设定文件上修改一下,即可移去事务管理服务,无需改变代码重新编译,这样维护起来极其方便。
  Spring使用AOP来完成声明式的事务管理,因而声明式事务是以方法为单位,Spring的事务属性自然就在于描述事务应用至方法上的策略,在Spring中事务属性有以下四个参数:
  1.传播行为
  2.隔离级别
  3.只读提示
  4.事务超时期间

  

参考:http://developer.51cto.com/art/201104/255961.htm

http://flysnow.iteye.com/blog/733785

原文地址:https://www.cnblogs.com/jslee/p/3439178.html