3500 字
18 分钟
Spring AOP 动态代理源码跟踪

前言#

博客有段时间没更新了,短短几个月好像发生了不少事情,心情受到一些影响,花了点时间进行复盘,重新调整情绪。这段时间 AI 进步很快,尝试 Vibe Coding 了一段时间,确实好用,开发效率提高了不少,但写代码和文章的成就感降低了很多,加上本来也懒,好像干什么事情都没有动力

在上一篇文章中,问题拆解和整体思路主要是自己整理,具体的实现方案主要是通过问 ChatGPT 和查阅资料选择的,如何实现已经有清晰的规划步骤了,但现在的一些智能 IDE 例如 trae 等已经比较重视方法论,可以拆解问题和实现步骤,形成执行计划,而且拆分得比较详细,不得不感叹现在 Vibe Coding 的门槛变得更低了,不懂代码的人也能做出一个 demo 级别的产品,但也说明了之前使用 AI 的思路没有问题,只是未来可能要往更高层次的思维和方法论去使用了,想法和思路依然重要,需要清楚得知道需求和边界是什么

继续深入研究源码依然有用,而且源码中的实现思路和设计模式,性能优化等内容依然值得我们学习和模仿,可以开阔实现功能的思路,只是使用 AI 辅助学习效率会更高。现在初中级程序员因为有 AI 的辅助,除非刻意去学习,否则会越来越难掌握编程经验,至少能够看懂 AI 是不是在瞎说瞎写,知道代码哪里出了问题,修改的方向,AI 改得是否正确,才能更高效得使用 AI

现阶段来看,对原本行业和工程经验丰富的人来说,懂整体流程和运作逻辑,熟悉业务,有想法,使用 AI 会如虎添翼,例如架构师,技术/产品经理等

也要好好琢磨一下以后的学习方向和博客内容了,想做的事情挺多,但执行力不够,越来越迷茫,哎

ps:年初看了辉夜姬,真是太赞了!好久没有因为看动画这么兴奋了。杀戮尖塔2终于出了,几年前在老朋友的推荐下玩过第一部,后来因为一些事情弃坑,期间朋友约过好多次一起玩游戏,但那些游戏我都不是很感兴趣,当时个人时间不是很充裕,更想做自己的事情,只能约定出第二部的时候再一起玩,如今也不能食言

@EnableAspectJAutoProxy#

Springboot 在启动的过程中,通过约定大于配置的方式,扫描 spring.factories 文件加载需要的 Bean,其中 AOP 是在 AopAutoConfiguration 自动配置类中声明了 @EnableAspectJAutoProxy 注解

图1

需要配置 spring.aop.auto,默认为 true,还需要一些 Advice 等类存在才会生效

重点看 @EnableAspectJAutoProxy 注解中又引入了 AspectJAutoProxyRegistrar.class

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}

AspectJAutoProxyRegistrar 实现了 ImportBeanDefinitionRegistrar 扩展注册了 AnnotationAwareAspectJAutoProxyCreator.class

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

AspectJAutoProxyRegistrar#

查看该类的继承和实现情况,主要是实现了 InstantiationAwareBeanPostProcessor 接口进行扩展,在 Bean 的生命周期中处理动态代理

图2

需要区分一下

BeanPostProcessor 有两个方法:

  • postProcessBeforeInitialization,在 Bean 初始化之前执行
  • postProcessAfterInitialization,在 Bean 初始化之后执行

InstantiationAwareBeanPostProcessor 继承了 BeanPostProcessor,提供了

  • postProcessBeforeInstantiation,在 Bean 实例化之前执行
  • postProcessAfterInstantiation,在 Bean 实例化之后执行(还未初始化)

这里调用的是 postProcessBeforeInstantiation方法,在 Bean 实例化之前执行

postProcessBeforeInitialization#

这里主要是处理 targetSource 的逻辑,如果这个 Bean 实现了 targetSource 接口,会在这里先生成动态代理,不创建 Bean 实例了

@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)) { // 缓存不需要创建动态代理的 Bean
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;
}
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them! advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
// 缓存 Advisor,避免重复扫描
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself. continue;
}
}
throw ex;
}
}
}
}
return advisors;
}

TargetSource

实现 TargetSource 的 getTarget 方法,可以自定义 AOP 对象的获取方式,例如从对象池中获取对象,一般是自己创建动态代理的时候使用

在 postProcessBeforeInstantiation 中很少会遇到使用 targetSource 的情况,这里就简单介绍一下。不过需要注意在 shouldSkip 方法中会调用 findCandidateAdvisors 方法找出所有的 Advisor 切面,并缓存到 cachedAdvisorBeanNames,避免下次重复扫描

然后在advisedBeans中缓存记录不需要生成动态代理的 Bean,在后面postProcessAfterInitialization方法执行的时候避免重复创建动态代理

postProcessAfterInitialization#

Bean 实例化后,从findCandidateAdvisors方法的cachedAdvisorBeanNames缓存中获取所有切面(例如 @Before 等注解),然后通过findAdvisorsThatCanApply方法筛选出当前 Bean 符合切面执行条件的 Advisor

@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;
}
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;
}
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable 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) {
// 获取所有 Advisor 切面(@Before等注解)
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 筛选出当前 Bean 符合切面条件的 Advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// advisors 里包含需要 MethodInvocation 的 Advice,会添加 ExposeInvocationInterceptor(添加到 advisors 列表的最前面)
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}

如果有符合当前 Bean 的 Advisor,就会调用 createProxy 方法,把 Advisor 设置到 proxyFactory 中,然后调用 proxyFactory.getProxy(classLoader)通过代理工厂生成动态代理

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
// ...
ProxyFactory proxyFactory = new ProxyFactory();
// ...
// 这里把 advisors 添加到 proxyFactory 中
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
// 这里会使用原来的 ClassLoader
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
// 通过代理工厂生成动态代理
return proxyFactory.getProxy(classLoader);
}
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!NativeDetector.inNativeImage() &&
(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);
}
}

createAopProxy 方法会判断当前类是否实现了接口,是否强制使用 cglib 等判断创建对应的 AopProxy 对象然后调用对应的 getProxy 方法创建动态代理对象

图3

代理对象都会实现 advised 接口,目的是为了兼容类型,这里以 Cglib 为例

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
//...
// Configure CGLIB Enhancer...
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);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(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);
}
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
// Choose an "aop" interceptor (used for AOP calls).
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
//...
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
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.
if (isStatic && isFrozen) {
//...
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array. 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 = mainCallbacks;
}
return callbacks;
}

cglib 动态代理对象会把 DynamicAdvisedInterceptor 设置到第一个 callbacks 里,所以在动态代理方法被调用时,入口是 DynamicAdvisedInterceptor.intercept 方法

jdk 动态代理在创建时 InvocationHandler 设置成 this,所以代理方法被调用时,入口是 JdkDynamicAopProxy.invoke 方法

public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// this 是 JdkDynamicAopProxy
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}

AOP 拦截器#

在动态代理方法被调用时,都会在入口方法调用 this.advised.getInterceptorsAndDynamicInterceptionAdvice 方法筛选出匹配代理方法的 Advisor转换成 MethodInterceptor 放到缓存中,最后通过责任链模式执行拦截器

以 cglib 为例

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) {
// 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 {
// 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);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
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;
}
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
// 获取生成动态代理时设置的 advisors
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list. AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
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);
}
// 匹配代理方法是否符合 advisor 条件
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
if (match) {
// 如果匹配转换成 MethodInterceptor
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
// 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;
}

拦截器的执行流程就不继续跟踪了,调试起来有点麻烦,有兴趣可以自行 debug 跟踪一下,主要使用了责任链模式,但有点不一样的地方是通过数组缓存拦截器,计算数组下标的方式实现责任链,这种方式减少了对象的创建,性能更好

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. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}

总结#

AOP 动态代理创建流程

  • Spring 启动通过 AopAutoConfiguration 配置类引入了@EnableAspectJAutoProxy注解
  • @EnableAspectJAutoProxy注解中 import 了 AspectJAutoProxyRegistrar 类
  • AspectJAutoProxyRegistrar 实现了 ImportBeanDefinitionRegistrar 扩展注册了 AnnotationAwareAspectJAutoProxyCreator 类
  • AnnotationAwareAspectJAutoProxyCreator 类实现了 BeanPostProcessor 接口
    • postProcessBeforeInstantiation 方法(主要处理 TargetSource)在 Bean 初始化前会调用 findCandidateAdvisors 缓存 Advisor
    • 通过 postProcessAfterInitialization 方法在 Bean 初始化之后调用
  • 查找当前的 Bean 是否有 Advisor
    • findCandidateAdvisors(),查找出所有的切面
    • findAdvisorsThatCanApply(),筛选出当前当前类符合的 Advisor
  • 如果有,调用 createProxy 方法创建动态代理
  • createProxy 会根据当前类是否实现了接口,是否强制使用 cglib 判断使用哪种代理方式
  • 并且都会实现 advised 的接口,目的是为了兼容类型

AOP 拦截器创建流程

  • 代理方法被调用时
    • cglib 代理类,把 DynamicAdvisedInterceptor 放在 callbacks 的第一个,所以 DynamicAdvisedInterceptor.intercept 方法是入口
    • jdk 代理,JdkDynamicAopProxy.invoke 方法是入口
  • 它们都通过 this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 获取生成动态代理时设置的 Advisor,转换成 MethodInterceptor
  • 然后使用 ReflectiveMethodInvocation.proceed 方法执行责任链
Spring AOP 动态代理源码跟踪
https://cloop.zone.id/posts/technology/spring-aop/
作者
Cloop
发布于
2026-03-21
许可协议
CC BY-NC-SA 4.0