本文基于Spring AOP 实践Spring AOP XML配置方式原理详解, 来继续讲解 基于注解方式实现AOP 自动代理的原理。

Spring AOP 实践一文中,我们探讨了通过在XML配置文件中使用ProxyFactoryBean来配置代理对象的方法,并在需要时手动获取代理对象以实现AOP功能。

然而,在大型生产环境中,这种配置方式显得繁琐且不切实际。为了解决这一问题,Spring提供了一种基于AbstractAutoProxyCreator的自动代理机制,使得我们无需为每个Bean手动配置ProxyFactoryBean

AbstractAutoProxyCreator通过自动检测Bean的类型和相应的切面(Aspect)来创建代理对象,从而简化了配置过程。

注解方式实现的AOP 自动代理机制使用的是AbstractAutoProxyCreator的子类AnnotationAwareAspectJAutoProxyCreator

如果你已经了解了

  1. Spring bean 实例化
  2. Spring IOC 容器启动过程拓展点
  3. Spring AOP 实践
  4. Spring AOP XML配置方式原理详解

那么现在来理解注解方式的自动代理机制其实已经比较容易了。

接下来,我们将以一个Spring Boot项目为示例,探讨AnnotationAwareAspectJAutoProxyCreator 实现自动代理的原理。

0. 示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
@Service
public class UserService {
public void createUser(String username) {
// 模拟业务处理
System.out.println("Creating user: " + username);
}


public void deleteUser(String username) {

// 模拟业务处理
System.out.println("Deleting user: " + username);
}
}

@Aspect
@Component
public class LoggingAspect {
//定义一个匹配userService中所有方法的切点表达式
@Pointcut("execution(* com.example.codingInAction.service.UserService.*(..))")
public void userServiceAllMethod() {
}

// 在方法执行之前执行的通知
@Before("userServiceAllMethod()")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}

// 在方法执行之后执行的通知
@After("userServiceAllMethod()")
public void logAfter(JoinPoint joinPoint) {
System.out.println("After method: " + joinPoint.getSignature().getName());
}

// 定义一个只匹配 UserService.createUser 方法的切点表达式
@Around("execution(* com.example.codingInAction.service.UserService.createUser(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
System.out.println(joinPoint.getSignature().getName() + " 方法开始执行");

Object result = joinPoint.proceed(); // 执行目标方法

long endTime = System.currentTimeMillis();
System.out.println(joinPoint.getSignature().getName() + " 方法执行时间: " + (endTime - startTime) + "ms");

return result;
}
}


@SpringBootApplication
public class CodingInActionApplication {
public static void main(String[] args) {
SpringApplication.run(CodingInActionApplication.class, args);
}
}

1. AnnotationAwareAspectJAutoProxyCreator 继承、实现关系解析

AnnotationAwareAspectJAutoProxyCreator是Spring AOP实现的核心类之一用于在Spring容器中扫描和处理带有@Aspect注解的bean。

AnnotationAwareAspectJAutoProxyCreator 继承关系较为复杂,它是多个类和接口的组合体,主要继承关系如下:

1.1 BeanPostProcessor

Spring IOC 容器启动过程拓展点一文中,已经详细讲解过BeanPostProcessor的作用,此处不再赘述,直接来看它的3个子类

1.1.1 InstantiationAwareBeanPostProcessor

图中置灰的2个方法,是继承自BeanPostProcessor的2个方法

InstantiationAwareBeanPostProcessor自有的3个方法中有2个方法名称和BeanPostProcessor中方式名称相同,但是入参和返回值略有不同

  1. postProcessBeforeInstantiation
    1
    2
    3
    4
    @Nullable  
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    return null;
    }

在bean 的实例化之前,会调用这个方法,其逻辑存在于下面代码中resolveBeforeInstantiation方法中。 这个方法可以返回一个代理对象,来替代 Bean 的默认实例化过程。但通常情况下,代理对象是在 Bean 实例化之后创建的,所以这个方法一般返回 null

1
2
3
4
5
6
7
8
9
@Override  
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
}
  1. postProcessAfterInstantiation
    在 bean create之后,populate之前调用。返回 true 表示允许属性注入,返回 false 则跳过属性注入。
1
2
3
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {  
return true;
}
  1. postProcessProperties
    在populate 属性注入过程中调用,可以对属性值进行检查或修改。
    1
    2
    3
    4
    5
    @Nullable  
    default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
    throws BeansException {
    return null;
    }

1.1.2 SmartInstantiationAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor 是 Spring 框架中的一个接口,它扩展了 InstantiationAwareBeanPostProcessor 接口,提供了更细粒度的控制和额外的钩子方法来介入 Spring Bean 的实例化过程。这个接口主要用于在 Bean create之前、create之后、populate之前、populate之后等多个阶段执行自定义逻辑,从而实现更加复杂和灵活的 Bean 初始化控制。

  1. predictBeanType
    在实际创建 Bean 实例之前预测其类型。这对于提前检测某些类型相关的元数据很有用。

    1
    2
    3
    default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {  
    return null;
    }
  2. determineCandidateConstructors
    确定要用于创建 Bean 实例的候选构造函数。允许自定义选择用于实例化 Bean 的构造函数。

    1
    2
    3
    4
    5
    default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)  
    throws BeansException {

    return null;
    }
  3. getEarlyBeanReference
    允许在 Bean 实例化之前提前暴露 Bean 的引用。通常用于解决循环依赖问题

    1
    2
    3
    default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {  
    return bean;
    }

1.2 AbstractAutoProxyCreator

AbstractAutoProxyCreator 是一个抽象类,它继承自 ProxyProcessorSupport 并实现了 SmartInstantiationAwareBeanPostProcessorBeanFactoryAware 接口。这些接口和类提供了创建代理对象和与 Spring 容器集成的基础功能。

它的主要作用是自动为 Spring 容器中的 bean 创建代理对象,以便在这些 bean 的方法调用时插入横切关注点的逻辑。具体来说,AbstractAutoProxyCreator 的功能包括:

  1. 扫描和筛选 bean:在 Spring 容器初始化时,扫描所有 bean,根据配置的切点筛选出需要增强的 bean。
  2. 创建代理对象:为符合条件的 bean 创建代理对象,代理对象可以是 JDK 动态代理或 CGLIB 代理。
  3. 注册代理对象:将创建的代理对象注册到 Spring 容器中,替换原始的 bean。
  4. 处理生命周期回调:实现 BeanPostProcessor 接口中的 postProcessBeforeInitializationpostProcessAfterInitialization 方法,在 bean 初始化前后执行代理逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport  
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

/**
* Convenience constant for subclasses: Return value for "do not proxy".
* @see #getAdvicesAndAdvisorsForBean
*/
@Nullable
protected static final Object[] DO_NOT_PROXY = null;

/**
* Convenience constant for subclasses: Return value for
* "proxy without additional interceptors, just the common ones".
* @see #getAdvicesAndAdvisorsForBean
*/
protected static final Object[] PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS = new Object[0];


/** Logger available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());

/** Default is global AdvisorAdapterRegistry. */
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();

/**
* Indicates whether or not the proxy should be frozen. Overridden from super
* to prevent the configuration from becoming frozen too early.
*/
private boolean freezeProxy = false;

/** Default is no common interceptors. */
private String[] interceptorNames = new String[0];

private boolean applyCommonInterceptorsFirst = true;

@Nullable
private TargetSourceCreator[] customTargetSourceCreators;

@Nullable
private BeanFactory beanFactory;

private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));

private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);

private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);


// 保存已经处理过的bean信息。这个映射用于保存bean实例到布尔值的映射,指示这些bean是否已经被代理或不需要代理。缓存这些信息可以提高性能,避免重复处理。
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);
}

下面来分析一下AbstractAutoProxyCreator 的具体子类

1.2.1 AbstractAdvisorAutoProxyCreator

  • 作用:这个类是 AbstractAutoProxyCreator 的直接子类,它的主要作用是自动为 Spring Bean 创建代理对象,并将配置的切面(advice)应用到这些代理对象上。
  • 工作原理:它扫描 Spring 容器中的所有 Advisor(一个 Advisor 包含一个 Advice 和一个 Pointcut),并根据 Pointcut 的匹配规则,自动为匹配的 Bean 创建代理对象,并应用对应的 Advice

1.2.2 AspectJAwareAdvisorAutoProxyCreator

作用:这个类是 AbstractAdvisorAutoProxyCreator 的子类,主要用于处理基于 AspectJ 方式的 AOP 配置。
工作原理:它和 AnnotationAwareAspectJAutoProxyCreator 类似,但主要用于处理通过 XML 配置文件或其他非注解方式配置的 AspectJ 切面。

