首先给出 AOP 的实现过程的时序图

Spring 的 AOP 实现大致可以分为 2 个步骤

1.创建代理对象。这个阶段主要为代理对象的创建,封装好对应的 advise 集合

2.调用阶段,在调用阶段完成 aop 的功能

image-20200903172942096

过程分析

  1. 创建代理对象分析

    在上一篇博客中,我们有分析 DI 的实现过程,那么在实现 DI 的过程中,其实包含了对应的 AOP 过程,我们追踪到 AbstractAutowireCapableBeanFactory 的 creatBean 方法中,在调用 createBeanInstance 创建 bean 实例,populateBean 注入对应的属性之后,调用了 initializeBean 方法,这个方法就是 AOP 的创建代理对象的入口

  2. initializeBean 方法的具体代码如下

    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
    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    invokeAwareMethods(beanName, bean);
    return null;
    }, getAccessControlContext());
    }
    else {
    //为bean实例包装相关属性,如名称,类加载器,所属容器信息
    invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
    //bean实例化之前的前置处理
    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
    //调用bean实例初始化的方法
    invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
    throw new BeanCreationException(
    (mbd != null ? mbd.getResourceDescription() : null),
    beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
    //bean实例化之后的后置处理
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
    }

    这里面最主要有 3 个步骤,第一个调用 applyBeanPostProcessorsBeforeInitialization 方法,主要完成创建代理对象的前置工作。第二个调用 invokeInitMethods 方法,这个方法主要是调用 bean 对象声明的时候的 init 方法。第三个方法是 applyBeanPostProcessorsAfterInitialization,这个方法主要完成创建代理对象的后置工作。这里我们需要跟踪的是 applyBeanPostProcessorsAfterInitialization 方法。

  3. applyBeanPostProcessorsAfterInitialization 的具体方法如下

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	Object result = existingBean;
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
    Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
    if (current == null) {
    return result;
    }
    result = current;
    }
    return result;
    }

    这里主要委托给了 BeanPostProcessor 对象来实现功能,我们选择它的实现类 AbstractAutoProxyCreator 来查看具体的实现过程

  4. postProcessAfterInitialization 的具体方法如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
    if (bean != null) {
    Object cacheKey = getCacheKey(bean.getClass(), beanName);
    if (!this.earlyProxyReferences.contains(cacheKey)) {
    return wrapIfNecessary(bean, beanName, cacheKey);
    }
    }
    return bean;
    }

    这里我们需要注意的是 wrapIfNecessary 方法

    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
    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;
    }

    注意到,这里有注释的地方,这里就是获取在代理对象上面的所有 advice,然后按照排序规则返回。获取通知集合之后,然后调用 createProxy 方法,创建代理对象

  5. createProxy 方法的具体实现过程如下

    protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
    @Nullable Object[] specificInterceptors, TargetSource targetSource) {

    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
    	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);
    }

    return proxyFactory.getProxy(getProxyClassLoader());
    }

    最后调用代理工厂来获取对应的代理类,因为我们知道实现代理工厂的方式主要有 2 个,JDK 代理和 CGlib 代理,我们查看 JDK 代理 JdkDynamicAopProxy 的具体实现来查看。

  6. 我们发现 JdkDynamicAopProxy 实现了 InvocationHandler 接口中 invoke 方法,不难发现,在调用对象的时候,主要是调用的 invoke 方法,那么我们现在也就到了具体的调用阶段

    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
    83
    84
    85
    86
    87
    88
    89
    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 {
    if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
    // The target does not implement the equals(Object) method itself.
    return equals(args[0]);
    }
    else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
    // The target does not implement the hashCode() method itself.
    return hashCode();
    }
    else if (method.getDeclaringClass() == DecoratingProxy.class) {
    // There is only getDecoratedClass() declared -> dispatch to proxy config.
    return AopProxyUtils.ultimateTargetClass(this.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) {
    // 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);

    //获取所有在该方法上面的Interceptor集合
    // 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 {
    //调用对应的通知
    // 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;
    }
    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);
    }
    if (setProxyContext) {
    // Restore old proxy.
    AopContext.setCurrentProxy(oldProxy);
    }
    }
    }
  7. 查看 invocation.proceed()的调用过程,具体的实现类为 ReflectiveMethodInvocation

    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
    public Object proceed() throws Throwable {
    //Interceptor调用完之后调用
    // 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;
    //动态匹配,满足条件时调用拦截器
    if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
    return dm.interceptor.invoke(this);
    }
    else {
    //动态匹配失败,掉用下一个interceptor
    // Dynamic matching failed.
    // Skip this interceptor and invoke the next in the chain.
    return proceed();
    }
    }
    else {
    //执行当前interceptor
    // 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);
    }
    }
  8. 我们来看下具体的两个通知实例 MethodBeforeAdviceInterceptor 和 AfterReturningAdviceInterceptor,这 2 个通知的实现,有一定的差异

    1
    2
    3
    public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {

    private MethodBeforeAdvice advice;
     /**
      * Create a new MethodBeforeAdviceInterceptor for the given advice.
    • @param advice the MethodBeforeAdvice to wrap
      */
      public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
      Assert.notNull(advice, “Advice must not be null”);
      this.advice = advice;
      }
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        //先调用通知的前置方法,再调用proceed
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
        return mi.proceed();
    }

}

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

```java
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

private final AfterReturningAdvice advice;


/**
* Create a new AfterReturningAdviceInterceptor for the given advice.
* @param advice the AfterReturningAdvice to wrap
*/
public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//先调用proceed,在调用afterReturning方法
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}

}
这 2 这个类的差异实现了前置通知和后置通知的功能, 以上就是 AOP 的调用过程了。