BeanPostProcessor是一个接口,定义了两个方法,postProcessorBeforeInitialization()、postProcessorAfterInitialization()。
其中,postProcessorBeforeInitialization()方法在初始化方法执行之前,在构造方法之后执行;
postProcessorAfterInitialization()方法在初始化方法执行之后执行。
这个接口的作用主要就是在bean实例化之后,初始化前后对实例化生成的bean进行预置处理。它有很多的实现类,这里举出几个例子来分析这个接口的作用。
- AutowiredAnnotationBeanPostProcessor,这个PostProcessor功能就是完成@Autowired注解的功能实现
- 测试代码
@Component
public class Dog {
@Autowired
private Cat cat;
}
@Component
public class Cat {
}
2.标注断点:进入AutowiredAnnotationBeanPostProcessor类,在它的内部类AutowiredFieldElement的inject()方法上标注断点,这个内部类使用来处理属性赋值的
3. debug启动,发现进入到这个方法之中
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
//要赋值的属性,本例中为cat
Field field = (Field) this.member;
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
//这个方法就是从容器中提取出符合名字的bean,也就是Cat的bean实例
//如果没有这样的bean,或者有多个这样的bean,都是会报错的
//要注入的bean的名字和类型都存在desc属性中
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName)) {
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
//将从容器中获取的bean注入到对应的属性中
field.set(bean, value);
}
}
}
总的来说,在容器启动的时候,单实例bean被实例化,此后要对bean属性赋值,此时会查看有没有对属性赋值的PostProcessor(InstantiationAwareBeanPostProcessor)存在,如果有就调用它,@Autowired注解就作用在这个时候,AutowiredAnnotationBeanPostProcessor就是InstantiationAwareBeanPostProcessor的子类,因此会调用它的postProcessPropertyValues()方法,最终会调用到AutowiredFieldElement的inject()方法来完成属性注入。
以上过程分析请自行查看方法调用栈。
- ApplicationContextAwareProcessor,这个postProcessor的主要功能就是完成ApplicationContextAware接口向bean中注入ApplicationContext对象(也就是容器)的功能实现
1. 测试代码
@Component
public class Dog implements ApplicationContextAware, {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("setApplicationContext。。。。");
}
}
2. 原理分析:
此时dog Bean中就被注入了IOC容器,这是如何做到的?在方法上打个断点,debug,查看方法栈,发现这个方法执行之前执行了ApplicationContextAwareProcessor的postProcessBeforeInitialization()方法,这个方法里又调用了这个类中的invokeAwareInterfaces()方法。在这个方法里调用了ApplicationAware接口的setApplicationContext()方法。
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
ApplicationContextAwareProcessor.this.invokeAwareInterfaces(bean);
return null;
}
}, acc);
} else {
//方法调用
this.invokeAwareInterfaces(bean);
}
return bean;
}
//此方法被调用
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware)bean).setMessageSource(this.applicationContext);
}
//判断bean是不是ApplicationContextAware的实例,我们的例子中Dog类实现了
//ApplicationContextAware接口,自然就是它的实例,因而Dog类中实现的方法
//setApplicationContext()就被调用,容器对象就被注入到Dog的bean中
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
}
}