其实当我们访问代理对象(也就是Spring Aop原理分析(一)最后所说的Bean)到最后访问目标方法,JdkDynamicAopProxy和CglibAopProxy采用了两种不同的方式:
对通知和目标方法的增强就是在invoke和intercept方法中,其中有段代码很重要:
//获得通知链,然后把它初始化到ReflectiveMethodInvocation中
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
关于通知的实现部分,我们放到后面再分析
这儿还需要多分析一点,在该方法中的类MethodMatcher,就是Pointcut(切入点)实现的一部分,MethodMatcher.matches检查该方法是否织入了Aop
接着看ReflectiveMethodInvocation.proceed (),类ReflectiveMethodInvocation的基类就是Joinpoint,在上面这张图中也很好的表现出了连接点的作用,继续看proceed的源码:
public Object proceed() throws Throwable {
// 如果通知链中的通知迭代调用完毕,这开始调用target函数,这个函数是通过反射机制完成的
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// 对通知进行动态匹配的判断
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// 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);
}
}
在这里我们看到对advice通知的调用入口了,我们继续看通知的实现部分
承上,想从源码角度去分析通知,有两个入口:
在分析Aop的通知之前,我们先复习一下适配器模式:适配器模式
适配器定义:将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配儿无法在一起工作的两个类能够在一起工作
Advice(通知)中就使用了适配器模式,因为Spring需要将每个Advice(通知)都封装成对应的拦截器类型,在ReflectiveMethodInvocation.proceed ()方法中会调用MethodInterceptor.invoke()方法,目的是当有多个Advice时,通过这种方式可以很好地回调,所以需要使用适配器模式对Advice进行转换
下面我们看看具体代码
Advice接口:Adaptee
public interface MethodBeforeAdvice extends BeforeAdvice {
void before(Method method, Object[] args, Object target) throws Throwable;
}
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 {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
}
从类图和源码可知MethodInterceptor对Advice进行了封装了,再看它的invoke()方法,就已经和前面在ReflectiveMethodInvocation.proceed ()分析中联系起来了,可得ReflectiveMethodInvocation.proceed ()->MethodInterceptor.invoke()->ReflectiveMethodInvocation.proceed ()……循环调用,直到全部通知执行完毕,其他Advice的实现原理类似
Adapter接口:Target
public interface AdvisorAdapter {
boolean supportsAdvice(Advice advice);
MethodInterceptor getInterceptor(Advisor advisor);
}
MethodBeforeAdviceAdapter类……:Adapter
从类层次关系可以看出,有三种通知适配器,以类MethodBeforeAdviceAdapter为例:
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof MethodBeforeAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
}
getInterceptor()方法返回的是MethodInterceptor(Adaptee)
DefaultAdvisorAdapterRegistry类:Client
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);
/** * Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters. */
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
@Override
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);
}
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
@Override
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
}