Spring AOP核心源码、原理
2022-02-11 / Lampkins   

Advice通知相关的类

image-20220706231214818

通知包装器

负责将各种非MethodInterceptor类型的通知(Advice)包装为MethodInterceptor类型。

  • MethodBeforeAdviceInterceptor

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    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();
    }
    }
  • AfterReturningAdviceInterceptor

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

    private final AfterReturningAdvice advice;

    public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
    Assert.notNull(advice, "Advice must not be null");
    this.advice = advice;
    }

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
    //先执行方法调用链,可以获取目标方法的执行结果
    Object retVal = mi.proceed();
    //执行后置通知
    this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
    return retVal;
    }
    }
  • ThrowsAdviceInterceptor

    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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {

    private static final String AFTER_THROWING = "afterThrowing";

    private static final Log logger = LogFactory.getLog(ThrowsAdviceInterceptor.class);

    private final Object throwsAdvice;

    /** Methods on throws advice, keyed by exception class. */
    private final Map<Class<?>, Method> exceptionHandlerMap = new HashMap<>();

    public ThrowsAdviceInterceptor(Object throwsAdvice) {
    Assert.notNull(throwsAdvice, "Advice must not be null");
    this.throwsAdvice = throwsAdvice;
    //获取异常通知中定义的所有方法(public、默认的、protected、private)
    Method[] methods = throwsAdvice.getClass().getMethods();
    //轮询methods
    for (Method method : methods) {
    //方法名称为afterThrowing && 方法参数为1或者4
    if (method.getName().equals(AFTER_THROWING) &&
    (method.getParameterCount() == 1 || method.getParameterCount() == 4)) {
    //获取方法的最后一个参数类型
    Class<?> throwableParam = method.getParameterTypes()[method.getParameterCount() - 1];
    //判断方法参数类型是不是Throwable类型的
    if (Throwable.class.isAssignableFrom(throwableParam)) {
    // 缓存异常处理方法到map中(异常类型->异常处理方法)
    this.exceptionHandlerMap.put(throwableParam, method);
    if (logger.isDebugEnabled()) {
    logger.debug("Found exception handler method on throws advice: " + method);
    }
    }
    }
    }
    // 不能为空,最少要有一个异常处理方法
    if (this.exceptionHandlerMap.isEmpty()) {
    throw new IllegalArgumentException(
    "At least one handler method must be found in class [" + throwsAdvice.getClass() + "]");
    }
    }

    // 获取异常通知中自定义的处理异常方法的数量
    public int getHandlerMethodCount() {
    return this.exceptionHandlerMap.size();
    }

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
    try {
    //调用通知链
    return mi.proceed();
    }
    catch (Throwable ex) {
    //获取异常通知中自定义的处理异常的方法
    Method handlerMethod = getExceptionHandler(ex);
    if (handlerMethod != null) {
    //调用异常处理方法
    invokeHandlerMethod(mi, ex, handlerMethod);
    }
    //继续向外抛出异常
    throw ex;
    }
    }

    // 获取throwsAdvice中处理exception参数指定的异常的方法
    @Nullable
    private Method getExceptionHandler(Throwable exception) {
    //获取异常类型
    Class<?> exceptionClass = exception.getClass();
    if (logger.isTraceEnabled()) {
    logger.trace("Trying to find handler for exception of type [" + exceptionClass.getName() + "]");
    }
    //从缓存中获取异常类型对应的方法
    Method handler = this.exceptionHandlerMap.get(exceptionClass);
    // 循环获取异常的父类型及对应缓存的处理方法
    while (handler == null && exceptionClass != Throwable.class) {
    exceptionClass = exceptionClass.getSuperclass();
    handler = this.exceptionHandlerMap.get(exceptionClass);
    }
    if (handler != null && logger.isTraceEnabled()) {
    logger.trace("Found handler for exception of type [" + exceptionClass.getName() + "]: " + handler);
    }
    return handler;
    }

    //通过反射调用异常通知中的异常方法
    private void invokeHandlerMethod(MethodInvocation mi, Throwable ex, Method method) throws Throwable {
    Object[] handlerArgs;
    //若只有1个参数,参数为:异常对象
    if (method.getParameterCount() == 1) {
    handlerArgs = new Object[] {ex};
    }
    else {
    //4个参数(方法、方法请求参数、目标对象、异常对象)
    handlerArgs = new Object[] {mi.getMethod(), mi.getArguments(), mi.getThis(), ex};
    }
    try {
    //通过反射调用异常通知中的方法
    method.invoke(this.throwsAdvice, handlerArgs);
    }
    catch (InvocationTargetException targetEx) {
    throw targetEx.getTargetException();
    }
    }
    }

PointCut切入点相关类

image-20220707003232219

MethodMatcher过滤流程:

  •         调用matches(Method method, Class<?> targetClass)方法,验证方法是否匹配
    
  •         isRuntime方法(动态匹配)是否为true,如果为false,则以第一步的结果为准,否则继续向下
    
  •         调用matches(Method method, Class<?> targetClass, Object... args)方法继续验证,可以对目标方法传入的参数进行校验。
    

Advisor顾问

image-20220707003907469

  • DefaultPointcutAdvisor类:里面定义了2个属性:pointcut和advisor,由使用者指定
  • IntroductionAdvisor接口:可以给目标类引入更多接口的功能

代理创建过程源码解析

创建代理3大步骤:

1. 创建代理所需参数配置

image-20220707005628299

2. 根据配置获取AopProxy对象

1
2
3
4
// 创建AopProxy使用了简单工厂模式 
AopProxyFactory aopProxyFactory = new DefaultAopProxyFactory();
//通过AopProxy工厂获取AopProxy对象
AopProxy aopProxy = aopProxyFactory.createAopProxy(advisedSupport);

此阶段会根据AdvisedSupport中配置信息,判断具体是采用cglib的方式还是采用jdk动态代理的方式获取代理对象

image-20220707004544447

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
/**
* 默认AopProxyFactory实现,创建CGLIB代理或JDK动态代理。
* 对于给定的AdvisedSupport实例,以下条件为真,则创建一个CGLIB代理:
* optimize = true || proxyTargetClass = true || 未指定代理接口
* 通常,指定proxyTargetClass来强制执行CGLIB代理,或者指定一个或多个接口来使用JDK动态代理。
*/
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (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.");
}
//如果被代理的类为接口 或者 被代理的类是jdk动态代理创建代理类,则采用JdkDynamicAopProxy的方式,否则采用cglib代理的方式
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}

// 确定所提供的AdvisedSupport是否只指定了SpringProxy接口(或者根本没有指定代理接口)
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] ifcs = config.getProxiedInterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}

}

3. 通过AopProxy创建代理对象

AopProxy.getProxy

  • JdkDynamicAopProxy:以jdk动态代理的方式创建代理

  • ObjenesisCglibAopProxy:以cglib的方式创建动态代理

JdkDynamicAopProxy类

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

/** use serialVersionUID from Spring 1.2 for interoperability. */
private static final long serialVersionUID = 5531744639992436476L;

/** We use a static Log to avoid serialization issues. */
private static final Log logger = LogFactory.getLog(JdkDynamicAopProxy.class);

//代理的配置信息
private final AdvisedSupport advised;

//需要被代理的接口中是否定义了equals方法
private boolean equalsDefined;

//需要被代理的接口中是否定义了hashCode方法
private boolean hashCodeDefined;


//通过AdvisedSupport创建实例
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
}

//生成一个代理对象
@Override
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// @0:根据advised的信息获取代理需要被代理的所有接口列表
// [开发者硬编码指定的需要被代理的接口列表,SpringProxy,Advised,DecoratingProxy]
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
//查找被代理的接口中是否定义了equals、hashCode方法
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//通过jdk动态代理创建代理对象,注意最后一个参数是this表示当前类,当前类是InvocationHandler类型的,当调用代理对象的任何方法的时候都会被被当前类的 invoke 方法处理 */
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

//查找被代理的接口中是否定义了equals、hashCode方法
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
for (Class<?> proxiedInterface : proxiedInterfaces) {
Method[] methods = proxiedInterface.getDeclaredMethods();
for (Method method : methods) {
if (AopUtils.isEqualsMethod(method)) {
this.equalsDefined = true;
}
if (AopUtils.isHashCodeMethod(method)) {
this.hashCodeDefined = true;
}
if (this.equalsDefined && this.hashCodeDefined) {
return;
}
}
}
}


//当在程序中调用代理对象的任何方法,最终都会被下面这个invoke方法处理
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
//用来标记是否需要将代理对象暴露在ThreadLocal中
boolean setProxyContext = false;
//获取目标源
TargetSource targetSource = this.advised.targetSource;
//目标对象
Object target = null;

try {
//处理equals方法:被代理的接口中没有定义equals方法 && 当前调用是equals方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// 直接调用当前类中的equals方法
return equals(args[0]);
}
// 处理hashCode方法:被代理的接口中没有定义hashCode方法 && 当前调用是 hashCode方法
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// 直接调用当前类中的hashCode方法
return hashCode();
}
// 方法来源于 DecoratingProxy 接口,这个接口中定义了一个方法用来获取原始的被代理的目标类,主要是用在嵌套代理的情况下(嵌套代理:代理对象又被作为目标对象进行了代理)
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// 内部通过循环遍历的方式,找到最原始的被代理的目标类
return AopProxyUtils.ultimateTargetClass(this.advised);
}
// 方法来源于Advised接口,代理对象默认情况下会实现Advised接口,可以通过代理对象来动态向代理对象中添加通知等
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// this.advised是AdvisedSupport类型的,AdvisedSupport实现了Advised 接口中的所有方法
// 所以最终通过反射方式交给this.advised来响应当前调用
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}

// 用来记录方法返回值
Object retVal;

//是否需要在threadLocal中暴露代理对象
if (this.advised.exposeProxy) {
// 将代理对象暴露在上线文中,即暴露在threadLocal中,那么在当前线程中可以通过静态方法AopContext#currentProxy获取当前被暴露的代理对象
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}

// 通过目标源获取目标对象
target = targetSource.getTarget();
// 获取目标对象类型
Class<?> targetClass = (target != null ? target.getClass() : null);

// @1:获取当前方法的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

// 拦截器链为空的情况下,表示这个方法上面没有找到任何增强的通知,那么会直接通过反射直接调用目标对象
if (chain.isEmpty()) {
// 获取方法请求的参数(有时候方法中有可变参数(...)这种格式的参数,传入的参数类型和这种类型不一样的时候,会通过下面的adaptArgumentsIfNecessary方法进行转换)
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
//通过反射直接调用目标方法
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 创建一个方法调用器(包含了代理对象、目标对象、调用的方法、参数、目标类型、 方法拦截器链)
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// @3:通过拦截器链一个个调用最终到目标方法的调用
retVal = invocation.proceed();
}

// 下面会根据方法返回值的类型,做一些处理,比如方法返回的类型为自己,则最后需要将返回值置为代理对象
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// 将返回值设置为代理对象
retVal = proxy;
}
//retVal为null && 不为void && 方法的返回值类型returnType为八大基本类型
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 {
// 目标对象不为null && 目标源不是静态的或者说不是单例的
if (target != null && !targetSource.isStatic()) {
// 必须释放来自TargetSource中的目标对象
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// 需要将旧的代理再放回到上线文中
AopContext.setCurrentProxy(oldProxy);
}
}
}
...
}

小结

  1. 被创建的代理对象默认会实现 SpringProxy,Advised,DecoratingProxy 3个接口

  2. SpringProxy 这个接口中没有任何方法,只是起一个标记作用,用来标记代理对象是使用spring aop创建的

  3. 代理对象默认都会实现 Advised 接口,所以可以通过这个接口动态变更代理对象中的通知

  4. DecoratingProxy 接口中定义了一个方法 getDecoratedClass ,用来获取被代理的原始目标对象的类型

CglibAopProxy类

  • getProxy
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
public Object getProxy(@Nullable ClassLoader classLoader) {
try {
// 获取被代理的类
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

// 代理对象的父类(cglib是采用继承的方式来创建代理对象的,所以将被代理的类作为代理对象的父类)
Class<?> proxySuperClass = rootClass;
// 判断被代理的类是不是cglib创建的类,如果是cblib创建的类,会将其父类作为被代理的类
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
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);

// 开始cglib创建代理
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
// 设置被代理的接口[开发者硬编码指定的需要被代理的接口列表,SpringProxy,Advised],这个比jdk动态代理的方式少了一个DecoratingProxy接口
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
// 设置代理类类名生成策略(被代理class name + "$$" + 使用cglib处理的class name + "BySpringCGLIB" + "$$" + key的 hashcode)
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
// 设置字节码的生成策略
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

// @1:获取Callback列表,
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// @2:设置CallbackFilter,其内部会判断被代理对象中的方法最终会被callbacks列表中的那个Callback来处理
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);

// 获取代理对象(内部会先创建代理类,然后会根据代理类生成一个代理对象)
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
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
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// 是否需要将代理暴露在threadLocal中
boolean exposeProxy = this.advised.isExposeProxy();
// 配置是否是冻结的
boolean isFrozen = this.advised.isFrozen();
// 被代理的目标对象是否是静态的(是否是单例的)
boolean isStatic = this.advised.getTargetSource().isStatic();

// @1当方法上有需要执行的拦截器的时候,会用这个来处理
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

// 当方法上没有需要执行的拦截器的时候,会使用targetInterceptor来处理,内部会通过反射直接 调用目标对象的方法
Callback targetInterceptor;
// 根据是否要存储到threadLocal或是否要释放资源来创建不同的类
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()));
}

// targetDispatcher会直接调用目标方法
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());

Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // 处理匹配到拦截器的方法
targetInterceptor, // 处理未匹配到拦截器的方法
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, // 处理未匹配到拦截器的方法,目标方法如果返回值的结果是目标对象类型的,会使用 targetInterceptor 处理,内部会返回代理对象
this.advisedDispatcher, // 处理Advised接口中定义的方法
new EqualsInterceptor(this.advised), // 处理equals方法
new HashCodeInterceptor(this.advised) // 处理hashCode方法
};

Callback[] callbacks;

// 如果被代理的对象是单例的 && 配置是冻结的,此时会进行优化,
// 配置冻结的情况下,生成好的代理中通知是无法修改的,所以可以提前将每个方法对应的拦截器链找到给缓存起来
// 调用方法的时候,就直接从缓存中可以拿到方法对应的缓存信息,效率会高一些
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);

// 获取每个方法的调用链,然后给缓存在fixedInterceptorMap中
for (int x = 0; x < methods.length; x++) {
Method method = methods[x];
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(method, x);
}

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

DynamicAdvisedInterceptor类:处理拦截器类

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
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
//代理配置信息
private final AdvisedSupport advised;

public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}

// 用来处理代理对象中方法的调用
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null; //被暴露在threadLocal中旧的代理对象
boolean setProxyContext = false; //用来标记代理对象是否被暴露在threadLocal中
Object target = null; //目标对象
TargetSource targetSource = this.advised.getTargetSource(); //目标源
try {
//代理配置中是否需要将代理暴露在threadLocal中
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//获取目标对象(即被代理的对象)
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
//@1:获取当前方法的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal; //记录方法返回值
//拦截器链为空 && 方法是public类型的
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// 获取方法请求的参数(有时候方法中有可变参数(...)这种格式的参数,传入的参数类型和这种类型不一样的时候,会通过下面的adaptArgumentsIfNecessary方法进行转换)
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 直接调用目标对象的方法
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// 创建一个方法调用器(包含了代理对象、目标对象、调用的方法、参数、目标类型、 方法拦截器链)
// @2:并执行方法调用器的processd()方法,此方法会一次执行方法调用链,最终会调用目标方法,获取返回结果
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
// 处理方法返回结果:会根据方法返回值的类型,做一些处理,比如方法返回的类型为自己,则最后需要将返回值置为代理对象
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
// 目标对象不为null && 目标源不是静态的或者说不是单例的
if (target != null && !targetSource.isStatic()) {
// 必须释放来自TargetSource中的目标对象
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
}

方法拦截器链的获取

image-20220707230535133

代理方法的调用过程(拦截器链的执行)

创建完代理对象后,开始使用,在代理对象上执行一些方法调用,此时会依次调用此方法上的所有MethodInterceptor,最终会调用到目标上对应的方法。

image-20220707010100510

  • jdk动态代理:ReflectiveMethodInvocation#proceed

  • cglib代理:CglibAopProxy.CglibMethodInvocation#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
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
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
//生成的代理对象
protected final Object proxy;
//被代理的目标对象
protected final Object target;
//被调用的方法
protected final Method method;
//调用方法传入参数
protected Object[] arguments;
//目标对象类型
private final Class<?> targetClass;

//当期被调用的方法上匹配的 MethodInterceptor and InterceptorAndDynamicMethodMatcher 列表,即方法调用链列表
protected final List<?> interceptorsAndDynamicMethodMatchers;

//当前正在调用的连接器索引
private int currentInterceptorIndex = -1;

protected ReflectiveMethodInvocation(
Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,
@Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {

this.proxy = proxy;
this.target = target;
this.targetClass = targetClass;
this.method = BridgeMethodResolver.findBridgedMethod(method);
this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
}

// 处理被调用的方法,会递归进行调用,所有的拦截器都执行完毕之后,会通过反射调用目标方法
public Object proceed() throws Throwable {
// 拦截器都执行完毕之后,通过反射调用目标对象中的方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}

//获取++this.currentInterceptorIndex指定的拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
//判断拦截器是否是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 {
//执行拦截器的调用
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}

//通过反射调用目标方法
@Nullable
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}

...
}

