Spring AOP源码
WARING
Spring 5.x 中 AOP 默认依旧使用 JDK 动态代理。
SpringBoot 2.x 开始,为了解决使用 JDK 动态代理可能导致的类型转化异常而默认使用 CGLIB。
在 SpringBoot 2.x 中,如果需要默认使用 JDK 动态代理可以通过配置项spring.aop.proxy-target-class=false来进行修改,proxyTargetClass配置已无效。
1.注册加载
Spring.factories中AopAutoConfiguration配置类

// proxyBeanMethods属性默认值是true,也就是说该配置类会被代理(CGLIB),在同一个配置文件中调用其它被@Bean注解标注的方法获取对象时会直接从IOC容器之中获取; // 如果设置为false,每次调用@Bean标注的方法获取到的对象是一个新的对象 @Configuration(proxyBeanMethods = false) // name 与 prefix 组合使用组成完整属性名称,与value不可同时存在 // havingValue 比较获取的属性值与havingValue给定的值是否相同,相同才加载配置类 // matchIfMissing 缺少 property 时是否加载,如果为true,没有该property属性也会正常加载,反之报错 @ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true) public class AopAutoConfiguration { @Configuration(proxyBeanMethods = false) @ConditionalOnClass(Advice.class) static class AspectJAutoProxyingConfiguration { // JDK代理 @Configuration(proxyBeanMethods = false) @EnableAspectJAutoProxy(proxyTargetClass = false) @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false) static class JdkDynamicAutoProxyConfiguration { } // CGLIB代理 @Configuration(proxyBeanMethods = false) @EnableAspectJAutoProxy(proxyTargetClass = true) @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true) static class CglibAutoProxyConfiguration { } } @Configuration(proxyBeanMethods = false) // 当项目里没有 aspectjweaver 的依赖的时候生效 @ConditionalOnMissingClass("org.aspectj.weaver.Advice") @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true) static class ClassProxyingConfiguration { ClassProxyingConfiguration(BeanFactory beanFactory) { if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry); AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } } } }
@EnableAspectJAutoProxy(proxyTargetClass = false)
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy { //true: 使用CGLIB基于类创建代理;false: 使用java接口创建代理 boolean proxyTargetClass() default false; // 是否通过aop框架暴露该代理对象,aopContext能够访问. boolean exposeProxy() default false; }
AspectJAutoProxyRegistrar.class
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { // 注册bean : AnnotationAwareAspectJAutoProxyCreator AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); // 获取注解 @EnableAspectJAutoProxy 的属性,并设置为Bean Definition的属性 AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); if (enableAspectJAutoProxy != null) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } } }
AnnotationAwareAspectJAutoProxyCreator.class
AnnotationAwareAspectJAutoProxyCreator:
->AspectJAwareAdvisorAutoProxyCreator
->AbstractAdvisorAutoProxyCreator
->AbstractAutoProxyCreator
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
//关注后置处理器(在bean初始化完成强做的事情)、自动装配BeanFactory
在执行 ConfigurationClassPostProcessor 的 processConfigBeanDefinitions 中会执行AspectJAutoProxyRegistrar来创建AnnotationAwareAspectJAutoProxyCreator BeanDefinition,但并没有实例化和初始化该对象。
因为AnnotationAwareAspectJAutoProxyCreator 顶层接口是 BeanPostProcessor,是在 registerBeanPostProcessors 时会实例化注册到容器中;
而又因为实现了BeanFactoryAware 接口,在实例化之后的初始化阶段会注入 BeanFactory ( void setBeanFactory ); AbstractAdvisorAutoProxyCreator 中重写了setBeanFactory 方法。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { @Override public Object getEarlyBeanReference(Object bean, String beanName) { Object cacheKey = getCacheKey(bean.getClass(), beanName); this.earlyProxyReferences.put(cacheKey, bean); return wrapIfNecessary(bean, beanName, cacheKey); } @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { // advisedBeans 用于存储不可代理的bean,如果包含直接返回 if (this.advisedBeans.containsKey(cacheKey)) { return null; } // 判断当前bean是否可以被代理,然后存入 advisedBeans; 判断有没有 @Advice,@Pointcut,@Advisor,@AopInfrastructureBean注解 // shouldSkip 方法在 子类AspectJAwareAdvisorAutoProxyCreator中已经重写,并且已经把所有的切面的通知(增强方法)加载,排序并缓存了 // 顺序:Around, Before, After, AfterReturning, AfterThrowing if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } // 获取自定义目标类来创建代理并返回,如果没有则在 postProcessorAfterInitialization 中创建代理 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; } @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; } // 包装 Bean 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; } // 查找适合当前Bean的切面方法 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; } } AbstractAdvisorAutoProxyCreator: protected Object[] getAdvicesAndAdvisorsForBean( Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) { // 查找应用当前Bean的增强方法 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(); // 查找可以应用于指定bean的所有增强方法。 List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { // 顺序:Around, Before, After, AfterReturning, AfterThrowing eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; } 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 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.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 获取动态代理类,SpringBoot 默认使用CGLib动态代理 return proxyFactory.getProxy(getProxyClassLoader()); }
2.AOP调用
CglibAopProxy 类中的静态内部类 DynamicAdvisedInterceptor下:
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {...}
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) { oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } target = targetSource.getTarget(); Class<?> targetClass = (target != null ? target.getClass() : null); // 获取MethodInterceptor拦截器链 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); Object retVal; if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = methodProxy.invoke(target, argsToUse); } else { // 创建一个方法并调用proceed() // 实际是调用父类 ReflectiveMethodInvocation 的构造方法 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); } if (setProxyContext) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } }
CglibMethodInvocation 继承 ReflectiveMethodInvocation,实际是调用父类 ReflectiveMethodInvocation 的 proceed()方法
public Object proceed() throws Throwable { // 从索引-1开始并提前递增,最后一个永远是被代理的方法 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // 在这里评估动态方法匹配器:静态部分已经被评估并发现匹配。 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 { // 动态匹配失败,跳过这个拦截器并调用链中的下一个。 return proceed(); } } else { // 它是一个拦截器,所以我们调用它:切入点将具有在构造此对象之前静态求值。 // MethodBeforeAdviceInterceptor、 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
这里以前置通知@Before 为例:会执行 前置通知拦截器例的invoke 方法
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable { private final MethodBeforeAdvice advice; public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } @Override public Object invoke(MethodInvocation mi) throws Throwable { this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); return mi.proceed(); } }
public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice, Serializable {...}
public void before(Method method, Object[] args, @Nullable Object target) throws Throwable { invokeAdviceMethod(getJoinPointMatch(), null, null); }
public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedenceInformation, Serializable {...}
protected Object invokeAdviceMethod( @Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex) throws Throwable { // 调用通知方法基于给定参数 return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex)); } protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { Object[] actualArgs = args; if (this.aspectJAdviceMethod.getParameterCount() == 0) { actualArgs = null; } try { ReflectionUtils.makeAccessible(this.aspectJAdviceMethod); return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs); } catch (IllegalArgumentException ex) { throw new AopInvocationException("Mismatch on arguments to advice method [" + this.aspectJAdviceMethod + "]; pointcut expression [" + this.pointcut.getPointcutExpression() + "]", ex); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } }
public final class Method extends Executable {...}
public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { Class<?> caller = Reflection.getCallerClass(); checkAccess(caller, clazz, obj, modifiers); } } MethodAccessor ma = methodAccessor; // read volatile if (ma == null) { ma = acquireMethodAccessor(); } // 执行通知方法 return ma.invoke(obj, args); }
最后执行 被增强的方法时:
回到ReflectiveMethodInvocation
最后一个是被代理的方法,也是索引最后一位 public Object proceed() throws Throwable { // 从索引-1开始并提前递增 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // 在这里评估动态方法匹配器:静态部分已经被评估并发现匹配。 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 { // 动态匹配失败,跳过这个拦截器并调用链中的下一个。 return proceed(); } } else { // 它是一个拦截器,所以我们调用它:切入点将具有在构造此对象之前静态求值。 // MethodBeforeAdviceInterceptor、 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {...}
protected Object invokeJoinpoint() throws Throwable { if (this.methodProxy != null) { return this.methodProxy.invoke(this.target, this.arguments); } else { return super.invokeJoinpoint(); } }
public class MethodProxy {...}
public Object invoke(Object obj, Object[] args) throws Throwable { try { init(); FastClassInfo fci = fastClassInfo; return fci.f1.invoke(fci.i1, obj, args); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } catch (IllegalArgumentException ex) { if (fastClassInfo.i1 < 0) throw new IllegalArgumentException("Protected method: " + sig1); throw ex; } }
大致的一个AOP调用过程就是如此

浙公网安备 33010602011771号