Spring技术内幕:Spring AOP的实现原理(四)

4、目标方法的调用 如果没有拦截器会对目标对象方法直接调用。对于JDKDynamicAopProxy代理对象是通过AopUtils使用反射机制实现的。在这个调用方法中首先得到调用方法的反射对象,然后使用invoke启动对方法反射对象的调用。源码如下:

/*** Invoke the given target via reflection, as part of an AOP method invocation.* @param target the target object* @param method the method to invoke* @param args the arguments for the method* @return the invocation result, if any* @throws Throwable if thrown by the target method* @throws org.springframework.aop.AopInvocationException in case of a reflection error*/public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)throws Throwable {// Use reflection to invoke the method.try {ReflectionUtils.makeAccessible(method);return method.invoke(target, args);}catch (InvocationTargetException ex) {ex.getTargetException();}catch (IllegalArgumentException ex) {throw new AopInvocationException(“AOP configuration seems to be invalid: tried calling method [” +method + “] on target [” + target + “]”, ex);}catch (IllegalAccessException ex) {throw new AopInvocationException(“Could not access method [” + method + “]”, ex);}}}

5、AOP拦截器的调用 下面进入AOP的核心部分,,Aop是怎样完成对目标的增强的。这些都封装在Aop拦截器链中,由一个具体的拦截器完成。 无论是使用JDKDynamicAopProxy还是使用CglibAopProxy创建代理对象最终对AOP拦截链的调用都是在ReflectiveMethodInvocation中通过proceed方法实现的。在proceed方法中逐个运行拦截器的拦截方法。在运行拦截器的拦截方法之前需要对代理方法完成一个匹配,通过这个匹配判断来决定拦截器是否满足切面增强的要求。具体代码如下:

public Object proceed() throws Throwable {(this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() – 1) {return invokeJoinpoint();}// 这里沿着定义好的interceptorOrInterceptionAdvice链进行处理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 {proceed();}}else {((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}}

这时我们会有疑问,这些advisor是怎样从配置文件中获得并配置到proxy的拦截器链中,我们使用的advisor通知时怎样起作用的,让我们带着这些问题继续往下看。 6、配置通知器 在整个AopProxy代理对象拦截回调过程中,先回到ReflectionMethodInvocation类的proceed方法,在这个方法里,可以看到得到了配置的interceptorOrInterceptionAdvice,如下所示:

Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);

interceptorOrInterceptionAdvice是获得的拦截器,他通过拦截器机制对目标对象进行增强。这个拦截器来自interceptorsAndDynamicMethodMatchers。具体来说,他是interceptorsAndDynamicMathers持有的List中的一个元素。关于如何配置拦截器的问题就转化为了List中的拦截器元素是从哪里来的,在哪里配置的问题。接着对invoke调用进行回放,回到JDKDynamicAopProxy中的invoke方法中,可以看到这个List中的interceptors是从哪个调用中获取的。对于CglibAopProxy,也有类似过程,只不过这个过程是在DynamicAdvisedInterceptor的intercept回调中实现的,如下所示:

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method,targetClass);

从上面的代码可以看出,获取intercptors的操作是由advised对象完成的,这个advised是一个AdvisedSupport对象,从AdvisedSupport类中可以看到getInterceptorsAndDynamicInterceptionAdvice的实现。在这个方法中取得了拦截器链,再取得拦截器链的时候,为了提高拦截器链的效率,还为这个拦截器链这是了缓存。

/*** Determine a list of {@link org.aopalliance.intercept.MethodInterceptor} objects* for the given method, based on this configuration.* @param method the proxied method* @param targetClass the target class* @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)*/public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class targetClass) {// 这里使用cache,利用cache去获取已有的inteceptor链,但是第一次还是需要自己动手生成的。这个inteceptor链的生成// 是由advisorChainFactory完成的,在这里使用的是DefaultAdvisorChainFactoryMethodCacheKey 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;}用开怀的笑容去迎接每一个黎明,

Spring技术内幕:Spring AOP的实现原理(四)

相关文章:

你感兴趣的文章:

标签云: