BeanPostProcessor的概念容易与BeanFactoryPostProcessor的概念混淆,看上去都是以PostProcessor,但两者不是同一个概念,用处也不同;BeanPostProcessor是存在于对象实例化后,进行初始化的阶段;而BeanFactoryPostProcessor则是存在于容器启动阶段;
BeanPostProcessor为bean的后置处理器,在bean初始化之前调用进行拦截,在bean初始化前后进行一些处理工作 ,说明此时的bean已经进行了实例化;
BeanPostProcessor接口声明了两个方法,分别在两个不同的时机执行;BeanPostProcessor的两个方法中都传入了原来的对象实例的引用,这为使用者扩展容器的对象实例化过程中的行为提供了极大的便利,使用者几乎可以对传入的对象实例执行任何的操作;
以下Spring版本为5.2.4.RELEASE
org.springframework.context.support.AbstractApplicationContext#refresh是Spring中一个很重要的方法,它用来加载配置,完成Spring上下文初始化工作,而refresh方法在org.springframework.context.ConfigurableApplicationContext接口定义;
- org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
postProcessBeforeInitialization方法是BeanPostProcessor前置处理这一步将会执行的方法,该方法会在org.springframework.beans.factory.InitializingBean#afterPropertiesSet或自定义init-method方法前执行;
org.springframework.beans.factory.InitializingBean#afterPropertiesSet,在初始化bean的时候执行,可以针对某个具体的bean进行自定义配置;
不过afterPropertiesSet方法是优先于init-method执行;
init-method方式有两种,如下;
-
-
- 在@Bean注解的initMethod属性添加该类自定义的初始化方法;
- 在@Bean注解的initMethod属性添加该类自定义的初始化方法;
-
org.springframework.context.annotation.Bean#initMethod
-
- Spring支持 JSR-250,可在该类自定义的初始化方法上添加@PostConstruct注解
@PostConstruct:在bean创建完成(即在构造方法执行完毕后执行),且属于赋值完成后进行初始化,属于JDK规范的注解;
@PreDestroy:在bean将被移除之前进行通知,在容器销毁之前进行清理工作;
这两个注解org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor是在这里进行处理的;
- org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
postProcessAfterInitialization方法是BeanPostProcessor后置处理那一步将会执行的方法,该方法会在org.springframework.beans.factory.InitializingBean#afterPropertiesSet或自定义init-method方法后执行;
- 具体调用,如下
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
bean在实例化后,进入初始化阶段;
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
该方法里面会有调用afterPropertiesSet和invokeCustomInitMethod;
afterPropertiesSet方法对实现了InitializingBean接口的类可以进行自定义初始化配置,在构造方法后执行;
invokeCustomInitMethod也是可以进行自定义初始化配置,在构造方法后执行,不需要实现InitializingBean接口;
自定义的init-method是在org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod设置的;
该方法是在org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors里面进行调用的,里面执行的是执行BeanFactoryPostProcessor的方法;
前面说到afterPropertiesSet方法执行优先于init-method,具体如下;
而invokeCustomInitMethod里面调用的是BeanDefinition的init-method方法;
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
该方法在自定义初始化配置前执行;遍历对应的Processors,并执行它相应的postProcessorsBeforeInitialization方法;
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
该方法在自定义初始化配置后执行;遍历对应的Processors,并执行它相应的postProcessorsAfterInitialization方法;
它的调用格式如下,这个相当于AOP,在invokeInitMethods的前后进行方法增强;
applyBeanPostProcessorsBeforeInitialization invokeInitMethods applyBeanPostProcessorsAfterInitialization
- 测试代码
Person2类
public class Person2 implements InitializingBean { private static final Logger logger = LoggerFactory.getLogger(Person2.class); private String name; private Integer age; public Person2() { logger.info("person2 constructor none params..."); } public Person2(String name, Integer age) { super(); this.name = name; this.age = age; logger.info("person2 constructor all params..."); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public void init() { logger.info("person2 init... " + this); } public void destory() { logger.info("person2 destroy..."); } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } @Override public void afterPropertiesSet() throws Exception { logger.info("afterPropertiesSet.."); } }
LifeCycleConfig1类
@Configuration @Import(value = {DemoBeanPostProcessor.class}) public class LifeCycleConfig1 { @Bean(initMethod = "init", destroyMethod = "destory") public Person2 person2() { return new Person2("dev", 33); } }
DemoBeanPostProcessor类
@Component public class DemoBeanPostProcessor implements BeanPostProcessor { private final static Logger logger = LoggerFactory .getLogger(DemoBeanPostProcessor.class); @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { // 返回一个的对象(传过来的对象) // 在初始化方法调用之前进行后置处理工作, // 什么时候调用它: init-method=init之前调用 logger.info("postProcessBeforeInitialization...." + beanName + "..." + bean); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { logger.info("postProcessAfterInitialization...." + beanName + "..." + bean); return bean; } }
测试类
@Test public void lifeCycleTest1() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(LifeCycleConfig1.class); System.out.println("IOC容器创建完成..."); context.close(); }
执行结果如下: