spring aop(七)--拦截链

无论基于JDK还是CGLib,在触发方法调用时都会先通过List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);这句代码去获取拦截链.其中advised是AdvisedSupport类型.下面看看这个方法:

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;
}
MethodCacheKey的equals方法就是根据传进来的方法是否判断为同一个对象.private transient Map<MethodCacheKey, List<Object>> methodCache;很明显是一个map,作用是实现缓存.AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();可以知道是通过工厂去获取,DefaultAdvisorChainFactory是默认实现,当然可以注入自定义实现.再看org.springframework.aop.framework.DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
		Advised config, Method method, Class<?> targetClass) {
	//使用一个List来装要获取的拦截器,最将返回这个拦截链
	List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
	Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
	//判断配置config是否符合要求
	boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
	//通过单例方式实例一个DefaultAdvisorAdapterRegistry,
	AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
	//从配置获取所有的Advisor进行迭代
	for (Advisor advisor : config.getAdvisors()) {
		if (advisor instanceof PointcutAdvisor) {
			//如果是PointcutAdvisor类型
			PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
			if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
				//已预过滤过的或者这个切点适用于给定的接口或目标类
				//从registry获取MethodInterceptor拦截器
				MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
				MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
				if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
				//如果切点的MethodMatcher都匹配这个method
					if (mm.isRuntime()) {
						//如果是动态MethodMatcher,就会对每一个interceptor创建一个新的InterceptorAndDynamicMethodMatcher拦截器,并加入到返回List.
						for (MethodInterceptor interceptor : interceptors) {
							interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
						}
					}
					else {
						//不是动态的MethodMatcher,将所有的拦截器加入到返回List
						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;
}
再看看org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#getInterceptors
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()]);
}
从这个方法可以看出,interceptors来源于advisor和this.adapters,从声明private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);可以看出,在方法调用的过程中并没有传递AdvisorAdapter过来,在这类中提供方法
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
	this.adapters.add(adapter);
}
而这个方法被构造函数就有调用,外界也可能会调用,在spring aop(五)--ProxyFactory创建代理的实现,提到配置的Advisor链就是在initializeAdvisorChain()完成的,

Object advice;
if (this.singleton || this.beanFactory.isSingleton(name)) {
	//从容器得到advice
	advice = this.beanFactory.getBean(name);
}
else {
	// It's a prototype Advice or Advisor: replace with a prototype.
	// Avoid unnecessary creation of prototype bean just for advisor chain initialization.
	advice = new PrototypePlaceholderAdvisor(name);
}
//添加advice
addAdvisorOnChainCreation(advice, name);
再看看addAdvisorOnChainCreation
private void addAdvisorOnChainCreation(Object next, String name) {
	//将advice转为Advisor
	Advisor advisor = namedBeanToAdvisor(next);
	if (logger.isTraceEnabled()) {
		logger.trace("Adding advisor with name '" + name + "'");
	}
	//添加Advisor
	addAdvisor(advisor);
}
public void addAdvisor(Advisor advisor) {
	int pos = this.advisors.size();
	addAdvisor(pos, advisor);
}
最终添加到org.springframework.aop.framework.AdvisedSupport#advisors


再回来,上面提及org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#DefaultAdvisorAdapterRegistry添加了MethodBeforeAdviceAdapter,AfterReturningAdviceAdapter,ThrowsAdviceAdapter到private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);

public interface AdvisorAdapter {
	//适配器是否能理解此advice对象
	boolean supportsAdvice(Advice advice);
	//将advisor转为AOP Alliance MethodInterceptor,即对Advisor进行封装
	MethodInterceptor getInterceptor(Advisor advisor);
}
以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);
	}
}
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();
	}
}
从MethodBeforeAdviceInterceptor设计的invoke可以看出先触发了advice的before回调,然后再调用MethodInvocation的proceed.根据AOP的配置规则,ReflectiveMethodInvocation会触发拦截器的invoke方法,最终根据不同的advice类型,触发不同的advice的拦截器封装,比如这个org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor#invoke在调用方法前会先调用before方法,从而达到前置通知的效果.


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值