10°

SpringFramework之DefaultAdvisorChainFactory

    Spring版本是5.0.4.release. 

    JdkDynamicAopProxy中使用到了拦截器链,如下List-1,advised是ProxyFactory,而方法getInterceptorsAndDynamicInterceptionAdvice则是在其父类AdvisedSupport中。

    List-1

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		...
		// Get the interception chain for this method.
		List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
		...
}

    如下List-2,advisorChainFactory是DefaultAdvisorChainFactory

    List-2

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable 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;
}

     getInterceptorsAndDynamicInterceptionAdvice的方法实现如下List-3所示,会将Advisor转换为Interceptor,List-3中的registry是DefaultAdvisorAdapterRegistry。

    List-3

public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {
@Override
public List&lt;Object&gt; getInterceptorsAndDynamicInterceptionAdvice(
		Advised config, Method method, @Nullable Class&lt;?&gt; targetClass) {
		...
		Interceptor[] interceptors = registry.getInterceptors(advisor);
		...		

	return interceptorList;
}
...</code></pre> 

    如下List-4所示,构造方法中注册了Adapter,而后getInterceptors方法中会使用模板模式将advisor中的advice转换为MethodInterceptor。

    List-4

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
private final List&lt;AdvisorAdapter&gt; adapters = new ArrayList&lt;&gt;(3);

public DefaultAdvisorAdapterRegistry() {
	registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
	registerAdvisorAdapter(new AfterReturningAdviceAdapter());
	registerAdvisorAdapter(new ThrowsAdviceAdapter());
}

@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
	List&lt;MethodInterceptor&gt; interceptors = new ArrayList&lt;&gt;(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[0]);
}
...</code></pre> 

    来看个例子,如下List-5所示,MethodBeforeAdviceAdapter的supportsAdvice方法中判断是否是MethodBeforeAdvice;getInterceptor方法中将advice封装到MethodBeforeAdviceInterceptor中。

    List-5

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

}

    MethodBeforeAdviceInterceptor的代码如下,比较简单,主要是invoke方法,会先调用MethodBeforeAdvice的before方法,之后才会执行MethodInvocation的invoke方法。

    List-6

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

}

    整体来看DefaultAdvisorChainFactory会将我们的advice转换为MethodInerceptor,而不同的Advice实现,对应的MethodInterceptor实现也不一样,进而实现Before、After的拦截实现。

Reference

  1. https://github.com/spring-projects/spring-framework/tree/5.0.x

本文由【克虏伯】发布于开源中国,原文链接:https://my.oschina.net/u/2518341/blog/3073829

全部评论: 0

    我有话说: