Spring aop 源码分析 (2)

前置知识

在阅读此文章前, 建议先阅读一下

Spring aop 源码分析 (1)

创建代理对象

在上一篇文章中说道, AopProxyFactory通过一些条件判断创建的AopProxy是基于cglibCglibAopProxy还是基于jdkJdkDynamicAopProxy. 接下来我们就看看AopProxy到底是如何产生代理对象的, 并且代理过程是如何执行的

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
63
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
...

try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, ...);

Class<?> proxySuperClass = rootClass;
// 如果类名含有$$, 说明当前类已经是代理类了
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);

// 到了我们熟悉的gclib创建代理对象的过程了
// 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));

// 注意这个callbacks类型
Callback[] callbacks = getCallbacks(rootClass);
// 设置type
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// 设置interceptor过滤器
enhancer.setCallbackFilter(
new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(),
this.fixedInterceptorMap,
this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);

return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
...
}
catch (Throwable ex) {
...
}
}

getCallbacks

进入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
71
72
73
74
75
76
77
78
79
80
81
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();

// 非常关键
// 使用DynamicAdvisedInterceptor封装AdvisedSupport中的代理方法
// advice方法都在AdvisedSupport的成员变量中保存的
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

Callback targetInterceptor;
// 如果 aop proxy暴露给每个Invocation
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()));
}

// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(
this.advised.getTargetSource().getTarget()) :
new SerializableNoOp());
// 注意看, callbacks中并没有我们以为的自定义的增加
// 所有的callback, 注意: 我们写的代理方法并没有封装成callback, 而是MethodInvocation
// 后面会说道
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.
// 如果代理的是静态类, 并且advice chain被冻住了(没有改变)
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);

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

createProxyClassAndInstance

这里就是我们熟悉的cglib创建代理的方式

1
2
3
4
5
6
7
8
9
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
// 构造的时候是不能进行Intercept
enhancer.setInterceptDuringConstruction(false);
enhancer.setCallbacks(callbacks);
// 如果构造函数有参数, 使用create(Class[] argumentTypes, Object[] arguments)方法
return (this.constructorArgs != null && this.constructorArgTypes != null ?
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
enhancer.create());
}

到这里, 使用cglib创建代理对象的大致流程就完成了

JdkDynamicAopProxy

我们来看一下AopProxy是如何使用jdk代理方法创建代理对象的

getProxy

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// 获取需要被代理的接口
Class<?>[] proxiedInterfaces =
AopProxyUtils.completeProxiedInterfaces(this.advised, true);

findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 因为 JdkDynamicAopProxy本身就实现了InvocationHandler接口,所有这里传参了this
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

completeProxiedInterfaces

completeProxiedInterfaces方法就是把接口解析出来, 如果有代理Advised, SpringProxy等接口也会被添加到被代理的接口中

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
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
if (specifiedInterfaces.length == 0) {
// No user-specified interfaces: check whether target class is an interface.
Class<?> targetClass = advised.getTargetClass();
if (targetClass != null) {
if (targetClass.isInterface()) {
advised.setInterfaces(targetClass);
}
else if (Proxy.isProxyClass(targetClass)) {
advised.setInterfaces(targetClass.getInterfaces());
}
specifiedInterfaces = advised.getProxiedInterfaces();
}
}
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
int nonUserIfcCount = 0;
if (addSpringProxy) {
nonUserIfcCount++;
}
if (addAdvised) {
nonUserIfcCount++;
}
if (addDecoratingProxy) {
nonUserIfcCount++;
}
Class<?>[] proxiedInterfaces =
new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
int index = specifiedInterfaces.length;
if (addSpringProxy) {
proxiedInterfaces[index] = SpringProxy.class;
index++;
}
if (addAdvised) {
proxiedInterfaces[index] = Advised.class;
index++;
}
if (addDecoratingProxy) {
proxiedInterfaces[index] = DecoratingProxy.class;
}
return proxiedInterfaces;
}

方法调用

DynamicAdvisedInterceptor

实现cglibMethodInterceptor接口的类有很多, 例如DynamicAdvisedInterceptor, FixedChainStaticTargetInterceptor, HashCodeInterceptor

