@EnableAspectJAutoProxy 源码如下,它导入了AspectJAutoProxyRegistrar类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
打开AspectJAutoProxyRegistrar类,它实现了ImportBeanDefinitionRegistrar接口的registerBeanDefinitions方法,从而向容器中注册其他的BeanDefinition。
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* 注册配置AOP自动代理
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
...
}
}
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);从方法名可以看出来这里面要注册AspectJAnnotationAutoProxyCreator类的BeanDefinition,点开看一下
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
继续点,真的注册了AnnotationAwareAspectJAutoProxyCreator.class类的BeanDefinition
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
继续进入registerOrEscalateApcAsRequired
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator";
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
...
/* 如果已经存在名字为org.springframework.aop.config.internalAutoProxyCreator的BeanDefinition, 判断是否覆盖之前的注册
*/
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
/*
创建beanDefinition并返回,以完成注册
*/
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
现在AnnotationAwareAspectJAutoProxyCreator.class类的BeanDefinition已经完成注册。那么AnnotationAwareAspectJAutoProxyCreator.class类有什么用呢?
先看一下这个类的继承关系
AnnotationAwareAspectJAutoProxyCreator实现的最顶级的接口有
-
BeanPostProcessor
-
Aware
-
Ordered
-
AopInfrastructureBean
-
Serializable
比较重要的是BeanPostProcessor和Aware这两个接口。Aware接口用来接收一些容器对象的生命周期的通知。因此猜测应该是在BeanPostProcessor及其子接口的实现方法中完成的AOP
AnnotationAwareAspectJAutoProxyCreator与BeanPostProcessor及其子接口继承关系是
AnnotationAwareAspectJAutoProxyCreator < SmartInstantiationAwareBeanPostProcessor < InstantiationAwareBeanPostProcessor < BeanPostProcessor
BeanPostProcessor 接口有下面两个方法
postProcessBeforeInitialization
postProcessAfterInitialization
InstantiationAwareBeanPostProcessor 接口中有这几个方法
postProcessBeforeInstantiation
postProcessAfterInstantiation
// 这两个看起来是监听属性的,应该不重要
postProcessProperties
postProcessPropertyValues
SmartInstantiationAwareBeanPostProcessor 接口有这几个方法,看起来似乎都不是实现AOP的关键方法
predictBeanType
determineCandidateConstructors
getEarlyBeanReference
所以,可以推测AnnotationAwareAspectJAutoProxyCreator中实现AOP的关键方法是
postProcessBeforeInitialization
postProcessAfterInitialization
postProcessBeforeInstantiation
postProcessAfterInstantiation
打开AnnotationAwareAspectJAutoProxyCreator类,它的方法列表如下,没有猜测的关键方法
setIncludePatterns
setAspectJAdvisorFactory
initBeanFactory
findCandidateAdvisors
isInfrastructureClass
isEligibleAspectBean
打开它的父类AspectJAwareAdvisorAutoProxyCreator看看,AspectJAwareAdvisorAutoProxyCreator的方法列表如下,还是没有
sortAdvisors
extendAdvisors
shouldSkip
继续向上找AspectJAwareAdvisorAutoProxyCreator的父类AbstractAutoProxyCreator方法列表如下,还是没有
setBeanFactory
initBeanFactory
getAdvicesAndAdvisorsForBean
findEligibleAdvisors
findCandidateAdvisors
findAdvisorsThatCanApply
isEligibleAdvisorBean
sortAdvisors
extendAdvisors
advisorsPreFiltered
继续向上找AbstractAutoProxyCreator的父类AbstractAutoProxyCreator
AbstractAutoProxyCreator中可以找到postProcessAfterInitialization和postProcessBeforeInstantiation方法,AbstractAutoProxyCreator再往上找就是SmartInstantiationAwareBeanPostProcessor接口了,所以应该就是这两个方法了
postProcessBeforeInstantiation,注释说这段代码的逻辑是如果有自定义的TargetSource就创建一个代理。因此这里应该是实现Spring AOP TargetSource机制的地方。现在追的是普通的AOP的实现flow,因此这个方法也不是重点
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
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.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
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;
}
postProcessAfterInitialization,它的重点是调用了wrapIfNecessary方法
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
wrapIfNecessary方法,可以看到注解:Create proxy if we have advice. 应该就是这里了
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && 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;
}
// Create proxy if we have advice.
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;
}
到此,推测应该出是postProcessAfterInitialization方法实现了AOP机制,postProcessAfterInitialization的执行时机如下图,再调用自定义的init-method之后
接下来,我们先给这个方法打上断点,创建一个切面类,看看执行流程
package com.example.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspect {
@Pointcut("execution(* com.example..*.*(..))")
public void pointcut(){}
@Before("pointcut()")
public void before() {
System.out.println("before");
}
}
package com.example.controller;
import org.springframework.stereotype.Component;
@Component
public class HelloController {
public void sayHello() {
System.out.println("hello");
}
}
开始debug。会看到确实有执行到postProcessAfterInitialization方法,并返回了织入切面之后的代理类。
至此已经能够分析出@EnableAspectJAutoProxy 是如何启用AOP的
总结一下流程
-
@EnableAspectJAutoProxy导入了AspectJAutoProxyRegistrar类
-
AspectJAutoProxyRegistrar类向Spring注册了AnnotationAwareAspectJAutoProxyCreator类
-
AnnotationAwareAspectJAutoProxyCreator类实现了BeanPostProcessor 接口,并在postProcessAfterInitialization方法的实现中判断是否为传入的Bean织入切面并生成AOP代理对象
此外,还发现:AnnotationAwareAspectJAutoProxyCreator类实现InstantiationAwareBeanPostProcessor 接口,并在postProcessBeforeInstantiation方法中实现了Spring AOP的Target Source机制