Factory hook that allows for custom modification of new bean instances,e.g. checking for marker interfaces or wrapping them with proxies.
允许自定义修改的新的对象实例的工厂钩子,检查标记性接口或者包装成一个代理对象。
ApplicationContexts can autodetect BeanPostProcessor beans in their bean definitions and apply them to any beans subsequently created. Plain bean factories allow for programmatic registration of post-processors,applying to all beans created through this factory.
ApplicationContexts可以在bean定义中自动检测BeanPostProcessor的beans并且将它们应用与随后创建的实例类中。 纯bean实例工厂允许后处理器的编程注册,适用于通过该工厂创建的所有bean实例。
Typically, post-processors that populate beans via marker interfaces or the like will implement {@link #postProcessBeforeInitialization}, while post-processors that wrap beans with proxies will normallyimplement {@link #postProcessAfterInitialization}.
通常,通过标记接口等填充bean的后处理器将实现{@link #postProcessBeforeInitialization方法},而用代理机构包装bean的后处理器通常会补充{@link #postProcessAfterInitialization方法}。
定义一个实体类:
public class Car {
private ApplicationContext applicationContext;
@Autowired
public void setApplication(ApplicationContext applicationContext) {
System.out.println("=========set=========");
this.applicationContext = applicationContext;
}
public void show(){
System.out.println("================show=========="+applicationContext.getClass());
}
public void init(){
System.out.println("===== Car init ==========");
}
}
@Configuration
public class MyConfig {
@Bean(initMethod="init")
public Car createCar(){
return new Car();
}
}
@Component
public class EchoBeanPostProcessor implements BeanPostProcessor{
/**
* 是在bean依赖装配(属性设置完)完成之后触发
* 这里可以对指定的bean做一些处理,比如说,返该对象的代理对象
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("=========postProcessBeforeInitialization=========" + bean.getClass());
//返回具体实例的代理对象
return bean;
}
/**
* 是在bean init方法执行之后触发的
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("=========postProcessAfterInitialization=========" + bean.getClass());
return bean;
}
}
测试:
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.zhihao.miao.bean.demo9");
Car car = context.getBean(Car.class);
System.out.println(car);
context.close();
}
}
打印结果:
=========postProcessBeforeInitialization=========class org.springframework.context.event.EventListenerMethodProcessor
=========postProcessAfterInitialization=========class org.springframework.context.event.EventListenerMethodProcessor
=========postProcessBeforeInitialization=========class org.springframework.context.event.DefaultEventListenerFactory
=========postProcessAfterInitialization=========class org.springframework.context.event.DefaultEventListenerFactory
=========postProcessBeforeInitialization=========class com.zhihao.miao.bean.demo9.MyConfig$$EnhancerBySpringCGLIB$$dbdd1e75
=========postProcessAfterInitialization=========class com.zhihao.miao.bean.demo9.MyConfig$$EnhancerBySpringCGLIB$$dbdd1e75
=========set=========
=========postProcessBeforeInitialization=========class com.zhihao.miao.bean.demo9.Car
===== Car init ==========
=========postProcessAfterInitialization=========class com.zhihao.miao.bean.demo9.Car
com.zhihao.miao.bean.demo9.Car@2d127a61
Apply this BeanPostProcessor to the given new bean instance before any bean initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
or a custom init-method). The bean will already be populated with property values.
The returned bean instance may be a wrapper around the original.
在任何bean初始化回调之前将此BeanPostProcessor应用于给定的新bean实例(如InitializingBean的afterPropertiesSet(也相当于初始化方法)或自定义init方法)。 该bean将已经使用属性值进行填充。返回的bean实例可能是原始实例的封装。
Apply this BeanPostProcessor to the given new bean instance after any bean
initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
or a custom init-method). The bean will already be populated with property values.
The returned bean instance may be a wrapper around the original.
在任何bean之后,将此BeanPostProcessor应用于给定的新Bean实例初始化回调(如InitializingBean的 afterPropertiesSet或自定义init方法)。 该bean将已经使用属性值进行填充。返回的bean实例可能是原始实例的封装。
In case of a FactoryBean, this callback will be invoked for both the FactoryBean
instance and the objects created by the FactoryBean (as of Spring 2.0). The
post-processor can decide whether to apply to either the FactoryBean or created
objects or both through corresponding {@code bean instanceof FactoryBean} checks.
在FactoryBean的情况下,被回调指定在FactoryBean实例或者FactoryBean创建的实例(从Spring 2.0开始)。该后处理器可以决定是应用于FactoryBean还是创建对象或两者通过相应的{@code bean instanceof FactoryBean}检查。
This callback will also be invoked after a short-circuiting triggered by a
{@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,in contrast to all other BeanPostProcessor callbacks.
回调函数将被执行在InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation的短路触发,与所有的BeanPostProcessor回调函数相反。
自己写一个demo
定义一个接口SpringContextAware,只要类实现这个接口SpringContextAware,就会自动得把ApplicationContext对象注入到当前对象的属性中。是不是很类似ApplicationContextAware的实现原理
定义接口:
@Component
public interface SpringContextAware {
void setApplicationContext(ApplicationContext applicationContext);
}
自己定义实例类继承SpringContextAware接口:
@Component
public class Dog implements SpringContextAware {
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public void show(){
System.out.println("dog:"+applicationContext.getClass());
}
}
定义一个类实现BeanPostProcessor,然后在postProcessBeforeInitialization中判断是否是实现SpringContextAware接口的实例
@Component
public class ContextBeanPostProcessor implements BeanPostProcessor {
@Autowired
private ApplicationContext applicationContext;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof SpringContextAware){
SpringContextAware sca = (SpringContextAware)bean;
sca.setApplicationContext(applicationContext);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
return bean;
}
}
打印结果:
dog:class org.springframework.context.annotation.AnnotationConfigApplicationContext