浅谈Spring bean 生命周期验证

网友投稿 220 2023-03-23


浅谈Spring bean 生命周期验证

一、从源码注释看bean生命周期

从JDK源码上看,BeanFactory实现类需要支持Bean的完整生命周期,完整的初始化方法及其标准顺序(格式:接口 方法)为:

1.BeanNameAware setBeanName 设置bean名称

2.BeanClassLoaderAware setBeanClassLoader 设置bean类加载器

3.BeanFactoryAware setBeanFactory 设置bean工厂

4.EnvironmentAware setEnvironment 设置环境:profiles+properties

5.EmbeddedValueResolverAware setEmbeddedValueResolver 设置嵌入式值解析器

6.ResourceLoaderAware setResourceLoader 设置资源载入器,只适用于在应用程序上下文中运行

7.ApplicationEventPublisherAware setApplicationEventPublisher注入应用事件发布器ApplicationEventPublisher

8.MessageSourceAware setMessageSource 设置国际化支持

9.ApplicationContextAware setApplicationContext 设置应用上下文

10.ServletContextAware setServletContext 设置servlet上下文

11.BeanPostProcessors postProcessBeforeInitialization 执行bean处理器前置方法

12.InitializingBean afterPropertiesSet 执行初始化Bean设置完属性后置方法

13.a custom init-method definition 执行自定义初始化方法

14.BeanPostProcessors postProcessAfterInitialization 执行bean处理器后置方法

销毁顺序:

1.DestructionAwareBeanPostProcessors postProcessBeforeDestruction 销毁处理器的前置方法

2.DisposableBean destroy Bean销毁回调方法

3.a custom destroy-method definition 用户自定义销毁方法

核心方法流程图:

二、测试验证

2.1分析原理

前面说的17个步骤都可以测试,我们选取其中的8个步骤进行测试如下:

初始化流程:

1.BeanNameAware setBeanName 设置bean名称

3.BeanFactoryAware setBeanFactory 设置bean工厂

11.BeanPostProcessors postProcessBeforeInitialization 执行bean处理器前置方法

12.InitializingBean afterPropertiesSet 执行初始化Bean设置完属性后置方法

13.a custom init-method definition 执行自定义初始化方法

14.BeanPostProcessors postProcessAfterInitialization 执行bean处理器后置方法

销毁流程:

2.DisposableBean destroy Bean销毁回调方法

3.a custom destroy-method definition 用户自定义销毁方法

2.2 代码清单

1.构建一个Person类,实现BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean接口。

package spring.ioc;

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.BeanFactory;

import org.springframework.beans.factory.BeanFactoryAware;

import org.springframework.beans.factory.BeanNameAware;

import org.springframework.beans.factory.DisposableBean;

import org.springframework.beans.factory.InitializingBean;

public class Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {

private String name;

private String mobile;

public Person() {

super();

System.out.println("[构造器] 调用Person的构造器实例化");

}

public String getName() {

return name;

}

public void setName(String name) {

System.out.println("[属性注入] name="+name);

this.name = name;

}

public String getMobile() {

return mobile;

}

public void setMobile(String mobile) {

System.out.println("[属性注入] mobile="+mobile);

this.mobile = mobile;

}

@Override

public void destroy() throws Exception {

System.out.println("[接口DisposableBean.destroy() ]");

}

@Override

public void afterPropertiesSet() throws Exception {

System.out.println("[接口InitializingBean.afterPropertiesSet() ]");

}

@Override

public void setBeanName(String name) {

System.out.println("[接口BeanNameAware.setBeanName() ]");

}

@Override

public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

System.out.println("[接口BeanFactoryAware.setBeanFactory() ]");

}

public void myInit(){

System.out.println("[init-method]调用的init-method属性指定的初始化方法");

}

public void myDestory() {

System.out.println("[destroy-method]调用的destroy-method属性指定的销毁方法");

}

}

2.自定义工厂后处理器,复写postProcessBeanFactory方法,获取bean定义后添加属性mobile=110

package spring.ioc;

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.config.BeanDefinition;

import org.springframework.beans.factory.config.BeanFactoryPostProcessor;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

/**

*

* @ClassName:MyBeanFactoryPostProcessor

* @Description:自定义工厂后处理器

* @author diandian.zhang

* @date 2017年10月25日下午7:14:09

*/

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

public MyBeanFactoryPostProcessor() {

super();

System.out.println("[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor实现类构造器!!");

}

@Override

public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)

throws BeansException {

System.out.println("[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor.postProcessBeanFactory()获取bean定义后添加属性mobile=110");

BeanDefinition bd = arg0.getBeanDefinition("person");

bd.getPropertyValues().addPropertyValue("mobile", "110");

}

}

3.自定义Bean后处理器,复写postProcessBeforeInitialization和postProcessAfterInitialization2个方法,分别对应初始化前后时的操作。

package spring.ioc;

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.config.BeanPostProcessor;

/**

*

* @ClassName:MyBeanPostProcessor

* @Description:自定义Bean后处理器

* @author diandian.zhang

* @date 2017年10月25日下午7:03:53

*/

