spring AOP源码分析之拦截器

我们都知道在spring AOP中产生代理对象的方式有jdk和cglib的方式生成,无论那种方式,AOP的拦截的处理都是通过ReflectiveMethodInvocation中的proceed方法
其方法的源码如下:
  public Object proceed()
        throws Throwable
    {
        //如果拦截器迭代完毕,这里开始调用目标方法
        if(currentInterceptorIndex == interceptorsAndDynamicMethodMatchers.size() - 1)
            return invokeJoinpoint();
        //从拦截器的集合中获取拦截器
        Object interceptorOrInterceptionAdvice = interceptorsAndDynamicMethodMatchers.get(++currentInterceptorIndex);
        //判断如果是该类型的
        if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher)
        {
            InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
            //那么对方法进行匹配
            if(dm.methodMatcher.matches(method, targetClass, arguments))
                return dm.interceptor.invoke(this);
            else
                //否则进行递归调用
                return proceed();
        } else
        {
            //如果是interceptor,直接调用这个interceptor对应的方法  
            return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
        }
    }

那么这个拦截器链的集合是如何产生的呢?
由于AopFactoryBean是继承AdvisedSupport我们在看下AdvisedSupport中的getInterceptorsAndDynamicInterceptionAdvice方法
//获取拦截器
public List getInterceptorsAndDynamicInterceptionAdvice(Method method, Class targetClass)
    {
        MethodCacheKey cacheKey = new MethodCacheKey(method);
        List cached = (List)methodCache.get(cacheKey);
        if(cached == null)
        {
            //拦截器链工厂获取
            cached = advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);
            methodCache.put(cacheKey, cached);
        }
        return cached;
    }
获取拦截器链的工作是由配置好的advisorChainFactory来完成的,在这里advisorChainFactory被配置成一个DefaultAdvisorChainFactory对象,在DefaultAdvisorChainFactory中getInterceptorsAndDynamicInterceptionAdvice方法来获取,源码如下:
public List getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class targetClass)
    {
       //定义拦截器链数组的大小
        List interceptorList = new ArrayList(config.getAdvisors().length);
        boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);
        //这里采用的简单工厂的方式产生AdvisorAdapterRegistry对象,而该接口的实现类为DefaultAdvisorAdapterRegistry
        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
        org.springframework.aop.Advisor aadvisor[];
        int j = (aadvisor = config.getAdvisors()).length;
        for(int i = 0; i < j; i++)
        {
            org.springframework.aop.Advisor advisor = aadvisor[i];
            if(advisor instanceof PointcutAdvisor)
            {
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor)advisor;
                if(config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass))
                {
                    org.aopalliance.intercept.MethodInterceptor interceptors[] = registry.getInterceptors(advisor);
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    if(MethodMatchers.matches(mm, method, targetClass, hasIntroductions))
                        if(mm.isRuntime())
                        {
                            org.aopalliance.intercept.MethodInterceptor amethodinterceptor[];
                            int l = (amethodinterceptor = interceptors).length;
                            for(int k = 0; k < l; k++)
                            {
                                org.aopalliance.intercept.MethodInterceptor interceptor = amethodinterceptor[k];
                                interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                            }

                        } else
                        {
                            interceptorList.addAll((Collection)Arrays.asList(interceptors));
                        }
                }
            } else
            if(advisor instanceof IntroductionAdvisor)
            {
                IntroductionAdvisor ia = (IntroductionAdvisor)advisor;
                if(config.isPreFiltered() || ia.getClassFilter().matches(targetClass))
                {
                    org.aopalliance.intercept.Interceptor interceptors[] = registry.getInterceptors(advisor);
                    interceptorList.addAll((Collection)Arrays.asList(interceptors));
                }
            } else
            {
                org.aopalliance.intercept.Interceptor interceptors[] = registry.getInterceptors(advisor);
                interceptorList.addAll((Collection)Arrays.asList(interceptors));
            }
        }

        return interceptorList;
    }

从上述源码可知:DefaultAdvisorChainFactory会通过一个AdivesorAdatperRegistry来实现拦截器的注册,而这个AdivesorAdatperRegistry对象的advice通知的知入功能起了很大的作用。


Advice通知的实现
我们在看下DefaultAdvisorAdapterRegistry中的getInterceptors方法

//通知适配器集合
private final List adapters = new ArrayList(3);

public MethodInterceptor[] getInterceptors(Advisor advisor)
        throws UnknownAdviceTypeException
    {
        List interceptors = new ArrayList(3);
        //从通知器中获取通知
        Advice advice = advisor.getAdvice();
        if(advice instanceof MethodInterceptor)
            interceptors.add((MethodInterceptor)advice);
        
        for(Iterator iterator = adapters.iterator(); iterator.hasNext();)
        {
            //循环所有的适配器通知
            AdvisorAdapter adapter = (AdvisorAdapter)iterator.next();
            if(adapter.supportsAdvice(advice))
                interceptors.add(adapter.getInterceptor(advisor));
        }

        if(interceptors.isEmpty())
            throw new UnknownAdviceTypeException(advisor.getAdvice());
        else
            return (MethodInterceptor[])interceptors.toArray(new MethodInterceptor[interceptors.size()]);
    }

关于通知适配器集合的初始化,通过构造函数注册
//注册advice适配器
public DefaultAdvisorAdapterRegistry()
{
        registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
        registerAdvisorAdapter(new AfterReturningAdviceAdapter());
        registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
//注册方法
public void registerAdvisorAdapter(AdvisorAdapter adapter)
{
        adapters.add(adapter);
}

我们在看一个advice适配器具体实现例如MethodBeforeAdviceAdapter源码
class MethodBeforeAdviceAdapter
    implements AdvisorAdapter, Serializable
{

    MethodBeforeAdviceAdapter()
    {
    }

    public boolean supportsAdvice(Advice advice)
    {
        return advice instanceof MethodBeforeAdvice;
    }

    public MethodInterceptor getInterceptor(Advisor advisor)
    {
        //从中获取advice
        MethodBeforeAdvice advice = (MethodBeforeAdvice)advisor.getAdvice();
        //返回拦截器
        return new MethodBeforeAdviceInterceptor(advice);
    }
}

猜你喜欢

转载自liuwuhen.iteye.com/blog/1638723
今日推荐