以JDK动态代理为例,看一下Aop代理的拦截机制:
JdkDynamicAopProxy的invoke拦截
使用JDK动态代理生成代理对象时,需要传入三个参数,分别是目标对象的类加载器loader、目标对象的接口interfaces、一个InvocationHandler对象:1
2
3public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
InvocationHandler是一个接口,定义了一个invoke方法,对目标对象方法调用的拦截就是在invoke方法中实现的。1
2
3
4public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
JdkDynamicAopProxy
1.拦截器链的调用
JdkDynamicAopProxy实现了InvocationHandler接口,因此生成代理对象时,可以将自身作为参数传入。
1 | final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable { |
(1)在invoke方法中,如果没有配置拦截器,将会通过AopUtils的invokeJoinpointUsingReflection方法,使用反射机制对目标对象的方法进行调用。
1 | public abstract class AopUtils { |
(2)如果配置了拦截器,会获创建一个ReflectiveMethodInvocation对象,通过ReflectiveMethodInvocation对象的proceed方法逐个运行拦截器的拦截方法,从而完成整个拦截器链的调用。当拦截器链执行完毕后,同样使用反射机制执行目标对象中的方法。
在运行拦截器的拦截方法之前,会进行动态匹配判断,判断是否和定义的pointcut匹配,如果匹配就会执行这个advice。
1 | public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable { |
2.配置通知器
回到JdkDynamicAopProxy的ivoke方法中,有一个获取当前方法的拦截器链的过程:
1 | List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); |
getInterceptorsAndDynamicInterceptionAdvice方法是在AdvisedSupport类中实现的,在这个方法中,还使用到了缓存:
1 | public class AdvisedSupport extends ProxyConfig implements Advised { |
如果缓存中不存在拦截器链,会调用AdvisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice方法获取拦截器链,AdvisorChainFactory是一个生产通知器链的工厂:
1 | public interface AdvisorChainFactory { |
AdvisorChainFactory是一个接口,它的子类DefaultAdvisorChainFactory实现了该方法:
1 | public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable { |
来看这行代码,从GlobalAdvisorAdapterRegistry类中获取了通知适配器注册实例AdvisorAdapterRegistry:
1 | AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); |
GlobalAdvisorAdapterRegistry
GlobalAdvisorAdapterRegistry是一个抽象类,返回的是一个单例模式的DefaultAdvisorAdapterRegistry对象:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public abstract class GlobalAdvisorAdapterRegistry {
/**
* 单例模式,使用了DefaultAdvisorAdapterRegistry实现
*/
private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();
/**
* 返回实例
*/
public static AdvisorAdapterRegistry getInstance() {
return instance;
}
/**
* 重置
*/
static void reset() {
instance = new DefaultAdvisorAdapterRegistry();
}
}
DefaultAdvisorAdapterRegistry
DefaultAdvisorAdapterRegistry在构造方法中注册了一系列的适配器,在getInterceptors方法中通过适配器模式完成了advice向拦截器的转换: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
69public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
private final List<AdvisorAdapter> adapters = new ArrayList<>(3);
/**
* 构造函数,注册适配器
*/
public DefaultAdvisorAdapterRegistry() {
//前置通知
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
/**
* 获取拦截器
*/
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
//创建一个list,存放的类型是MethodInterceptor
List<MethodInterceptor> interceptors = new ArrayList<>(3);
//从Advisor通知器配置中获取advice通知
Advice advice = advisor.getAdvice();
//如果是MethodInterceptor类型的,不需要适配器,直接加入拦截器集合中
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
//这里判断取得的advice是什么类型的通知器,从而注册不同的拦截器
if (adapter.supportsAdvice(advice)) {
//advice转为拦截器加入到集合
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
}
getInterceptors方法中,传入的参数是Advisor类型的通知,返回的是方法拦截器集合,每个通知器都有对应的方法拦截器,比如BeforeAdvice通知器的拦截器是MethodBeforeAdviceInterceptor,该方法的作用就是通过适配器模式将通知器转为对应的方法拦截器。所以通知器如果是MethodInterceptor类型的直接加入集合,如果不是,需要通过适配器模式将通知转为拦截器:
1 | for (AdvisorAdapter adapter : this.adapters) { |
Spring AOP适配器模式的应用
1.AdvisorAdapter
上面知道通过调用AdvisorAdapter的getInterceptor方法将通知器advisor转为了对应的拦截器MethodInterceptor,AdvisorAdapter是一个接口,定义了两个方法,分别是
supportsAdvice和getInterceptor:
1 | public interface AdvisorAdapter { |
MethodInterceptor
1 |
|
2.MethodBeforeAdviceAdapter
以MethodBeforeAdviceAdapter为例看一下如何转换的:
1 | class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable { |
MethodBeforeAdviceInterceptor
MethodBeforeAdviceInterceptor实现了MethodInterceptor接口,1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
private MethodBeforeAdvice advice;
/**
* 构造函数
*/
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
/**
* 拦截器的回调方法,会在代理对象的方法被调用前调用
*/
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
}
参考:
spring技术内幕:深入解析spring架构与设计原理
Spring版本:5.0.5