spring BeanPostProcessor 生命周期
BeanPostProcessor:后置解决器
spring使用模板模式,在bean的创立过程中安插了许多锚点,客户寻觅对应的锚点,通过重写方法介入到bean的创立过程当中。本节通过重写这些锚点,学习如何使用BeanPostProcessor、获取各类BeanAware并且理清bean的生命周期
代码
- 创立类LifeCycleBean
public class LifeCycleBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean { private BeanFactory beanFactory; private ApplicationContext applicationContext; private String name; public LifeCycleBean(String name) { System.out.println("2. 构造方法被调用,name:" + name); this.name = name; } @Override public void setBeanName(String name) { System.out.println("5. BeanNameAware被调用, 获取到的beanName:" + name); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; System.out.println("6. BeanFactoryAware被调用,获取到beanFactory:" + beanFactory); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; System.out.println("7. ApplicationContextAware被调用,获取到ApplicationContextAware:" + applicationContext); } @Override public void afterPropertiesSet() throws Exception { System.out.println("9. afterPropertiesSet被调用"); } public void myInit() { System.out.println("10. myInit自己设置初始化方法被调用,name:" + getName()); } @Override public void destroy() throws Exception { System.out.println("13. DisposableBean被调用"); } public void myDestroy() { System.out.println("14. destroy-method自己设置销毁方法被调用"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public BeanFactory getBeanFactory() { return beanFactory; } public ApplicationContext getApplicationContext() { return applicationContext; }}- 创立BeanPostProcessor后置解决器(postProcessProperties过时了,这里就不演示了)
public class LifeCycleBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if (beanName.equals("lifeCycleBean")) { System.out.println("1. postProcessBeforeInstantiation被调用"); } return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if (beanName.equals("lifeCycleBean")) { System.out.println("3. postProcessAfterInstantiation被调用"); } return true; } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { if (beanName.equals("lifeCycleBean")) { System.out.println("4. postProcessProperties被调用"); } return null; }// @Override// public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {// return pvs;// } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("lifeCycleBean")) { ((LifeCycleBean) bean).setName("中中"); System.out.println("8. postProcessBeforeInitialization被调用,把name改成中中"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("lifeCycleBean")) { ((LifeCycleBean) bean).setName("大大"); System.out.println("11. postProcessAfterInitialization被调用,把name改成大大"); } return bean; }}- xml配置文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="lifeCycleBean" class="lifeCycle.LifeCycleBean" destroy-method="myDestroy" init-method="myInit"> <constructor-arg value="小小"/> </bean> <bean id="lifeCycleBeanPostProcessor" class="lifeCycle.LifeCycleBeanPostProcessor"/></beans>- 测试类
/** * @author: chaitou */public class LifeCycleTest { @Test public void test() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("lifeCycle.xml"); LifeCycleBean myLifeCycleBean = applicationContext.getBean("lifeCycleBean", LifeCycleBean.class); System.out.println("12. bean创立完成 name: " + myLifeCycleBean.getName()); ((ClassPathXmlApplicationContext) applicationContext).destroy(); }}结果
// 控制台的输出结果1. postProcessBeforeInstantiation被调用2. 构造方法被调用,name:小小3. postProcessAfterInstantiation被调用4. postProcessProperties被调用5. BeanNameAware被调用, 获取到的beanName:lifeCycleBean6. BeanFactoryAware被调用,获取到beanFactory:org.springframework.beans.factory.support.DefaultListableBeanFactory@117e949d: defining beans [lifeCycleBean,lifeCycleBeanPostProcessor]; root of factory hierarchy7. ApplicationContextAware被调用,获取到ApplicationContextAware:org.springframework.context.support.ClassPathXmlApplicationContext@71e9ddb4, started on Sat Feb 22 20:30:35 CST 20208. postProcessBeforeInitialization被调用,把name改成中中9. afterPropertiesSet被调用10. myInit自己设置初始化方法被调用,name:中中11. postProcessAfterInitialization被调用,把name改成大大12. bean创立完成 name: 大大13. DisposableBean被调用14. destroy-method自己设置销毁方法被调用Process finished with exit code 0分析总结
BeanPostProcess
实例化相关:postProcessBeforeInstantiation、postProcessAfterInstantiation
填充属性相关:postProcessProperties、postProcessPropertyValues(已过时没有演示)
初始化相关:postProcessBeforeInitialization、postProcessAfterInitialization
通过重写BeanPostProcess的方法,可以介入bean创立的不同环节。同时通过postProcessBeforeInitialization将bean的name属性值从小小改成了中中,又通过postProcessAfterInitialization将中中改成了大大,成功介入了bean的创立,并且依据我们的意愿修改了beanBeanNameAware、BeanFactoryAware、ApplicationContextAware
这3类不属于后置解决器的范畴,学名叫感知器,让bean能感知到整个容器上下文信息的接口。spring在创立过程中,通过回调子类的setBeanName, setBeanFactory, setApplicationContext实现了BeanName, BeanFactory, ApplicationContext的注入,让bean能够感知获取到spring上下文的相关信息。尽管实现的东西很牛逼,但是实现的原理一点不复杂。通过检测当前的bean能否实现相关Aware,假如实现则调用子类set方法,将当前的BeanFactory等作为参数传入,直接上源码,看不懂可以参考这篇源码:spring源码日记17: 初始化
private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }最后贴出总结后的流程图
spring创立Bean .jpg
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » spring BeanPostProcessor 生命周期