[Spring]Bean在IOC容器的生命周期
2016-10-21 16:39
471 查看
Spring中整个Bean的生命周期经过了各个方法的调用,如下:
Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法
Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法。
容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
工厂后处理器接口方法:这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
首先介绍Bean级生命周期接口:BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean
我将这四个接口分为两类:
前两个接口负责在实例化Bean时,为Bean注入beanName(Bean在IOC容器的ID)与beanFactory属性
后两个接口负责为Bean进行实例化之前初始化和销毁时销毁。
下面介绍容器级生命周期接口:InstantiationAwareBeanPostProcessor 和 BeanPostProcessor
下面代码演示Bean的生命周期
Person - JavaBean
BeanFactoryPostProcessor接口的实现,可修改XML对Bean配置的元信息
InstantiationAwareBeanPostProcessorAdapter的实现
BeanPostProcessor的实现
XML配置信息
测试代码
运行结果
总结:
Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法
Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法。
容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
工厂后处理器接口方法:这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
首先介绍Bean级生命周期接口:BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean
我将这四个接口分为两类:
前两个接口负责在实例化Bean时,为Bean注入beanName(Bean在IOC容器的ID)与beanFactory属性
/** * BeanFactoryAware接口,只声明了一个方法:用来获取BeanFactory * BeanNameAware接口,只声明了一个方法:用来获取BeanName */
后两个接口负责为Bean进行实例化之前初始化和销毁时销毁。
/** * InitializingBean: * 在spring初始化bean的时候,如果该bean是实现了InitializingBean接口, * 并且同时在配置文件中指定了init-method, * 系统则是先调用InitializingBean的afterPropertiesSet方法, * 然后在调用init-method中指定的方法。 * */ /** * DisposableBean: * 在spring初始化bean的时候,如果该bean是实现了DisposableBean接口, * 并且同时在配置文件中指定了destroy-method, * 系统则是先调用DisposableBean的destroy方法, * 然后在调用destroy-method中指定的方法。 */
下面介绍容器级生命周期接口:InstantiationAwareBeanPostProcessor 和 BeanPostProcessor
/** * InstantiationAwareBeanPostProcessor 接口本质是 * BeanPostProcessor的子接口, * 一般我们继承Spring为其提供的适配器类 * InstantiationAwareBeanPostProcessorAdapter来使用它, * * 此接口可以在Bean实例化前、Bean实例化后分别进行操作 * 也可以对Bean实例化之后进行属性操作 */
/** * BeanPostProcessor接口包括2个方法 * postProcessAfterInitialization和postProcessBeforeInitialization, * 这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。 * 返回值也都是要处理的Bean对象。 * * 此接口的方法可以对Bean的属性进行更改 */
下面代码演示Bean的生命周期
Person - JavaBean
public class Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean{ /** * BeanFactoryAware接口,只声明了一个方法:用来获取BeanFactory * BeanNameAware接口,只声明了一个方法:用来获取BeanName */ /** * InitializingBean: * 在spring初始化bean的时候,如果该bean是实现了InitializingBean接口, * 并且同时在配置文件中指定了init-method, * 系统则是先调用InitializingBean的afterPropertiesSet方法, * 然后在调用init-method中指定的方法。 * */ /** * DisposableBean: * 在spring初始化bean的时候,如果该bean是实现了DisposableBean接口, * 并且同时在配置文件中指定了destroy-method, * 系统则是先调用DisposableBean的destroy方法, * 然后在调用destroy-method中指定的方法。 */ private String name; private BeanFactory beanFactory; private String beanName; public Person() { System.out.println("【构造器】调用Person的构造器实例化"); } public String getName() { return name; } public void setName(String name) { System.out.println("【注入属性】注入属性name,---name="+name); this.name = name; } @Override public String toString() { return "Person [name=" + name + "]"; } @Override public void destroy() throws Exception { System.out.println("【DiposibleBean接口】调用" + "DiposibleBean.destory()"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("【InitializingBean接口】调用" + "InitializingBean.afterPropertiesSet()"); } @Override public void setBeanName(String beanName) { System.out.println("【BeanNameAware接口】调用" + "BeanNameAware.setBeanName()---beanName="+beanName); this.beanName = beanName; } @Override public void setBeanFactory(BeanFactory arg0) throws BeansException { System.out.println("【BeanFactoryAware接口】调用" + "BeanFactoryAware.setBeanFactory()"); this.beanFactory = arg0; } // 通过<bean>的init-method属性指定的初始化方法 public void myInit() { System.out.println("【init-method】调用" + "<bean>的init-method属性指定的初始化方法"); } // 通过<bean>的destroy-method属性指定的初始化方法 public void myDestory() { System.out.println("【destroy-method】调用" + "<bean>的destroy-method属性指定的初始化方法"); } }
BeanFactoryPostProcessor接口的实现,可修改XML对Bean配置的元信息
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{ /** * BeanFactoryPostProcessor可以对bean的定义(配置元数据)进行处理。 * 也就是说,Spring IoC容器允许BeanFactoryPostProcessor * 在容器实际实例化任何其它的bean之前读取配置元数据,并有可能修改它。 * 如果你愿意,你可以配置多个BeanFactoryPostProcessor。 * 你还能通过设置'order'属性来控制BeanFactoryPostProcessor的执行次序。 * */ public MyBeanFactoryPostProcessor() { super(); System.out.println("这是BeanFactoryPostProcessor实现类构造器!!"); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) throws BeansException { System.out.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法"); BeanDefinition bd = arg0.getBeanDefinition("person1"); bd.getPropertyValues().addPropertyValue("name", "张三三"); } }
InstantiationAwareBeanPostProcessorAdapter的实现
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { /** * InstantiationAwareBeanPostProcessor 接口本质是 * BeanPostProcessor的子接口, * 一般我们继承Spring为其提供的适配器类 * InstantiationAwareBeanPostProcessorAdapter来使用它, * * 此接口可以在Bean实例化前、Bean实例化后分别进行操作 * 也可以对Bean实例化之后进行属性操作 */ public MyInstantiationAwareBeanPostProcessor (){ super(); System.out.println( "这是InstantiationAwareBeanPostProcessorAdapter" + "实现类构造器!!"); } // 接口方法、实例化Bean之前调用 @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessor" + "调用postProcessBeforeInstantiation方法"); return null; } /** * postProcessAfterInitialization重写了BeanPostProcessor的方法。 */ // 接口方法、实例化Bean之后调用 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessor" + "调用postProcessAfterInitialization方法"); return bean; } /** * 第三个方法postProcessPropertyValues用来操作属性,返回值也应该是PropertyValues对象 */ // 接口方法、设置某个属性时调用 @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessor" + "调用postProcessPropertyValues方法"); System.out.println("beanName="+beanName); return pvs; } }
BeanPostProcessor的实现
public class MyBeanPostProcessor implements BeanPostProcessor { /** * BeanPostProcessor接口包括2个方法 * postProcessAfterInitialization和postProcessBeforeInitialization, * 这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。 * 返回值也都是要处理的Bean对象。 * * 此接口的方法可以对Bean的属性进行更改 */ public MyBeanPostProcessor() { super(); System.out.println("这是BeanPostProcessor实现类构造器!!"); } @Override public Object postProcessAfterInitialization(Object obj, String objName) throws BeansException { Person person = (Person) obj; person.setName("之后--赵六"); System.out.println("BeanPostProcessor接口方法" + "postProcessAfterInitialization对属性进行更改!" + "---"+"obj="+obj+"---objName="+objName); return obj; } @Override public Object postProcessBeforeInitialization(Object obj, String objName) throws BeansException { Person person = (Person) obj; person.setName("之前--李四"); System.out.println("BeanPostProcessor接口方法" + "postProcessBeforeInitialization对属性进行更改!" + "---"+"obj="+obj+"---objName="+objName); return obj; } }
XML配置信息
<bean id="beanPostProcessor" class="com.bean.MyBeanPostProcessor"> </bean> <bean id="instantiationAwareBeanPostProcessor" class="com.bean.MyInstantiationAwareBeanPostProcessor"> </bean> <bean id="beanFactoryPostProcessor" class="com.bean.MyBeanFactoryPostProcessor"> </bean> <bean id="person1" class="com.bean.Person" init-method="myInit" destroy-method="myDestory" scope="singleton"> <property name="name" value="aaa"></property> </bean>
测试代码
public static void main(String[] args) { System.out.println("现在开始初始化IOC容器"); ApplicationContext context = new ClassPathXmlApplicationContext("spring2.xml"); System.out.println("IOC容器初始化成功"); Person person = (Person) context.getBean("person1"); System.out.println("使用person对象的toString:"+person); System.out.println("现在开始关闭容器!"); ((ClassPathXmlApplicationContext)context).registerShutdownHook(); }
运行结果
现在开始初始化IOC容器 这是BeanFactoryPostProcessor实现类构造器!! BeanFactoryPostProcessor调用postProcessBeanFactory方法 这是BeanPostProcessor实现类构造器!! 这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!! InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法 【构造器】调用Person的构造器实例化 InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 beanName=person1 【注入属性】注入属性name,---name=张三三 【BeanNameAware接口】调用BeanNameAware.setBeanName()---beanName=person1 【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory() 【注入属性】注入属性name,---name=之前--李四 BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!---obj=Person [name=之前--李四]---objName=person1 【InitializingBean接口】调用InitializingBean.afterPropertiesSet() 【init-method】调用<bean>的init-method属性指定的初始化方法 【注入属性】注入属性name,---name=之后--赵六 BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!---obj=Person [name=之后--赵六]---objName=person1 InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法 IOC容器初始化成功 使用person对象的toString:Person [name=之后--赵六] 现在开始关闭容器! 【DiposibleBean接口】调用DiposibleBean.destory() 【destroy-method】调用<bean>的destroy-method属性指定的初始化方法
总结:
整个Bean的生命周期 1、实例化BeanFactoryPostProcessor实现类 2、执行BeanFactoryPostProcessor的postProcessBeanFactory修改XML对Bean配置的元信息 3、实例化BeanPostProcessor实现类 4、实例化InstantiationAwareBeanPostProcessorAdapter实现类 5、InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法,Bean实例化之前调用此方法 new Bean(),开始进行注入属性 6、InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法,可以修改Bean的属性信息 7、读取第二步BeanFactoryPostProcessor的postProcessBeanFactory方法中修改的XML对Bean的配置的元信息,修改Bean的属性 8、调用BeanNameAware的setBeanName方法,为Bean注入beanName(Bean的ID) 9、调用BeanFactoryAware的setBeanFactory,为Bean注入BeanFactory 10、BeanPostProcessor实现类调用接口方法postProcessBeforeInitialization对属性进行更改 11、InitializingBean实现类调用afterPropertiesSet()进行Bean的初始化方法 12、调用<bean>的init-method属性指定的初始化方法 13、BeanPostProcessor实现类接口方法postProcessAfterInitialization对属性进行更改 Bean的属性注入完毕 14、InstantiationAwareBeanPostProcessor实现类调用postProcessAfterInitialization方法,Bean实例化之后调用此方法 15、IOC容器初始化成功,可以调用容器的Bean使用了 下面是销毁动作 16、调用DiposibleBean接口的destory方法 17、调用<bean>的destroy-method属性指定的销毁方法
相关文章推荐
- spring IOC 容器中 Bean 的生命周期
- spring-IOC容器bean生命周期
- Spring IOC容器中Bean的生命周期
- Spring 的 IOC 容器中 Bean 的生命周期
- (spring-第1回【IoC基础篇】)Spring容器中Bean的生命周期
- (七)SpringIOC容器中bean生命周期
- Spring4深入理解IOC&DI03----Bean配置--SpEL,IOC 容器中 Bean 的生命周期
- Spring的IOC、Spring对象初始化bean时机、Spring容器生命周期
- 《Spring 3.x 企业应用开发实战》学习笔记 第三章 IoC容器概述 3.5 Bean的生命周期
- 《Spring 3.x 企业应用开发实战》学习笔记 第三章 IoC容器概述 3.5 Bean的生命周期
- Spring-IOC容器之Bean的生命周期
- Spring学习-- IOC 容器中 bean 的生命周期
- Spring 学习第十天: IOC容器中Bean的生命周期
- spring 8 bean配置--IOC容器中bean的生命周期
- Spring的IOC、Spring对象初始化bean时机、Spring容器生命周期
- Spring重点—— IOC 容器中 Bean 的生命周期
- spring源码学习之路---IOC容器初始化要义之bean定义载入
- Spring IoC容器中Bean的作用范围详解
- spring源码学习之路---IOC容器初始化要义之bean定义载入(五)
- spring IOC容器实例化Bean的方式与RequestContextListener应用