上一篇文章介绍了后置处理器在容器中的作用,本文章将记录后置处理器是如何处理bean的创建的,代理对象是如何被创建。
1、postProcessBeforeInstantiation
方法
之前介绍到了创建bean之前会先尝试返回一个代理对象而执行resolveBeforeInstantiation
操作。该方法就会遍历所有后置处理器,调用InstantiationAwareBeanPostProcessor
类型的后置处理器的postProcessBeforeInstantiation
方法。正好容器中@EnableAspectJAutoProxy为我们添加了该类型的后置处理器。所以每次单实例bean创建的时候都会调用该方法。(主要关注与aop相关的类LogAdvice (切面类)。Machine (需要被增强的对象)这两个类的具体在AOP初体验文章)
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
// 先尝试从缓存中获得该bean
Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
// 当前bean是否已经存在被增强的bean当中。(advicebean中保存了所以已经被增强的bean)
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
//回调子类重写的方法
//isInfrastructureClass(beanClass)判断是否是切面的基础类如:Advice Pointcut Advisor AopInfrastructureBean 否是切面(@Aspect)
//shouldSkip(beanClass, beanName)是否需要跳过
//1、获得所有的增强器List<Advisor>遍历并且判断类型
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
//返回null
return null;
}
}
2、postProcessAfterInstantiation
方法
当postProcessBeforeInstantiation
返回的不为null 的时候才会执行下面的方法(创建Machine 对象时返回的是null所有不会调用)
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
return true;
}
3、postProcessBeforeInitialization
方法
因为尝试返回一个代理对象失败,所以将执行doCreateBean方法。创建一个bean。然后在创建完成初始化之前会调用
applyBeanPostProcessorsBeforeInitialization方法,这个方法的内部就是,遍历所有后置处理器调用他们的postProcessBeforeInitialization
方法。当然也会调用AnnotationAwareAspectJAutoProxyCreator
的postProcessBeforeInitialization
方法。他就会执行在每次创建bean的时候执行下面操作。
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
4、postProcessAfterInitialization
方法
在调用完invokeInitMethods(beanName, wrappedBean, mbd);
初始化方法之后,也会遍历所有的后置处理器,执行他们的后置方法。所以每个bean创建的时候都会调用AnnotationAwareAspectJAutoProxyCreator
的postProcessAfterInitialization
方法。在这里也就是尝试创建一个代理对象。
前面都是准备工作。
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
// 尝试进行包装 返回代理对象
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
//$####################################wrapIfNecessary方法#######################################################
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//获得当前所有的增强器 找到候选的增强器 并且获得能被使用的增强器。返回拍好序的增强器链
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
//保存当前bean在advisedBeans中;
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//如果当前bean需要增强,创建当前bean的代理对象,spring自动决定创建哪种
//JdkDynamicAopProxy(config);jdk动态代理;
* //ObjenesisCglibAopProxy(config);cglib的动态代理;
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
//返回代理对象
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
执行到这里那么Machine
这个代理对象就被创建出来了。至于如何调用,将在下一篇博客记录
小结:一下这个包装方法wrapIfNecessary
1)、获取当前bean的所有增强器(通知方法) Object[] specificInterceptors
1、找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
2、获取到能在bean使用的增强器。
3、给增强器排序
2)、保存当前bean在advisedBeans中;
3)、如果当前bean需要增强,创建当前bean的代理对象;
1)、获取所有增强器(通知方法)
2)、保存到proxyFactory
3)、创建代理对象:Spring自动决定
JdkDynamicAopProxy(config);jdk动态代理;
ObjenesisCglibAopProxy(config);cglib的动态代理;
4)、给容器中返回当前组件使用cglib增强了的代理对象;