从源码可以看出,BeanPostProcessor
接口有postProcessBeforeInitialization
和postProcessAfterInitialization
两个方法
由于Bean对象实例化与初始化完全是两个过程,也就是说:
postProcessBeforeInitialization
方法会在Bean实例化和属性设置之后,自定义初始化方法InitializingBean
之前被调用,postProcessAfterInitialization
方法会在Bean实例化和属性设置之后,自定义初始化方法InitializingBean
之后被调用。
Spring自带了BeanPostProcessor
接口的很多实现类,例如
- AutowiredAnnotationBeanPostProcessor用于@Autowired注解的实现,
- AnnotationAwareAspectJAutoProxyCreator用于Spring AOP的动态代理等等。
以AnnotationAwareAspectJAutoProxyCreator
为例,简单说明一下后置处理器是怎样工作的。SpringAOP的实现原理是动态代理,最终放入容器的是代理类的对象,而不是Bean本身的对象,那么Spring是什么时候做到这一步的呢?就是在后置处理器AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization
方法中,即Bean对象初始化完成之后,后置处理器会判断该Bean是否注册了切面,若是,则生成代理对象注入到容器中。这一部分的关键代码是在哪儿呢?我们定位到AbstractAutoProxyCreator抽象类中的postProcessAfterInitialization方法处便能看到了,如下所示。
除此之外,我们还可以自定义BeanPostProcessor接口的实现类,在其中写入咱们需要的逻辑。
:::info
自定义BeanPostProcessor
:::
我们创建一个MyBeanPostProcessor类,实现BeanPostProcessor接口,如下所示。
package com.meimeixia.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* 后置处理器,在初始化前后进行处理工作
* @author liayun
*
*/
@Component // 将后置处理器加入到容器中,这样的话,Spring就能让它工作了
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessBeforeInitialization..." + beanName + "=>" + bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessAfterInitialization..." + beanName + "=>" + bean);
return bean;
}
}
接下来,我们应该是要编写测试用例来进行测试了
package com.meimeixia.bean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
public class Cat implements InitializingBean, DisposableBean {
public Cat() {
System.out.println("cat constructor...");
}
/**
* 会在容器关闭的时候进行调用
*/
@Override
public void destroy() throws Exception {
// TODO Auto-generated method stub
System.out.println("cat destroy...");
}
/**
* 会在bean创建完成,并且属性都赋好值以后进行调用
*/
@Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
System.out.println("cat afterPropertiesSet...");
}
}
将Car注册到容器中
package com.meimeixia.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import com.meimeixia.bean.Car;
@ComponentScan("com.meimeixia.bean")
@Configuration
public class MainConfigOfLifeCycle {
@Bean(initMethod="init", destroyMethod="destroy")
public Car car() {
return new Car();
}
}
直接运行IOCTest_LifeCycle类中的test01()方法就行,该方法的代码如下所示。
@Test
public void test01() {
// 1. 创建IOC容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器创建完成");
// 关闭容器
applicationContext.close();
}
输出的结果信息如下所示,但是我们的MyBeanPostProcessor
被默认放在了众多BeanPostProcessor
的最后
当然了也可以实现Ordered接口自定义BeanPostProcessor
的排序,如下所示。
package com.meimeixia.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
/**
* 后置处理器,在初始化前后进行处理工作
* @author liayun
*
*/
@Component // 将后置处理器加入到容器中,这样的话,Spring就能让它工作了
public class MyBeanPostProcessor implements BeanPostProcessor, Ordered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessBeforeInitialization..." + beanName + "=>" + bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessAfterInitialization..." + beanName + "=>" + bean);
return bean;
}
@Override
public int getOrder() {
// TODO Auto-generated method stub
return 3;
}
}