1.2.3 AnnotationAwareAspectJAutoProxyCreator

  • 作用:这个类是 AspectJAwareAdvisorAutoProxyCreator 的子类,它在 AbstractAdvisorAutoProxyCreator 的基础上增加了对 AspectJ 注解的支持。
  • 工作原理:它不仅扫描容器中的 Advisor,还扫描使用了 AspectJ 注解(如 @Aspect@Before@After 等)的 Bean,并将这些注解配置的切面应用到匹配的 Bean 上。

2. 自动代理工作流程

2.1 AnnotationAwareAspectJAutoProxyCreator的实例化

2.1.1 registerBeanPostProcessors

我们已经知道AnnotationAwareAspectJAutoProxyCreator其本质一个BeanPostProcessor 在 [Spring IOC 容器启动过程拓展点](obsidian://open?vault=Documents&file=second-brain%2F1-tech%2FSpring%20%E5%AE%B6%E6%97%8F%2Fnew%2F3-%20Spring%20%E6%8B%93%E5%B1%95%E7%82%B9) 一文中,已经详细介绍过 一个BeanPostProcessor的实例化或者注册过程,是在registerBeanPostProcessors`流程中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
AbstractApplicationContext.java
@Override
public void refresh() throws BeansException, IllegalStateException {

// 1. 创建beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// 2.Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

// 3.Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// 4. bean的生命周期管理和依赖关系的装配
finishBeanFactoryInitialization(beanFactory);
}

展开registerBeanPostProcessors 看一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
PostProcessorRegistrationDelegate.java
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
}

AbstractBeanFactory.java
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {

// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}

2.1.2 hasInstantiationAwareBeanPostProcessors

根据上面的继承依赖结构,可以看出AnnotationAwareAspectJAutoProxyCreator 实现了 InstantiationAwareBeanPostProcessor ,所以hasInstantiationAwareBeanPostProcessors会被设置为true

  1. 状态标记: 当Spring容器初始化时,会扫描并注册所有的BeanPostProcessor,并在适当的时候设置这个变量的值。如果容器中注册了至少一个InstantiationAwareBeanPostProcessor,这个变量会被设置为true。用于决定是否执行某些特定的处理逻辑。例如,在实例化bean之前,Spring容器会检查这个变量以决定是否需要调用InstantiationAwareBeanPostProcessorpostProcessBeforeInstantiation方法。
  2. 性能提升:如果没有注册任何InstantiationAwareBeanPostProcessor,则可以跳过一些不必要的检查和调用,从而提高性能。

2.2 代理对象的生成时机- init 阶段

业务bean 代理对象的生成时机,也可以理解成是AnnotationAwareAspectJAutoProxyCreator 的介入 bean 的生命周期,为业务bean生成代理对象的时机。

Spring bean 实例化一文中,已经介绍过,BeanPostProcessor 是在bean 实例化的init 阶段,通过 postProcessAfterInitialization 方法来介入普通bean 的生命周期,为其生成代理对象的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory  
implements AutowireCapableBeanFactory {
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {

invokeAwareMethods(beanName, bean);
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

invokeInitMethods(beanName, wrappedBean, mbd);

applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {

Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
}

当遇到AnnotationAwareAspectJAutoProxyCreator时, 会进行其postProcessAfterInitialization方法,开始执行代理对象生成的逻辑,下图debug 图片中,可以看到相关信息, 以及实际进入到的是AnnotationAwareAspectJAutoProxyCreator的父类,AbstractAutoProxyCreator

2.3 wrapIfNecessary

在SpringBoot 项目启动过程中,所有的业务bean 实例化过程中都在在initializeBean 阶段进入AnnotationAwareAspectJAutoProxyCreator.postProcessAfterInitialization方法,只要这个拓展点存在。也就是说,所有的bean都会进行是否代理的判断,只是有的不需要直接返回原bean即可,有的需要就行进行代理对象的生成并返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
@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创建代理对象以实现AOP(面向切面编程)的功能
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 检查Bean名称是否非空且是否已经在targetSourcedBeans集合中。
// 如果满足条件,说明这个Bean不需要代理,直接返回原始Bean。
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 从advisedBeans缓存中检查是否已经记录了该Bean不需要代理,即缓存中存在且值为Boolean.FALSE,直接返回原始Bean。
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 检查Bean是否是Spring的基础设施类,比如Advice、Advisor等
// 检查是否应该跳过代理该Bean
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
// 如果满足以上条件,记录该Bean不需要代理并返回原始Bean,看又出现了缓存用于提升性能
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

// Create proxy if we have advice.
// 获取可以用在该bean 上的增强
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// 如果没有需要用在该bean的Advice,
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建该bean的代理对象并记录
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
// 如果没有需要用在该bean的Advice, 记录该bean不需要代理直接返回即可
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

}

wrapIfNecessary方法的重点逻辑看2步

  1. getAdvicesAndAdvisorsForBean 为当前类寻找可用的增强
  2. createProxy 如果找到了可用的增强,则创建代理对象

    2.4 getAdvicesAndAdvisorsForBean

    为当前类寻找可用的增强
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
@Override
@Nullable
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) {
// 先找出当前Spring 容器中存在的所有Advisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 根据Advisor 找出可以用在当前bean上的增强
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}

// 找出当前Spring 容器中存在的所有Advisor
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}

