`

Spring参考手册 - AOP

 
阅读更多

概述

         Spring 2.0引入了一个简单而强大的机制,使用基于模式和@AspectJ注记样式实现自定义方面。Spring当前仅支持方法执行连接点而不支持字段拦截。Spring AOP框架的目标并不是实现完整的AOP实现,主要目的是帮助IOC容器解决一些企业应用的常见问题。Spring AOP框架通常需要和Spring IOC容器一起使用,方面使用通常的Bean定义语法。如果需要一个全面的AOP解决方案,AspectJ是更好的选择。
        Spring AOP框架是基于代理的,Spring缺省使用JDK的动态代理,JDK代理可以代理任何接口。而CGLIB代理主要用来代理类,如果一个Bean没有实现一个接口,Spring将使用CGLIB进行代理。

基本概念

        Aspect……横切多个对象的关注点。事务管理是J2EE应用的一个横切关注点的极好事例。
        Join Point……程序执行中的一个点,例如一个方法的执行或者异常处理,Spring中连接点总是指方法执行。
        Advice……方面在一个特定的连接点执行的动作,许多AOP框架,包括Spring都将advice模型为一个拦截器,基于一个连接点维持一个拦截器堆栈。
        Pointcut……用来匹配连接点的语法。Advice和一个Pointcut关联,并且运行在Pointcut匹配的连接点处(比如具有指定名称的方法)。Spring使用AspectJ的Pointcut语法。
        Introduction……针对某个类型声明额外的方法和字段,Spring AOP允许针对任何代理的对象引入新的接口。比如可以使用introduction让一个Bean实例实现IsModified接口。
        Target Object……被方面拦截的对象,Spring AOP使用运行时代理实现方面拦截机制,因此这些对象都是代理对象。
        Aop Proxy……AOP框架为了实现方面规约而创建的代理对象。Spring框架中,AOP代理是一个JDK动态代理或者CGLIB代理。
        Weave……将方面和其他对象类型进行关联创建Advice的方式,织入可以在编译时,加载时或运行时进行,Spring AOP使用运行时织入的方式。


Advice类型

        Before Advice……连接点之前执行,除非抛出异常将无法阻止执行连接点。
        After Return Advice……在连接点正常返回后执行。
        After throwing advice……连接点抛出异常后执行。
        After (finally) advice……不管连接点正常退出还是抛出异常都会执行。
        Around advice……在连接点之前和之后执行,可以在方法执行前后添加自定义逻辑,可以终止连接点的继续执行,返回值或抛出异常。


@AspectJ支持

启用AspectJ

        启用@AspectJ方面时,如果Spring检测到一个实例需要被一个或多个代理拦截,Spring将自动为这个实例生成一个代理,拦截方法执行,启用AspectJ需要添加如下配置:

xml 代码
  1. <aop:aspectj-autoproxy/>  


声明方面

        AspectJ对方面的支持是使用Annotation实现的,Spring将自动检测使用过@Aspect注记的Bean实例,配置AOP代理。AspectJ的方面就是一个使用了@Aspect注记的类,和普通类一样,可以包含方法,字段,另外也可以包含pointcut,advice,introduction等。


声明Pointcut

        Pointcut用来决定哪些方法需要应用方面,其声明包括两部分,一部分是返回值为void的方法签名,一部分是@Pointcut注记,@Pointcut注记的语法可以参见AspectJ参考指南。下面的示例定义了名称为anyOldTransfer的Pointcut,匹配任何方法名称为transfer:

java 代码
  1. @Pointcut("execution(* transfer(..))")// the pointcut expression   
  2. private void anyOldTransfer() {}// the pointcut signature  

Spring的Pointcut支持如下形式的限定方式:
       Within…..限制在指定的类型范围。 
       This……限制匹配的连接点所在的Bean实例的Spring AOP代理是指定的类型。
       Target……限制匹配的连接点所在的Bean实例是指定的类型。
       Args……限制匹配的连接点的参数是指定类型的实例。
       @target……限制连接点所在的类有一个指定类型的注记。
       @args……限制传递给连接点的参数的运行期类型有指定类型的注记。
       @within……限制连接点在有特定注记的类型范围。
       @annotation……限制连接点所在的Bean实例的Spring AOP代理有指定的注记。

       Pointcut表达式可以使用&&,||,!进行组合,也可以使用名称引用pointcut表达式,使用名称引用时,适用通常的java可见性规则,下面是几个示例:

java 代码
  1. @Pointcut("execution(public * *(..))")   
  2. private void anyPublicOperation() {}   
  3. @Pointcut("within(com.xyz.someapp.trading..*")   
  4. private void inTrading() {}   
  5. @Pointcut("anyPublicOperation() && inTrading()")   
  6. private void tradingOperation() {}   
声明Advice

       Advice和一个Pointcut表达式关联,运行在Pointcut表达式匹配的方法执行前后。

       针对几种不同类型的Advice,使用不同的注记来声明,比如使用@Before标记声明before advice。

       任何Advice方法可以声明一个org.aspectj.lang.JoinPoint 类型的参数,从而获取拦截方法的信息。

       可以在声明Advice时,将拦截方法的参数传递进来,下面的示例想拦截第一个参数为Account的方法,而且可以在advice方法内访问account对象。

java 代码
  1. @Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() &&" +   
  2. "args(account,..)")   
  3. public void validateAccount(Account account) {   
  4. // ...   
  5. }  

       代理对象,目标对象和注记也可以相同的方式访问,下面的示例拦截使用@Auditable
的方法,而且可以在advice方法内访问auditable对象。

java 代码
  1. @Before("com.xyz.lib.Pointcuts.anyPublicMethod() && " +   
  2. "@annotation(auditable)")   
  3. public void audit(Auditable auditable) {   
  4. AuditCode code = auditable.value();   
  5. // ...   
  6. }  


Introduction

       Introduction使用@DeclareParents注记声明,这个注记用来声明匹配pointcut的类将实现一个新的接口。下面的示例声明所有的服务接口将实现UsageTracked接口:

java 代码
  1. @Aspect  
  2. public class UsageTracking {   
  3. @DeclareParents(value="com.xzy.myapp.service.*+",   
  4. defaultImpl=DefaultUsageTracked.class)   
  5. public static UsageTracked mixin;   
  6. @Before("com.xyz.myapp.SystemArchitecture.businessService() &&" +   
  7. "this(usageTracked)")   
  8. public void recordUsage(UsageTracked usageTracked) {   
  9. usageTracked.incrementUseCount();   
  10. }   
  11. }   
Aspect实例模型

       缺省情况应用上下文中每个方面只有一个单独的实例,Spring支持perthis和pertarget模型。


基于模式的AOP

       如果不能使用JDK5,可以使用基于XML格式的配置,Spring通过使用aop标记提供对方面定义的支持。在Spring配置中,所有的方面和advisor元素都必须放在一个元素内。

       在基于模式的AOP中,Spring仅支持单例模型。要使用AOP标记,必须在配置文件中引入相应的XSD文件如下:

xml 代码
  1. xsi:schemaLocation=" http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsd"  
声明方面

       使用模式支持,一个方面只是Spring应用上下文中的一个Bean实例,状态和行为由这个Bean实例捕获,切入点和advice信息用XML描述。示例如下:

xml 代码
  1. <aop:config>  
  2. <aop:aspect  
  3. ...   
  4. aop:aspect>  
  5. aop:config>  
  6. <bean id="   
  7. ...   
  8. bean>  
声明Pointcut

       Pointcut可以直接声明在方面内部,也可以直接声明在元素内,可以供多个方面使用。

xml 代码
  1. <aop:config>  
  2. <aop:pointcut id="businessService"  
  3. Aspect Oriented Programming with Spring   
  4. Spring Framework (2.0.2) 118   
  5. expression="execution(* com.xyz.myapp.service.*.*(..))"/>  
  6. aop:config>  


声明advice

       下面的示例声明一个before类型的advice

xml 代码
  1. <aop:aspect id="beforeExample" ref="aBean">  
  2. <aop:before  
  3. pointcut-ref="dataAccessOperation"  
  4. method="doAccessCheck"/>  
  5. ...   
  6. aop:aspect>  
声明introduction

       下面的示例声明一个introduction

xml 代码
  1. <aop:aspect id="usageTrackerAspect" ref="usageTracking">  
  2. <aop:declare-parents  
  3. types-matching="com.xzy.myapp.service.*+",   
  4. implement-interface="UsageTracked"  
  5. default-impl="com.xyz.myapp.service.tracking.DefaultUsageTracked"/>  
  6. <aop:before  
  7. pointcut="com.xyz.myapp.SystemArchitecture.businessService()   
  8. and this(usageTracked)"   
  9. method="recordUsage"/>  
  10. aop:aspect>  
Advisor

       Advisor是Spring特有的概念,其实就是Pointcut和Advice的容器。


@AspectJ/XML

      基于Schema的AOP定义比较清晰明了,而且很容易通过配置文件修改,也有两个缺点:
            Schema方式中关于方面的信息由分布在XML文件和Bean实例中,而@Aspectj方式,所有关于方面的信息都集中在一个模块的所有Bean实例中。
            Schema方式仅支持方面的单例模型,@Aspectj方式支持组合命名的Pointcut。


代理机制

      Spring AOP缺省使用JDK的动态代理机制,只能针对接口代理,如果需要针对类代理,可以使用CGLIB代理,要在AOP中强制使用CGLIB代理,可以设置proxy-target-class属性如下:

xml 代码
  1. <aop:config proxy-target-class="true">  
  2. <!-- other beans defined here... -->  
  3. aop:config>  

      使用CGLIB代理的一个问题是final方法不能被代理,因为final方法不能重写。
      Spring框架使用代理机制,会导致调用自身方法的方法不能被代理,下面这种情况下,foo方法就不能被代理。


 

分享到:
评论

相关推荐

    官方原版完整包 spring-framework-5.3.6.RELEASE-dist.zip

    文档通常包括用户指南、参考手册、API文档等,帮助开发者理解和使用框架的各种特性。这些文档详细解释了如何配置和使用Spring,包括容器配置、bean定义、数据访问、事务管理、Web开发等方面的指导,是学习和解决问题...

    官方原版完整包 spring-framework-5.3.1.RELEASE.zip

    这些文档包括用户指南、参考手册、API文档以及开发者指南,是学习和使用Spring框架的重要参考资料。开发者可以通过阅读这些文档深入理解Spring框架的工作原理,以及如何有效地使用其各种特性。 **spring-5.3.1-...

    spring-framework-5.0.0.RELEASE-dist.zip

    这个文件夹通常包含Spring框架的官方文档,包括API参考、用户指南、开发者手册等。这些文档对于理解Spring框架的架构、工作原理以及如何使用其各种功能至关重要。开发者可以通过阅读这些文档快速上手,并深入学习...

    spring-framework-reference-4.3.19.pdf

    - **AOP与Instrumentation**:提供面向切面编程支持以及类加载时的增强。 - **消息传递**:支持异步消息处理和事件驱动架构。 - **数据访问/集成**:提供对数据库和其他持久化技术的支持。 - **Web**:包括Web ...

    spring-5.3.9-dist.zip(spring-framework-5.3.9)

    文档通常包括用户指南、参考手册、API文档以及各种教程。在学习和使用Spring时,这些文档将帮助我们理解如何配置、编程以及管理Spring应用程序。 `libs`文件夹包含了必要的库文件,即jar包,这些是运行Spring应用所...

    官方完整包 spring-framework-5.3.7.RELEASE-dist.zip

    - **spring-5.3.7-docs.zip**:包含完整的官方文档,包括用户指南、参考手册和API文档,是学习和开发过程中的重要参考资料。 - **spring-5.3.7-schema.zip**:可能包含Spring配置文件的XML模式定义,有助于验证...

    spring-framework-5.0.2.RELEASE官方完整包加官方文档

    `spring-framework-5.0.2.RELEASE-docs.zip` 文件包含了Spring官方的详细文档,这些文档通常包括用户指南、参考手册、API文档等。用户指南会引导开发者如何起步,包括如何创建项目、配置环境、编写代码等;参考手册...

    官方完整包 spring-framework-5.3.8.RELEASE-dist.zip

    - **spring-5.3.8-docs.zip**:这个文件包含了Spring Framework 5.3.8的官方文档,包括用户指南、参考手册和API文档。这些文档是开发者学习和解决问题的重要资源,详细阐述了框架的各种特性和用法。 - **spring-...

    官方原版spring-framework-4.3.18.RELEASE.zip

    "spring-framework-4.3.18.RELEASE-docs.zip"文件则包含了Spring Framework的完整文档,包括用户指南、参考手册和API文档。这些文档是开发者学习和理解Spring功能、最佳实践以及如何解决常见问题的重要资源。通过...

    spring-framework-5.0.8.RELEASE官方完整包加官方文档

    文档通常包括用户指南、参考手册、API文档等,它们详细地解释了框架的各个模块、类库、接口和方法的使用方法,有助于开发者快速理解和掌握Spring的核心概念和实践技巧。 在Spring 5.0.8.RELEASE版本中,有以下几个...

    spring-aop-5.3.4.jar中文-英文对照文档.zip

    中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-...

    spring-aop-5.3.12.jar中文-英文对照文档.zip

    中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-...

    spring-aop-5.3.7.jar中文-英文对照文档.zip

    中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-...

    spring-aop-5.3.10.jar中文-英文对照文档.zip

    中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-...

    spring-aop-5.3.15.jar中文-英文对照文档.zip

    中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-...

    spring-aop-5.3.9.jar中文-英文对照文档.zip

    中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-...

    spring-aop-5.3.6.jar中文-英文对照文档.zip

    中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-...

    spring-framework-4.3.18.RELEASE官方完整包加官方文档

    6. **文档**:`spring-framework-4.3.18.RELEASE-docs.zip`包含了官方的完整文档,包括用户指南、参考手册、API文档等。这些文档详细介绍了Spring的各个组件、配置选项和最佳实践,是学习和解决问题的重要资源。 7....

    spring-context-4.1.6.RELEASE.jar中文-英文对照文档.zip

    中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-...

    spring-aop-5.1.7.RELEASE.jar中文-英文对照文档.zip

    中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-...

Global site tag (gtag.js) - Google Analytics