目录
1. 说明
AnnotationAwareAspectJAutoProxyCreator作为InstantiationAwareBeanPostProcessor和BeanPostProcessor子类,在普通组件被创建的时候,在创建之前会调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation尝试创建一个代理类,在组件被创建并属性赋值后,在执行自定义初始化方法的时候会分别执行BeanPostProcessor的postProcessBeforeInitialization方法和postProcessAfterInitialization方法;
所以,就是在需要被代理的目标类在创建的时候,在这些方法中被判断、增强,最后将增强后的代理类放入到IOC容器中,供后续使用;
2. 目标类创建过程
1). 通过配置类,创建IOC容器
2). 注册配置类,调用refresh();刷新容器;
3). 刷新容器过程中,finishBeanFactoryInitialization(beanFactory)会完成到这一步还没有被创建的单实例组件,
3.1) 遍历获取容器中所有的Bean,依次创建对象getBean(beanName): getBean->doGetBean()->getSingleton()->先从缓存中获取,没有就调用createBean()创建组件;
3.2) 在createBean()创建bean的过程中
3.2.1) resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation,希望后置处理器在此能返回一个代理对象;如果能返回代理对象就使用;
3.2.2) 如果没有创建代理对象,则调用doCreateBean(beanName, mbdToUse, args);真正的去创建一个bean实例;
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])创建组件的过程代码如下:
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 尝试通过BeanPostProcessors给目标类创建一个代理类,这里面是通过InstantiationAwareBeanPostProcessor来实现的
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
3. 目标类创建之前尝试生成代理
在真正创建组件之前,Spring会尝试通过BeanPostProcessor(这里指的是InstantiationAwareBeanPostProcessor)创建出代理类,如果创建成功,这直接将创建的代理类注册到IOC容器中,就是createBean()中的resolveBeforeInstantiation()方法;
因为AnnotationAwareAspectJAutoProxyCreator也是InstantiationAwareBeanPostProcessor的子类,所有也会被调用,尝试通过AbstractAutowireCapableBeanFactory的resolveBeforeInstantiation生成代理类,具体实现在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(String, RootBeanDefinition)的代码如下:
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 判断是否允许在创建组件对象前解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
// 判断容器中是否有InstantiationAwareBeanPostProcessor组件
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 调用所有InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法
// 这里就会调用AnnotationAwareAspectJAutoProxyCreator的父类的postProcessBeforeInstantiation方法
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//如果创建成功,则调用所有BeanPostProcessor的postProcessAfterInitialization方法
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
其中,AbstractAutoProxyCreator的postProcessBeforeInstantiation的实现如下:
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
/**
isInfrastructureClass(beanClass):
判断是不是aop的基础类,就是Advice,Pointcut,Advisor,AopInfrastructureBean的子类或者被@Aspect标记的类,所以非切面类这里不会跳过,还会继续往下走,所有的切面类这里直接返回;
shouldSkip(beanClass, beanName):
获取候选的增强器(切面里面的通知方法)【List<Advisor> candidateAdvisors】,每一个封装的通知方法的增强器是InstantiationModelAwarePointcutAdvisor,判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;
返回true如果是AspectJPointcutAdvisor的子类,则跳过,这里目标类返回false;
*/
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
// 切面类在advisedBeans[是否是增前Bean]的集合中标记为false,表示切面类是不增强的
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
// 这里也没有自定义的目标,返回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;
}
}
return null;
}
所以目标类到这里没有通过 InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法创建出代理对象,最终还是调用AbstractAutowireCapableBeanFactory的doCreateBean方法创建Bean;
4. 目标类被增强生成代理类
通过doCreateBean创建组件的时候,调用AbstractAutowireCapableBeanFactory的initializeBean()方法执行目标类初始化的时候,在执行自定义初始化方法的后面,会调用BeanPostProcessor的postProcessAfterInitialization,所以就来到了AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator的postProcessAfterInitialization()方法中,具体代码如下:
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* @see #getAdvicesAndAdvisorsForBean
* org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(Object, String)
*/
@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;
}
其中org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(Object, String, Object)的代码如下:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 判断是否不需要增强的,切面类在AbstractAutoProxyCreator的postProcessBeforeInstantiation中就会标记为不增强,所有切面类到这里就直接返回组件
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 跟AbstractAutoProxyCreator的postProcessBeforeInstantiation中的一样,判断是否是aop的基础类的子类或者是否需要掉过,普通组件是不跳过的
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 这里很关键,通过目标组件找出与之相关的所有切面方法,封装为Object[] specificInterceptors, specificInterceptors的值如下:
/**
[org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,
InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.afterThrowing(org.aspectj.lang.JoinPoint,java.lang.Exception)]; perClauseKind=SINGLETON,
InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.afterReturning(org.aspectj.lang.JoinPoint,java.lang.Object)]; perClauseKind=SINGLETON,
InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.after(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,
InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.before(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]
*/
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 如果有与目标类相关的切面,则生成组件的代理对象
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;
}
其中在getAdvicesAndAdvisorsForBean()方法中,执行了如何找出与目标类匹配的增强器(通知方法),具体流程如下:
1). 获取当前bean的所有增强器(通知方法) Object[] specificInterceptors
1.1). 找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
1.2). 获取到能在bean使用的增强器。
1.3). 给增强器排序,排序很重要,涉及到增强器转为拦截器链的调用顺序,
排序优先级是 @AfterThrowing > @AfterReturning > @After > @Before
2). 保存当前bean在advisedBeans中;
3). 如果当前bean需要增强,创建当前bean的代理对象;
3.1). 获取所有增强器(通知方法)
3.2). 保存到proxyFactory
3.3). 创建代理对象:Spring自动决定
JdkDynamicAopProxy(config);jdk动态代理;
ObjenesisCglibAopProxy(config);cglib的动态代理;
4). 给容器中返回当前组件使用cglib增强了的代理对象;
5). 以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;
找出与目标类匹配的增强器的具体代码流程如下:
//找出与组件相关的所有增强器(通知方法)
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 想找出所有增强器(通知方法)
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 这里面就是根据切面类的切面表达式与目标类进行匹配
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 把与目标组件匹配的增强器进行排序(排序很重要,涉及到后面的目标方法调用,触发增强器调用链执行的流程)
// 排完序的增强器如下:
/**
[org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,
InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.afterThrowing(org.aspectj.lang.JoinPoint,java.lang.Exception)]; perClauseKind=SINGLETON,
InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.afterReturning(org.aspectj.lang.JoinPoint,java.lang.Object)]; perClauseKind=SINGLETON,
InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.after(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,
InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.before(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]\
排序优先级是 @AfterThrowing > @AfterReturning > @After > @Before
*/
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
// 返回所有与目标相关的增强器(通知方法)
return eligibleAdvisors;
}
创建目标类代理类的具体代码如下:
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 获取所有增强器(通知方法)
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 保存到proxyFactory
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 创建代理对象:Spring自动决定, 最后返回目标类的代理
return proxyFactory.getProxy(getProxyClassLoader());
}
在org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(AdvisedSupport)中,Spring自动选择创建代理类:
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
最后,生成的被增强后的代理类注册到IOC容器中;