// 根据Advisor 找出可以用在当前bean上的增强
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}


}

最终得到当前类可用的bean, 代理逻辑挺深的

  1. 找到当前Spring 容器中所有的Advisor
  2. 找到可以用在当前类的Advisor :对找到的所有的Advisor循环判断是否可以用在当前类上

我们重点看第二步,findAdvisorsThatCanApply 这个方法

2.4.1 findAdvisorsThatCanApply->canApply

在一组候选的Advisor中,找出可以应用于指定类的Advisor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
public abstract class AopUtils {

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
// 先处理 IntroductionAdvisor
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
// 再处理其他类型的Advisor
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}

// 对于IntroductionAdvisor,canApply(candidate, clazz)最终也是使用这个方法
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}


// 这里是真正的过滤逻辑, 先匹配类,再匹配方法
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}

MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}

IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}

Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}

return false;
}

}

整体逻辑

  1. 先把Advisor 分成两类,IntroductionAdvisor 和其他Advisor, 先检查和处理IntroductionAdvisor的主要原因是它们对目标类结构的影响较大,通过引入新的接口和功能,改变了目标类的形态。因此,在处理其他常规Advisor之前,确保IntroductionAdvisor已经被正确应用
  2. 对Advidor 依次进行类匹配、方法匹配, 看是否符合切点表达式,在以下方法中具体实现

Advisor 是一个复合概念,包括配套的PointcutAdvice

  1. Pointcut 中包含了对类的过滤条件 ClassFilter、方法的过滤条件MethodMatcher
  2. Advice 是符合Pointcut 切点条件的方法上需要执行的增强逻辑。
1
canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) 

观察这个方法的过滤逻辑, 其实和 Spring AOP XML配置方式原理详解getInterceptorsAndDynamicInterceptionAdvice方法的逻辑是一样的,都是通过ClassFilter匹配类,以及MethodMatcher匹配方法实现, 只不过在手动配置方式中,我们需要手动显示写明类去自定义实现 Pointcut、MethodMatcher ,但是在自动代理的注解方式中, Spring 会自动按照我们给出的切点表达式,自动实现这一功能。


2.5 createProxy

1
2
3
4
5
public class ProxyFactory extends ProxyCreatorSupport {
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
}

逻辑从这里开始就和 Spring AOP 注解方式原理详解中开始完全重合了,就不再赘述

  1. createAopProxy: 确定动态代理的类型, JDK 动态代理 or CGlib, 判断的逻辑也非常简单,可以简单认为就是有没有实现接口
    1. 实现了接口,用JDK 动态代理
    2. 没有实现接口,用CGlib 动态代理
  2. getProxy:根据确定的动态代理,创建target 的代理对象

最终给userService 生成了一个Cglib 动态代理对象

2.6 执行目标方法

不论是JDK 动态代理对象,还是CGLIB 动态代理对象, 执行目标方法时和
Spring AOP XML配置方式原理详解 中的逻辑完全一致,底层是公用事业一套代码逻辑的,这里就不再赘述。

3. 代理对象的获取方式对比

手动配置方式使用ProxyFactoryBean, 不介入到bean得生命周期,而是在实例化完成后通过getObjectForBeanInstance 完成代理对象的生成

注解方式的自动代理机制,介入bean 的生命周期,在init 阶段,通过BeanPostProcessor.postProcessAfterInitialization获取代理对象。

但是不论哪种方式, 底层判断使用哪种代理,增强织入的逻辑、以及方法的执行均是使用同一套代码完全相同的逻辑