一、分析BeanPostProcessor接口:
这个接口里面的两个方法每个Spring容器里面的Bean初始化时候都会调用,
一个是postProcessBeforeInitialization,
一个是postProcessAfterInitialization,
都是在bean属性设置完成后,进行调用。
postProcessBeforeInitialization在init方法之前调用,
postProcessAfterInitialization在之后调用。
这个接口是为什么ApplicationContextAware能够实现依赖注入的关键点。
我们可以利用这两个方法调用的时间,做一些bean初始化过程中的自定义的操作。
二、仿照Spring的ApplicationContextAware接口写一个自定义的依赖注入方法
(1)、声明SpringContextAwar接口
public interface SpringContextAwar {
public void setApplicationContext(ApplicationContext applicationContext);
}
(2)、创建EchoBeanProcessor,实现BeanPostProcessor接口
@Component
public class EchoBeanProcessor implements BeanPostProcessor {
@Autowired //spring容器上下文
private ApplicationContext applicationContext;
@Override
//bean init方法之前,属性设置之后执行
public Object postProcessBeforeInitialization(Object bean, String s) throws BeansException {
//instanceof可以判断接口继承,
//所以当spring容器初始化bean的时候,
//发现此bean实现了SpringContextAwar接口
//就将bean转为SpringContextAwar对象,
//通过SpringContextAwar的setApplicationContext方法将容器中的applicationContext当参数,
传入当前bean的setApplicationContext方法,
//从而完成依赖注入
if (bean instanceof SpringContextAwar){
SpringContextAwar awar=(SpringContextAwar)bean;
awar.setApplicationContext(applicationContext);
}
//实现动态代理
if (bean instanceof User){
System.out.println("*************postProcessBeforeInitialization************"+bean.getClass());
//动态代理,如果初始化的是User,就返回logUser对象,那么从spring容器中
//context.getBean(User.class)就是拿出的logUser对象。
}
return new logUser();
return bean;
}
@Override //bean init方法之后
public Object postProcessAfterInitialization(Object bean, String s) throws BeansException {
if (bean instanceof User){
System.out.println("*************postProcessAfterInitialization************"+bean.getClass());
}
return bean;
}
}
(3)、声明一个Dog类实现SpringContextAwar.接口
Dog.class
@Component
public class Dog implements SpringContextAwar {
private User user;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.user=applicationContext.getBean(User.class);
}
public void show(){
System.out.println("Dog show:"+user.getAge());
}
}
理解:
Spring的动态代理(AOP),依赖注入等等实现,基本上就是这个原理,
通过BeanPostProcessor接口的两个方法,在bean初始化的时候,
做一些处理(动态代理或者依赖注入).
依赖注入的实现:bean属性设置之后,发现本bean实现了SpringContextAwar方法,
于是在postProcessBeforeInitialization方法中将本dean转换为SpringContextAwar.
再通过SpringContextAwar调用setApplicationContext方法,
将Spring容器中的ApplicationContext对象注入到bean对应的属性中去,
然后要装配的bean(Dog)里面就可以通过ApplicationContext对象拿到任何Spring容器中的属性,
从而完成依赖注入。