这里选择一个比较有代表性的类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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {

private final AdvisedSupport advised;
// 构造方法中传入了AdvisedSupport
// AdvisedSupport中才是我们自己写的代理逻辑方法
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;
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.
// 如果advice chain是空的, 就直接调用方法获得返回值, 不用创建MethodInvocation
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 {
// 需要创建 method invocation...
// 然后调用proceed方法
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);
}
}
}

@Override
public boolean equals(@Nullable Object other) {
return (this == other ||
(other instanceof DynamicAdvisedInterceptor &&
this.advised.equals(((DynamicAdvisedInterceptor) other).advised)));
}

/**
* CGLIB uses this to drive proxy creation.
*/
@Override
public int hashCode() {
return this.advised.hashCode();
}
}

CglibMethodInvocation

进入关键类CglibMethodInvocationprocess方法,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public Object proceed() throws Throwable {
try {
// 调用父类方法
return super.proceed();
}
catch (RuntimeException ex) {
throw ex;
}
catch (Exception ex) {
if (ReflectionUtils.declaresException(getMethod(), ex.getClass())) {
throw ex;
}
else {
throw new UndeclaredThrowableException(ex);
}
}
}

ReflectiveMethodInvocation中的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
26
27
28
29
30
31
32
33
34
public Object proceed() throws Throwable {
// 如果是最后一个
if (this.currentInterceptorIndex ==
this.interceptorsAndDynamicMethodMatchers.size() - 1)
{
return invokeJoinpoint();
}

// 获取一个advice
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 如果是matcher类
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());
// 如果matcher中的方法满足当前方法, 就调用
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// 不匹配当前方法, 跳过递归执行其他方法
return proceed();
}
}
else {
// 如果是 MethodInterceptor, 就直接调用方法
// 这个 MethodInterceptor是spring的,不是cglib的, 注意区别
// this 实现了MethodInvocation接口, 相当于一个joinpoint
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}

JdkDynamicAopProxy

jdk的动态代理是通过invoke方法增强我们自己的代理逻辑, JdkDynamicAopProxy实现InvocationHandler接口, 创建代理对象时候需要传递的InvocationHandler参数就是this, 即JdkDynamicAopProxy. 所以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
90
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;

TargetSource targetSource = this.advised.targetSource;
Object target = null;

try {
// 如果代理了equals方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
// 如果代理的是hashcode方法
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);

// Get the interception chain for this method.
/// interceptor chain
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

// 如果chain是空的, 就不需要执行我们自定义的MethodInvocation
// 直接使用反射调用方法结束
if (chain.isEmpty()) {
// 获取参数
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
// 参照上面关于ReflectiveMethodInvocation的源码说明
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass,
chain);
retVal = invocation.proceed();
}

// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
// 返回值是this的情况
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;
}
// 如果返回值是null, 但是返回值要求的类型是基础类型,null转为基础类型就会报错
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException...
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}

AdvisedSupport

getInterceptorsAndDynamicInterceptionAdvice

这个方法回去遍历所有我们自定义的advice, 并且会缓存(通过代理的方法信息缓存), 这样就不用每次都去遍历所有的advice了

1
2
3
4
5
6
7
8
9
10
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, 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;
}

DefaultAdvisorChainFactory

在这个类中我们具体看一下是如何获取的InterceptionAdvice的

getInterceptorsAndDynamicInterceptionAdvice

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
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {

// 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;
// 遍历所有的advice
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);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
// 如果匹配当前方法
if (match) {
// 对advisor会有一个封装, 感兴趣的话可以自己看一下源码
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;
}

总结

我们自定义的代理逻辑大部分没有被封装成MethodInterceptor(cglib)或者InvocationHandler(jdk), 而是封装成一个个的MethodInterceptor(spring自己实现的类). spring-aop在代理过程中通过MethodInterceptor(cglib)InvocationHandler(jdk)中的代理方法去调用MethodInvocation(spring定义的接口), 而在MethodInvocationproceed的方法中去依次调用MethodInterceptor(spring自己实现)中的invoke方法, 去完成我们需要的逻辑

声明

如有错误请联系作者更正