`

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

分享到:
评论

相关推荐

    Java spring AOP源码

    ### Java Spring AOP源码分析 #### 概述 在探讨Spring AOP源码之前,我们首先需要了解Spring AOP的基本概念以及它的工作原理。面向切面编程(Aspect-Oriented Programming, AOP)是一种编程范式,它通过将横切关注...

    五、Spring源码分析——Spring Aop

    `org.aopalliance.intercept.MethodInterceptor`接口定义了拦截器的行为,而`org.springframework.aop.MethodBeforeAdvice`等类则是具体的通知实现。`org.springframework.aop.aspectj.AspectJExpressionPointcut`类...

    spring-aop源码

    《深入剖析Spring AOP源码》 Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对现有代码进行功能增强的技术。本文将深入探讨Spring ...

    Spring Aop 引用新功能 源码

    通过源码分析,我们可以深入了解Spring AOP的工作原理,以及如何通过`IntroductionInterceptor`或`@AspectJ`来实现引入。理解并熟练运用这一特性,将有助于我们在实际开发中更好地进行代码解耦和模块化,提升软件的...

    Java进阶之SpringAOP源码深度剖析共17页.pd

    通过对Spring AOP源码的深入分析,我们可以了解到其内部是如何通过代理模式和反射技术实现对方法调用的拦截,以及如何解析和执行切点表达式,理解通知的执行流程等。这些深入理解对于优化性能、排查问题以及自定义...

    spring-aop-ProxyFactoryBean 源码分析

    在Spring AOP中,拦截器是`MethodInterceptor`接口的实现,而顾问是`Advisor`接口的实现,包括`PointcutAdvisor`(包含切点和拦截器)和`IntroductionAdvisor`(引入新的接口)。`ProxyFactoryBean`可以通过`...

    spring源码分析(1-10)

    7. **Spring AOP中的拦截器调用实现**:Spring AOP使用Advisor和Interceptor实现拦截器链,处理方法调用前后的逻辑。MethodBeforeAdvice、AfterReturningAdvice等接口定义了拦截器的行为。 8. **Spring 驱动...

    Spring AOP框架实现的结构分析

    许多 AOP 框架都以拦截器的形式来表现增强--所谓拦截器是这样的一个对象:当连接点被调用时,它会收到一个回调消息。基本的增强有前增强、后增强、环绕增强等。引介是为一个现有的 Java 类或接口添加方法或字段。...

    Spring aop 性能监控器

    本篇文章将深入探讨如何使用Spring AOP实现性能监控器,并通过源码分析来理解其工作原理。 首先,我们要了解AOP的核心概念——切面(Aspect)、通知(Advice)、连接点(Join Point)、切入点(Pointcut)和织入...

    spring-aop.rar_aop1270_spring_spring aop

    本文将围绕Spring AOP的源码分析,探讨其核心概念、工作原理以及在实际开发中的应用。 一、AOP核心概念 1. 切面(Aspect):切面是关注点的模块化,通常包含一组通知(advises)和一个切入点(pointcut)定义。 2...

    反射实现 AOP 动态代理模式(Spring AOP 的实现 原理) - Java 例子 -

    Spring框架是Java中实现AOP的一个流行工具,它通过动态代理机制实现了这一功能。本文将深入探讨Spring AOP的实现原理,以及如何使用反射来实现动态代理模式。 首先,我们需要了解AOP的基本概念。AOP的核心思想是切...

    spring-aop.pdf 源码电子书

    标题和描述中提到的是关于Spring AOP源码的电子书。Spring AOP(Aspect-Oriented Programming)是Spring框架的一个重要组成部分,它支持面向切面编程的实践,是为了解决面向对象编程中的横切关注点问题而设计的。在...

    Spring AOP

    Spring AOP的源码分析主要涉及以下几个部分: - **ProxyFactoryBean**:它是Spring AOP代理的工厂类,负责创建代理对象。 - **Advised**:接口,代表可以配置通知的对象,如代理对象。 - **AopProxy**:接口,定义了...

    spring源码分析

    一、IOC 容器 二、IoC 容器在 Web 容器中的启动 三、Spring JDBC 四、Spring MVC 五、Spring AOP 获取 ...七、Spring AOP 中对拦截器调用的实现 八、Spring 驱动 Hibernate 的实现 九、Spring Acegi 框架鉴权的实现

    Spring Security 3 源码分析文档

    通过阅读《Spring Security3.pdf》和《spring security3 源码分析.pdf》这两份文档,你可以对Spring Security 3的内部工作机制有更深入的理解,从而更好地在项目中运用这个强大的安全框架。同时,这也会帮助你在面临...

    Spring AOP 用法笔记

    2. **通知(Advice)**:通知是在特定的连接点上执行的代码,也就是我们所说的拦截器。Spring支持五种类型的通知:前置通知(Before)、后置通知(After)、返回后通知(After Returning)、异常后通知(After ...

    四、Spring源码分析——动态代理

    - 接着,Spring创建一个代理对象,该对象持有目标对象的引用,并关联一个`Advised`对象,该对象包含了关于代理的所有信息,如拦截器链。 - 当调用代理对象的方法时,实际上会触发`InvocationHandler`的`invoke`...

    spring源码分析流程全面解析

    在深入探讨Spring源码分析流程之前,我们先要理解Spring框架的基本概念。Spring是一个轻量级的Java企业级应用框架,它提供了丰富的功能,包括依赖注入(DI)、面向切面编程(AOP)、数据访问、事务管理等。Spring的...

    spring源码报错缺失的两个包

    在Spring框架的开发和学习过程中,源码分析是提升理解深度的重要途径。然而,有时候我们可能会遇到"spring源码报错缺失的两个包"这样的问题,这意味着我们的开发环境缺少了某些必要的依赖,导致Spring框架无法正常...

    Spring源码学习文档,绝对值得好好研究~~

    Spring源代码解析(七):Spring AOP中对拦截器调用的实现.doc Spring源代码解析(八):Spring驱动Hibernate的实现.doc Spring源代码解析(九):Spring Acegi框架鉴权的实现.doc Spring源代码解析(十):Spring ...

Global site tag (gtag.js) - Google Analytics