public class MyBeanPostProcessor implements BeanPostProcessor {

public MyBeanPostProcessor() {

super();

System.out.println("这是BeanPostProcessor实现类构造器!!");

}

/**

*

* @Description 初始化前,处理器

* @param bean

* @param beanName

* @return

* @throws BeansException

* @author diandian.zhang

* @date 2017年10月25日下午7:07:02

* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)

*/

@Override

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!beanName="+beanName);

return bean;

}

/**

*

* @Description 初始化后,处理器

* @param bean

* @param beanName

* @return

* @throws BeansException

* @author diandian.zhang

* @date 2017年10月25日下午7:07:07

* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)

*/

@Override

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!beanName="+beanName);

return bean;//注意,如果返回null,后续BeanPostProcessor不会再执行

}

}

4.自定义实例化bean后处理器适配器,复写postProcessBeforeInstantiation、postProcessBeforeInstantiation、postProcessPropertyValues分别对应实例化Bean前调用、实例化Bean后调用、设置某个属性时调用

注意:InstantiationAwareBeanPostProcessorAdapter ,这里是实例化Instantiation,不是初始化Initialization!!!

package spring.ioc;

import java.beans.PropertyDescriptor;

import org.springframework.beans.BeansException;

import org.springframework.beans.PropertyValues;

import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

/**

*

* @ClassName:MyInstantiationAwareBeanPostProcessor

* @Description:BeanPostProcessor的子类,增加了更多自定方法

* @author diandian.zhang

* @date 2017年10月25日下午7:09:15

*/

public class MyInstantiationAwareBeanPostProcessor extends

InstantiationAwareBeanPostProcessorAdapter {

public MyInstantiationAwareBeanPostProcessor() {

super();

System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");

}

// 接口方法、实例化Bean之前调用

@Override

public Object postProcessBeforeInstantiation(Class> beanClass,String beanName) throws BeansException {

System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法[实例化Bean之前调用 ]beanname="+beanName);

return null;

}

// 接口方法、实例化Bean之后调用

@Override

public Object postProcessAfterInitialization(Object bean, String beanName)

throws BeansException {

System.out .println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法[实例化Bean之后调用]beanname="+beanName);

return bean;

}

// 接口方法、设置某个属性时调用

@Override

public PropertyValues postProcessPropertyValues(PropertyValues pvs,

PropertyDescriptor[] pds, Object bean, String beanName)

throws BeansException {

System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 pvs="+pvs+",beanName="+beanName);

return pvs;

}

}

5.测试类,使用ClassPathXmlApplicationContext从xml中读取bean配置文件生成applicationContext容器应用上下文,这一步对应容器初始化。第二部从应用上下文中获取bean。最后一步注册一个关闭钩子,在容器关闭时触发。

package spring.ioc;

import org.junit.Test; 6 import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;10

import spring.aop.xml.dao.Dao;

/**

*

* @ClassName:IOCTest

* @Description:测试类

* @author diandian.zhang

* @date 2017年10月25日下午4:42:01

*/

public class IOCTest {

@Test

public void iocPersonTest(){

System.out.println("=============容器初始化======start=========");

@SuppressWarnings("resource")

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("simple_spring_bean.xml");//源码入口

System.out.println("=============容器初始化=======end========");

System.out.println("=============获取person bean====start=======");

Person person = applicationContext.getBean("person",Person.class);//获取Bean

System.out.println("=============获取person bean====end=======,person类名="+person.getClass().getName());

System.out.println("=============注册关闭钩子,关闭容器(JVM shutdown)时触发钩子!================");

((ClassPathXmlApplicationContext)applicationContext).registerShutdownHook();

}

}

直接运行,结果如下:

=============容器初始化======start=========

log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).

log4j:WARN Please initialize the log4j system properly.

[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor实现类构造器!!

[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor.postProcessBeanFactory()获取bean定义后添加属性mobile=110

这是BeanPostProcessor实现类构造器!!

这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!

InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法[实例化Bean之前调用 ]beanname=person

[构造器] 调用Person的构造器实例化

InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 pvs=PropertyValues: length=2; bean property 'mobile'; bean property 'name',beanName=person

[属性注入] mobile=110

[属性注入] name=张三

[接口BeanNameAware.setBeanName() ]

[接口BeanFactoryAware.setBeanFactory() ]

BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!beanName=person

[接口InitializingBean.afterPropertiesSet() ]

[init-method]调用的init-method属性指定的初始化方法

BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!beanName=person

Insthttp://antiationAwareBeanPostProcessor调用postProcessAfterInitialization方法[实例化Bean之后调用]beanname=person

=============容器初始化=======end========

=============获取person bean====start=======

=============获取person bean====end=======,person类名=spring.ioc.Person

=============注册关闭钩子,关闭容器(JVM shutdown)时触发钩子!================

[接口DisposableBean.destroy() ]

[destroy-method]调用的destroy-method属性指定的销毁方法

总结流程:


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java源码解析之GenericDeclaration详解
下一篇:vue路由跳转时判断用户是否登录功能的实现
相关文章

 发表评论

暂时没有评论,来抢沙发吧~