创建AOP代理

image-20220708212633217

ProxyFactoryBean创建

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
@Configuration
public class MainConfig1 {
@Bean
public Service1 service1() { return new Service1(); }
@Bean
public Advisor interceptor1() {
MethodBeforeAdvice advice = new MethodBeforeAdvice() {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("准备调用"+method);
}
};

// 批量注册时,增强器的类型需要包装成Advisor类型
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
advisor.setAdvice(advice);
return advisor;
}

@Bean
public MethodInterceptor interceptor2() {
MethodInterceptor methodInterceptor = new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
long starTime = System.nanoTime();
Object result = invocation.proceed();
long endTime = System.nanoTime();
System.out.println(invocation.getMethod() + ",耗时(纳秒):" + (endTime - starTime));
return result;
}
};
return methodInterceptor;
}

@Bean
public AfterReturningAdvice afterReturningAdvice() {
AfterReturningAdvice afterReturningAdvice = new AfterReturningAdvice() {
@Override public void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable {
System.out.println(method + ",执行完毕!");
}
};
return afterReturningAdvice;
}

@Bean
public ProxyFactoryBean service1Proxy() {
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
proxyFactoryBean.setTargetName("service1");
// 批量注册时类型:org.springframework.aop.Advisor 或 org.aopalliance.intercept.Interceptor
proxyFactoryBean.setInterceptorNames("interceptor*", "afterReturningAdvice"); // *匹配符
return proxyFactoryBean;
}
}

ProxyFactoryBean类主要方法

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
public Object getObject() throws BeansException { 
//初始化advisor(拦截器)链
initializeAdvisorChain();
//是否是单例
if (isSingleton()) {
//创建单例代理对象 return getSingletonInstance();
}else {
//创建多例代理对象
return newPrototypeInstance();
}
}

private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
if (this.advisorChainInitialized) {
return;
}

if (!ObjectUtils.isEmpty(this.interceptorNames)) {
// 轮询 interceptorNames
for (String name : this.interceptorNames) {
//批量注册的方式:判断name是否以*结尾
if (name.endsWith(GLOBAL_SUFFIX)) {
if (!(this.beanFactory instanceof ListableBeanFactory)) {
throw new AopConfigException(
"Can only use global advisors or interceptors with a ListableBeanFactory");
}
//@1:从容器中匹配查找匹配的增强器,将其添加到aop配置中
addGlobalAdvisors((ListableBeanFactory) this.beanFactory,
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
}

else {
//非匹配的方式:按照name查找bean
Object advice;
if (this.singleton || this.beanFactory.isSingleton(name)) {
advice = this.beanFactory.getBean(name);
}
else {
advice = new PrototypePlaceholderAdvisor(name);
}
// 将advice包装为Advisor丢到aop配置中
addAdvisorOnChainCreation(advice);
}
}
}

this.advisorChainInitialized = true;
}

AspectJProxyFactory创建

@Aspect 标注的类上,这个类中,可以通过通过 @Pointcut 来定义切入点,可以通过 @Before@Around@After@AfterRunning@AfterThrowing 标注在方法上来定义通知,定义好了之后,将@Aspect标注的这个类交给 AspectJProxyFactory 来解析生成 Advisor 链,进而结合目标对象一起来生成代理对象.

@Pointcut的12种用法

表达式标签(10种):

  • execution:用于匹配方法执行的连接点

  • within:用于匹配指定类型内的方法执行

  • this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配

  • target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配

  • args:用于匹配当前执行的方法传入的参数为指定类型的执行方法

  • @within:用于匹配所有持有指定注解类型内的方法

  • @target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解

  • @args:用于匹配当前执行的方法传入的参数所属的类持有指定注解的

  • @annotation:用于匹配当前执行方法持有指定注解的

  • bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法

execution格式

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

  • 带?号的为可选项
  • modifier-pattern? 修饰符匹配,如public 表示匹配公有方法
  • ret-type-pattern 返回值匹配,* 表示任何返回值,全路径的类名等
  • declaring-type-pattern? 类路径匹配,com.example…IService+代表com.example包及其子包下所有IService接口及子类型的
  • name-pattern 方法名匹配,* 代表所有,set*,代表以set开头的所有方法
  • (param-pattern) 参数匹配,(…)代表所有参数;(*,String)代表第一个参数为任何值,第二个为String类型;(…,String)代表最后一个参数是String类型
  • throws-pattern? 异常类型匹配
表达式标签 判断的对象 判断规则**(x****:指表达式中指定的类型****)**
within target对象 target.getClass().equals(表达式中指定的类型)
this proxy对象 x.getClass().isAssignableFrom(proxy.getClass());
target target对象 x.getClass().isAssignableFrom(target.getClass());

image-20220708234953751

@Aspect中5种通知

  1. @Before:前置通知, 在方法执行之前执行

  2. @Aroud:环绕通知, 围绕着方法执行

  3. @After:后置通知, 在方法执行之后执行

  4. @AfterReturning:返回通知, 在方法返回结果之后执行

  5. @AfterThrowing:异常通知, 在方法抛出异常之后

微信图片_20220716155002

执行顺序

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
// ReflectiveAspectJAdvisorFactory,v5.2.9.RELEASE
// 执行顺序:@Around、@Before、@After、@AfterReturning、@AfterThrowing
private static final Comparator<Method> METHOD_COMPARATOR;

static {
// 通过instanceOrder数组索引位置来排序
Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
new InstanceComparator<>(
Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
(Converter<Method, Annotation>) method -> {
AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
return (ann != null ? ann.getAnnotation() : null);
});
Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
METHOD_COMPARATOR = adviceKindComparator.thenComparing(methodNameComparator);
}

// 在CglibAopProxy.CglibMethodInvocation#proceed中根据拦截器链依次执行拦截器
// 注意每次调用拦截器时都会使用到proceed中双catch的方式,下面只保留了最外面的
// 构造出的执行顺序大致如下:
try {

System.out.println("@Around通知start");
System.out.println("@Before通知!");
Object retVal = null;
try {
try {
retVal = mi.proceed();
} catch (Throwable ex) {
// 抛出的异常是给定抛出类型的子类型时
if (shouldInvokeOnThrowing(ex)) {
System.out.println("@AfterThrowing通知!");
}
//继续抛出异常
throw ex;
}
System.out.println("@AfterReturning通知!");
} finally {
System.out.println("@After通知!");
}
System.out.println("@Around通知end");
return retVal;
} catch (RuntimeException ex) {
// 抛出运行时异常
throw ex;
} catch (Exception ex) {
if (ReflectionUtils.declaresException(getMethod(), ex.getClass())) {
throw ex;
}
// 方法未声明该异常则抛出UndeclaredThrowableException异常
else {
throw new UndeclaredThrowableException(ex);
}
}
本文链接:
http://lampkins.gitee.io/2022/02/11/Spring-AOP%E6%A0%B8%E5%BF%83%E6%BA%90%E7%A0%81%E3%80%81%E5%8E%9F%E7%90%86/