【79期】别找了,回答Spring中Bean的生命周期,这里帮你总结好了!
共 4839字,需浏览 10分钟
·
2020-11-03 17:53
阅读本文大概需要 5 分钟。
来自:juejin.im/post/5a4ee1f6518825733e603fcb
ApplicationContext中Bean的生命周期
图中绿色箭头的三个步骤(InstantiationAwareBeanPostProcessor)和粉红色箭头的两个步骤(BeanPostProcessor)为容器级的生命周期接口,当Spring每加载任何一个Bean到容器中时,这些接口都会起到如图中的几次调用。这两个处理器叫做"容器级后处理器",他们的影响是全局的,能够影响所有的Bean.
图中大红色圆圈圈住的接口叫做"工厂级后处理器",类似的接口还有CustomEditorConfigurer,PropertyPlaceholderConfigurer等,这类接口只在上下文初始化的时候调用一次,其目的是完成一些配置文件的加工处理工作。
剩下的就简单了,属于Bean级别的接口,专属于某个Bean所有,每个Bean实例化的时候调用自己特有的。
这些接口的调用顺序并不是一尘不变的,会随便Spring的版本变动而变动,大家要做的是万变不离其宗,知道能够通过这些接口在Bean初始化的时做一些属性上的操作。调用顺序要根据具体的版本来自己测试。下面我会给大家来列一个例子:
public class Student implements BeanFactoryAware, BeanNameAware,
InitializingBean, DisposableBean,ApplicationContextAware {
private String name;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryAware......");
}
@Override
public void setBeanName(String s) {
System.out.println("BeanNameAware......");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean......");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean......");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware......");
}
}
public class MyBeanFactoryPostProcessor implements 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("student");
MutablePropertyValues propertyValues = bd.getPropertyValues();
//配置文件中的信息在加载到Spring中后以BeanDefinition的形式存在.在这里又可以更改BeanDefinition,所以可以理解为更改配置文件里面的内容
// propertyValues.add("zdy","123");
}
}
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor() {
super();
System.out.println("这是BeanPostProcessor实现类构造器!!");
}
@Override
public Object postProcessAfterInitialization(Object arg0, String arg1)
throws BeansException {
System.out.println("BeanPostProcessor接口方法After对属性进行更改!");
return arg0;
}
@Override
public Object postProcessBeforeInitialization(Object arg0, String arg1)
throws BeansException {
System.out.println("BeanPostProcessor接口方法Before对属性进行更改!");
return arg0;
}
}
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调用Before方法");
return null;
}
// 接口方法、实例化Bean之后调用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用Ater方法");
return bean;
}
// 接口方法、设置某个属性时调用
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法");
return pvs;
}
}
public class App
{
public static void main( String[] args )
{
ApplicationContext ac =new ClassPathXmlApplicationContext("applicationContext.xml");
Student stu = (Student) ac.getBean("student");
stu.setName("wangwu");
}
}
<beans
<bean id="student" class="com.zdy.Student">
<constructor-arg value="zhangsan"/>
bean>
<bean id="myBeanFactoryPostProcessor" class="com.zdy.MyBeanFactoryPostProcessor">bean>
<bean id="myInstantiationAwareBeanPostProcessor" class="com.zdy.MyInstantiationAwareBeanPostProcessor">bean>
<bean id="myBeanPostProcessor" class="com.zdy.MyBeanPostProcessor">bean>
beans>
这是BeanFactoryPostProcessor实现类构造器!!
BeanFactoryPostProcessor调用postProcessBeanFactory方法
这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!
这是BeanPostProcessor实现类构造器!!
InstantiationAwareBeanPostProcessor调用Before方法
InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
BeanNameAware......
BeanFactoryAware......
ApplicationContextAware......
BeanPostProcessor接口方法Before对属性进行更改!
InitializingBean......
InstantiationAwareBeanPostProcessor调用Ater方法
BeanPostProcessor接口方法After对属性进行更改!
上面的生命周期流程图,时候的时候注意调用先后顺序,避免属性被覆盖的现象。
BeanFactoryPostProcessor 主要是在Spring刚加载完配置文件,还没来得及初始化Bean的时候做一些操作。比如篡改某个Bean在配置文件中配置的内容。
InstantiationAwareBeanPostProcessorAdapter 基本没什么鸟用,Bean初始化后,还没有设置属性值时调用,和BeanFactoryPostProcessor一样,可以篡改配置文件加载到内存中的信息。
ApplicationContextAware:用处很大,注入了ApplicationContext到Bean中。
InitializingBean:有用处,可以在Bean属性全部改完之后,再做一些定制化操作。
BeanPostProcessor:没什么用,Spring框架内部使用的比较猛,像什么AOP,动态代理,都是在这搞事。后期有时间和大家分析。
其他的像什么init-method,destroy方法,基本都是个摆设。。我是没怎么用过,只知道有这么回事。
结语
推荐阅读:
【75期】面试官:说说Redis的过期键删除策略吧!(高频)
微信扫描二维码,关注我的公众号
朕已阅