Spring中AOP创建代理和运行时拦截的原理分析
- 0 入口`AbstractApplicationContext`类
- `doGetBean` 方法中的一段代码
- 1 postProcessAfterInitialization
- 2 wrapIfNecessary
- 3 getAdvicesAndAdvisorsForBean[获得Bean对应的增强器们]
- 3.1 findEligibleAdvisors[获得匹配的 Advisor 增强器](findAdvisorsThatCanApply)
- 3.1.1 findCandidateAdvisors[ 获取所有 Advisor 增强器]
- 3.1.2 buildAspectJAdvisors[根据@Aspect注解获取]
- advisorFactory.`isAspect`(beanType)
- 3.1.3 getAdvisors[解析有 AOP 注解中的增强方法]
- 3.1.4 getAdvisor[根据获得的增强方法生成增强Advisor对象]
- 3.1.5 InstantiationModelAwarePointcutAdvisorImpl[构造方法中生成增强器]
- 3.1.6 instantiateAdvice调用getAdvice[根据前置、后置等处理器生成对应增强器]
- 3.2 findEligibleAdvisors[获得匹配的 Advisor 增强器](`findAdvisorsThatCanApply`)
- 3.2.1 findAdvisorsThatCanApply[从所有 Advisor 增强器中,寻找匹配的]
- 3.2.2 findAdvisorsThatCanApply
- 4 createProxy[创建代理]
- 4.1 getProxy[创建代理对象](createAopProxy)
- 4.1.1 createAopProxy
- 4.1.2 createAopProxy[根据条件创建Cglib、JDK动态代理]
- 4.2 getProxy[创建代理对象](`getProxy`)
- 4.2.1 getProxy
- 4.2.2 CglibAopProxy
- `getCallbacks`
- `DynamicAdvisedInterceptor`实现了`MethodInterceptor`接口
- `createProxyClassAndInstance`调用create方法生成Cglib动态代理
- 4.2.3 JdkDynamicAopProxy
- 5 运行时进入动态代理拦截方法【Cglib为例】
- 5.1 CglibAopProxy#intercept(...)
- 5.1.1 getInterceptorsAndDynamicInterceptionAdvice[运行时拦截获取拦截器链]
- `getInterceptorsAndDynamicInterceptionAdvice`
- 5.2 proceed[执行方法]
- 6 JDK动态代理运行时拦截大同小异
- 最后说几句
0 入口AbstractApplicationContext
类
-
finishBeanFactoryInitialization
(beanFactory); 初始化非延迟加载的单例 - beanFactory.
preInstantiateSingletons
(); 初始化非延迟加载的单例 -
getBean
(beanName); -
doGetBean
(name, null, null, false);
doGetBean
方法中的一段代码
// bean 实例化
// Create bean instance.
if (mbd.isSingleton()) { // 单例模式
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
-
createBean
(beanName, mbd, args); -
resolveBeforeInstantiation
(beanName, mbdToUse); 给 BeanPostProcessors
一个机会用来返回一个代理类而不是真正的类实例,AOP 的功能就是基于这个地方,参见 AbstractAutoProxyCreator -
applyBeanPostProcessorsAfterInitialization
(bean, beanName);后置processor.postProcessAfterInitialization(result, beanName); - 实际调用AbstractAutoProxyCreator#
postProcessAfterInitialization
(@Nullable Object bean, String
beanName) 方法 -
wrapIfNecessary
(bean, beanName, cacheKey);
1 postProcessAfterInitialization
进入到创建Aop的类AbstractAutoProxyCreator中
AbstractAutoProxyCreator.java
@Override // 因为实现 InstantiationAwareBeanPostProcessor 接口
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 获得缓存 KEY
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
// 如果它适合被打理, 则需要封装指定 Bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
2 wrapIfNecessary
getAdvicesAndAdvisorsForBean详细看第三节
createProxy
AbstractAutoProxyCreator.java
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.
// 获得 Bean 对象,对应的增强器们 **见第3节**
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 芋艿,如果获取到了增强,则需要针对增强创建代理
if (specificInterceptors != DO_NOT_PROXY) {
// 通过 advisedBeans 标记,需要增强
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理 **见第4节**
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
// 记录代理类型
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
// 如果无需增强,则通过 advisedBeans 标记,无需增强
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
3 getAdvicesAndAdvisorsForBean[获得Bean对应的增强器们]
AbstractAdvisorAutoProxyCreator.java
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
// 获得匹配的 Advisor 增强器
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
// 无匹配,返回 DO_NOT_PROXY
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
// 有匹配,返回 Advisor 数组
return advisors.toArray();
}
3.1 findEligibleAdvisors[获得匹配的 Advisor 增强器](findAdvisorsThatCanApply)
findAdvisorsThatCanApply方法3.2节分析
AbstractAdvisorAutoProxyCreator.java
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 获取所有 Advisor 增强器 **见3.1.1**
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 从所有 Advisor 增强器中,寻找匹配的 **见3.2.1**
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 拓展 Advisor 集合。目前实现为空,子类可覆盖实现自定义逻辑
extendAdvisors(eligibleAdvisors);
// 排序匹配的 Advisor 增强器
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
3.1.1 findCandidateAdvisors[ 获取所有 Advisor 增强器]
关注AnnotationAwareAspectJAutoProxyCreator
类的方法,这里只关注注解的切面类,不关注配置文件
AnnotationAwareAspectJAutoProxyCreator.java
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
// 当使用注解方式配置 AOP 的时候,并不是丢弃了对 XML 配置的支持,
// 在这里调用父类方法加载配置文件中的 AOP 声明
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
// 获取 Bean 的注解 @Aspect 增强的功能
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
3.1.2 buildAspectJAdvisors[根据@Aspect注解获取]
BeanFactoryAspectJAdvisorsBuilder.java
public List<Advisor> buildAspectJAdvisors() {
// 第一种情况,aspectBeanNames 为 null ,说明未初始化,则需要进行初始化
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 获取所有 Bean 名字的集合
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
// 遍历所有 Bean 名字,找出对应的增强方法
for (String beanName : beanNames) {
// 不合法的 Bean 则略过,由子类定义规则,默认 BeanFactoryAspectJAdvisorsBuilder 返回 true 。子类的实现,可见 BeanFactoryAspectJAdvisorsBuilderAdapter 。
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
// 获得 Bean 对象的类型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 如果存在对应的 @Aspect 注解
if (this.advisorFactory.isAspect(beanType)) {
// 添加到 aspectNames 中
aspectNames.add(beanName);
// 创建 AspectMetadata 对象
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 根据不同类型,不同处理
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { // 单例
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); // BeanFactory 开头
// 解析有 AOP 注解中的增强方法 【重要】
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
// 记录到 advisorsCache 或 aspectFactoryCache 缓存中
if (this.beanFactory.isSingleton(beanName)) { // Bean 自身是单例
this.advisorsCache.put(beanName, classAdvisors);
} else { // Bean 是 BeanFactory
this.aspectFactoryCache.put(beanName, factory);
}
// 添加结果到 advisors 中
advisors.addAll(classAdvisors);
} else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) { // 要求非单例,即 Prototype 类型
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName); // Prototype 开头
// 记录到 aspectFactoryCache 缓存中
this.aspectFactoryCache.put(beanName, factory);
// 解析 @Aspect 注解中的增强方法 【重要】
// 添加结果到 advisors 中
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
// aspectBeanNames 非 null ,说明已经初始化
// 第二种情况,aspectNames 数组大小为 0 ,返回空数组
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
// 第三种情况,aspectNames 数组大小大于 1 ,查找对应的 Advisor 数组
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
} else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
advisorFactory.isAspect
(beanType)
AbstractAspectJAdvisorFactory.java
@Override
public boolean isAspect(Class<?> clazz) {
return (hasAspectAnnotation(clazz) // 使用 @Aspect 注解
&& !compiledByAjc(clazz)); // 并未使用 ajc 编译器进行编译过。关于 ajc ,可以看 https://www.jianshu.com/p/fe8d1e8bd63e
}
private boolean hasAspectAnnotation(Class<?> clazz) {
//根据是否有@Aspect注解
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
}
3.1.3 getAdvisors[解析有 AOP 注解中的增强方法]
ReflectiveAspectJAdvisorFactory.java
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
// 获得类和名字
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
// 验证
validate(aspectClass);
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
// 遍历方法,若方法有增强注解(例如,@Before、@After、@Around、@AfterReturning、@ 等等注解),则获取对应的增强 Advisor 对象
List<Advisor> advisors = new ArrayList<>();
for (Method method : getAdvisorMethods(aspectClass)) { // 获取非 @Pointcut 注解的方法们 https://www.jianshu.com/p/6f40dddd71a5
// 获取增强 Advisor 对象
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
// 获取到,添加到 advisors 中
if (advisor != null) {
advisors.add(advisor);
}
}
// If it's a per target aspect, emit the dummy instantiating aspect.
if (!advisors.isEmpty() // 非空
&& lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { // 配置了增强延迟初始化
// 如果寻找的增强器不为空,而且又配置了增强延迟初始化,那么需要在首个 advisors 的位置,加入 SyntheticInstantiationAdvisor 同步实例化增强器
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
// 遍历属性,若属性有增强注解 @DeclareParents ,则获取对应的增强 Advisor 对象 //
for (Field field : aspectClass.getDeclaredFields()) { // 属性
Advisor advisor = getDeclareParentsAdvisor(field);
// 获取到,添加到 advisors 中
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
3.1.4 getAdvisor[根据获得的增强方法生成增强Advisor对象]
ReflectiveAspectJAdvisorFactory.java
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
// 验证
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
// 切点信息的获取
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
// 获取不到,返回 null
if (expressionPointcut == null) {
return null;
}
// 根据切点信息,生成增强器。
// 所有的增强,都由 Advisor 的实现类 InstantiationModelAwarePointcutAdvisorImpl 统一封装
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
3.1.5 InstantiationModelAwarePointcutAdvisorImpl[构造方法中生成增强器]
InstantiationModelAwarePointcutAdvisorImpl.java
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
this.declarationOrder = declarationOrder;
this.aspectName = aspectName;
// 根据切面元数据判断是否要延迟实例化,一般为否
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
// Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
} else {
// A singleton aspect.
this.pointcut = this.declaredPointcut;
this.lazy = false;
// 实例化 Advice 实例
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
3.1.6 instantiateAdvice调用getAdvice[根据前置、后置等处理器生成对应增强器]
ReflectiveAspectJAdvisorFactory.java
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
// 注解了 @Aspect 的类名
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
// 验证
validate(candidateAspectClass);
// 获得 AspectJAnnotation 注解信息
// 在获取Advisor的方法 我们已经见过这个调用。这个在 Spring 的 AnnotationUtils 中会缓存方法的注解信息
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// If we get here, we know we have an AspectJ method.
// Check that it's an AspectJ-annotated class
// 再去校验一遍 如果不是切面类 则抛出异常
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
// 根据不同的切面注解类型,创建不同的 Advice 对象
AbstractAspectJAdvice springAdvice;
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// Now to configure the advice...
// 设置创建的 Advice 对象的属性
springAdvice.setAspectName(aspectName); // 切面名
springAdvice.setDeclarationOrder(declarationOrder); // 切面顺序 可在切面方法上用@Order(0),数值越小优先级越高
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod); // 参数集合
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings(); // 参数绑定
return springAdvice;
}
至此,增强器生成完毕。
3.2 findEligibleAdvisors[获得匹配的 Advisor 增强器](findAdvisorsThatCanApply
)
AbstractAdvisorAutoProxyCreator.java
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 获取所有 Advisor 增强器 见3.1.1
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 从所有 Advisor 增强器中,寻找匹配的 见3.2.1
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 拓展 Advisor 集合。目前实现为空,子类可覆盖实现自定义逻辑
extendAdvisors(eligibleAdvisors);
// 排序匹配的 Advisor 增强器
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
3.2.1 findAdvisorsThatCanApply[从所有 Advisor 增强器中,寻找匹配的]
AbstractAdvisorAutoProxyCreator.java
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
// 设置当前 Proxy Bean 的名字
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
// 清空当前 Proxy Bean 的名字
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
3.2.2 findAdvisorsThatCanApply
AopUtils.java
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>(); // eligible 翻译为符合条件的
// 首先,处理 IntroductionAdvisor 增强器
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor // 匹配 IntroductionAdvisor 增强器
&& canApply(candidate, clazz)) { // 判断,是否可以匹配
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
// 然后,处理非 IntroductionAdvisor 增强器
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) { // 跳过 IntroductionAdvisor 增强器,因为上面处理过了。
// already processed
continue;
}
if (canApply(candidate, clazz, hasIntroductions)) { // 判断,是否可以匹配
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
至此,挑选出匹配的增强器。
4 createProxy[创建代理]
AbstractAutoProxyCreator.java
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 创建 ProxyFactory 对象,负责创建 Proxy 对象的工厂
ProxyFactory proxyFactory = new ProxyFactory();
// 获取当前类的属性,到 ProxyFactory 中
proxyFactory.copyFrom(this);
// 判断对于给定的 Bean 是否使用 targetClass ,而不是接口代理。
// 使用 CGLIB 代理时,相当于使用 targetClass 代理
// 使用 JDK 代理时,相当于使用期接口代理。
if (!proxyFactory.isProxyTargetClass()) {
// 是否需要代理 targetClass
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true); // 设置使用 targetClass 代理
} else {
// 评估是否代理接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 创建增强器们,并添加到 ProxyFactory 对象中
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
// 设置 targetSource 目标对象,到 ProxyFactory 对象中
proxyFactory.setTargetSource(targetSource);
// 定制 ProxyFactory 对象。目前实现为空。
customizeProxyFactory(proxyFactory);
// 用来控制代理工厂被配置之后,是否还允许修改通知。
// 缺省值为 false ,即在代理被配置之后,不允许修改代理的配置
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 创建代理
return proxyFactory.getProxy(getProxyClassLoader());
}
4.1 getProxy[创建代理对象](createAopProxy)
createAopProxy见4.1.1
getProxy见4.2.1
ProxyFactory.java
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
4.1.1 createAopProxy
ProxyCreatorSupport.java
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 创建代理
return getAopProxyFactory().createAopProxy(this);
}
4.1.2 createAopProxy[根据条件创建Cglib、JDK动态代理]
DefaultAopProxyFactory.java
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() // 用来控制通过 CGLIB 创建的代理是否使用激进的优化策略,除非完成了解 Spring AOP 代理如何处理优化,否则不推荐用户使用这个设置。
// 目前这个属性仅用于 CGLIB 代理,对于 JDK 代理无效。
|| config.isProxyTargetClass() // 是否代理目标类,而不是目标类的接口。 在@EnableAspectJAutoProxy中设置属性proxyTargetClass
// 如果这个属性为 true ,CGLIB 代理将被创建。
|| 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.");
}
// 使用 JDK 代理策略
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 使用 CGLIB 代理策略
return new ObjenesisCglibAopProxy(config);
} else {
// 使用 JDK 代理策略
return new JdkDynamicAopProxy(config);
}
}
4.2 getProxy[创建代理对象](getProxy
)
4.2.1 getProxy
根据createAopProxy
返回的对象生成对应的代理类
4.2.2 CglibAopProxy
CglibAopProxy.java
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
// 目标类,即被代理类
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
// 判断目标类,是否已经被 CGLIB 代理
Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) { //名字是否包含 $$
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
// 验证类
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
// 配置 CGLIB Enhancer 对象。关于每个属性的用途,胖友可以看看 CGLIB 相应的文章。例如:https://www.jianshu.com/p/c42b3feecb09
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass); // 设置被代理类
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); // 设置接口
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); // 设置命名策略。ps:感兴趣可以点击去看下。
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
// 设置拦截器
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
// 生成代理类
// 生成代理对象
return createProxyClassAndInstance(enhancer, callbacks);
} catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class", ex);
} catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
getCallbacks
CglibAopProxy.java
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls).
// 将拦截器,封装成 DynamicAdvisedInterceptor 对象
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
// 创建目标拦截器
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
} else {
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
// 创建目标分发器
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice // 【重要】将拦截器,添加到 Callback 中
targetInterceptor, // invoke target without considering advice, if optimized 目标拦截器
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, // 目标拦截器
this.advisedDispatcher, // 目标分发器
new EqualsInterceptor(this.advised), // equals 方法的拦截器
new HashCodeInterceptor(this.advised) // hashCode 方法的拦截器
};
Callback[] callbacks;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimizations by sending the AOP calls
// direct to the target using the fixed chain for that method.
// 如果目标是静态的,并且通知链被冻结,
// 则使用优化AOP调用,直接对方法使用固定的通知链
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);
for (int x = 0; x < methods.length; x++) {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods[x].toString(), x);
}
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
// 复制到 callbacks 中
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
} else {
// 赋值给 callbacks
callbacks = mainCallbacks;
}
return callbacks;
}
DynamicAdvisedInterceptor
实现了MethodInterceptor
接口
createProxyClassAndInstance
调用create方法生成Cglib动态代理
CglibAopProxy.java
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
enhancer.setInterceptDuringConstruction(false);
enhancer.setCallbacks(callbacks);
return (this.constructorArgs != null && this.constructorArgTypes != null ?
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
enhancer.create());
}
4.2.3 JdkDynamicAopProxy
JdkDynamicAopProxy.java
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// 获得代理接口的数组
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
// 判断,是否已经包含 equals 和 hashCode 方法
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 创建 Proxy 对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
this
为JdkDynamicAopProxy
5 运行时进入动态代理拦截方法【Cglib为例】
5.1 CglibAopProxy#intercept(…)
CglibAopProxy.java
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
// 有时候,目标对象内部的自我调用将无法实施切面中的增强,则需要通过此属性暴露代理
if (this.advised.exposeProxy) {
// AopContext 的实现原理是,基于 ThreadLocal
// Make invocation available if necessary.
// 获得原代理对象
oldProxy = AopContext.setCurrentProxy(proxy);
// 标记,设置了代理
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获得当前方法拦截的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// 调用链为空,直接调用切点的方法
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
} else {
// 创建 CglibMethodInvocation 对象
// 将拦截器链封装到该对象,以便使其 proceed 方法执行时,进行拦截处理
// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
// 处理方法结果
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
} finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
// 设置 AopContext 回老代理
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
5.1.1 getInterceptorsAndDynamicInterceptionAdvice[运行时拦截获取拦截器链]
AdvisedSupport.java
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
// 优先从缓存中获取
List<Object> cached = this.methodCache.get(cacheKey);
// 获取不到,则进行构建
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
getInterceptorsAndDynamicInterceptionAdvice
DefaultAdvisorChainFactory.java
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
// 获得 DefaultAdvisorAdapterRegistry 对象
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors(); // 该类可筛选的 Advisor 集合,需要进过下面逻辑的筛选,再创建成对应的拦截器,添加到 interceptorList 中。
List<Object> interceptorList = new ArrayList<>(advisors.length); // 拦截器的结果集合
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass()); // 真实的类
Boolean hasIntroductions = null; // 是否 advisors 中有 IntroductionAdvisor 对象。
// 遍历 Advisor 集合
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
// 判断是否匹配
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
} else {
match = mm.matches(method, actualClass);
}
if (match) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) { // 运行时,封装成对应的 InterceptorAndDynamicMethodMatcher 拦截器对象。
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
} else { // 非运行时,直接添加
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
} else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
} else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
5.2 proceed[执行方法]
ReflectiveMethodInvocation.java
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// 执行完所有拦截器后,执行切面方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获得下一个拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
// 动态匹配
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) { // 匹配,则执行拦截器
return dm.interceptor.invoke(this);
} else { // 不匹配,跳到下一个,递归执行
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
} else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
// 将 this 作为参数传递,以保证当前实例中调用链的执行
// MethodInterceptor 基于不同的切面类型,有不同的实现。
// 例如 @Before 对应 MethodBeforeAdviceInterceptor
// 例如 @After 对应 AfterReturningAdviceInterceptor
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
6 JDK动态代理运行时拦截大同小异
JdkDynamicAopProxy.java
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
// 如果被代理的类,未实现 equals 方法,则调用当前类的 equals 方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
// 如果被代理的类,未实现 hashCode 方法,则调用当前类的 hashCode 方法
} else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
// 如果是 DecoratingProxy#getDecoratedClass() 方法,通过 advised 这个代理配置,获得被代理的类
} else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
// 调用 advised 这个代理配置的方法
} else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
// 有时候,目标对象内部的自我调用将无法实施切面中的增强,则需要通过此属性暴露代理
if (this.advised.exposeProxy) {
// AopContext 的实现原理是,基于 ThreadLocal
// Make invocation available if necessary.
// 获得原代理对象
oldProxy = AopContext.setCurrentProxy(proxy);
// 标记,设置了代理
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// Get the interception chain for this method.
// 获得当前方法拦截的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// 调用链为空,直接调用切点的方法
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
// 创建 ReflectiveMethodInvocation 对象
// 将拦截器链封装到该对象,以便使其 proceed 方法执行时,进行拦截处理
// We need to create a method invocation...
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
// 执行拦截器和方法
retVal = invocation.proceed();
}
// Massage return value if necessary.
// 处理方法结果
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
// 返回类型为基本类型,但是返回 null ,不匹配,所以抛出 AopInvocationException 异常
} else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
// 正常结果,无需处理,直接返回
return retVal;
} finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
// 设置 AopContext 回老代理
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
最后说几句
AOP的过程简单就是:
- 获取有@Aspect注解的类
- 为其中方法(有@Before、@After等注解)创建对应的拦截器
- 运行时进入动态代理方法,找到对应的增强方法,递归执行