`

<aop:aspectj-autoproxy />的作用

 
阅读更多

 

作用:启用注节方式,创建AOP切面。 

 

通过配置织入@Aspectj切面

虽然可以通过编程的方式织入切面,但是一般情况下,我们还是使用spring的配置自动完成创建代理织入切面的工作。

 

 

通过aop命名空间的<aop:aspectj-autoproxy />声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。当然,spring

在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,但具体实现的细节已经被<aop:aspectj-autoproxy />隐藏起来了

<aop:aspectj-autoproxy />有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为<aop:aspectj-autoproxy  poxy-target-class="true"/>时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理。

@AspectJ语法基础

@AspectJ使用jdk5.0注解和正规则的AspectJ 5的切面表达式语言描述切面,由于spring只支持方法的连接点,所以spring仅支持部分aspectJ的切面语言,在这节时,我们将对AspectJ切点表达式语言进行必要的学习。

 

切点表达式函数

AspectJ 5的切点表达式由关键字和操作参数组成。如execution(*greeTo(..))的切点表达式,"execute"为关键字,而"*greeTo(..)"为操作参数。在这里,execution代表目标类执行某一方法,而"*greeTo(..)"是描述目标方法的匹配模式串,两者联合起来所表示的切点匹配目标类greeTo(..)方法的连接点。为了描述方便,我们将execution()称作函数,而将匹配串"*greeTo(..)"称作函数的入参。

 

================================================================

 

 

 

  Spring除了支持Schema方式配置AOP,还支持注解方式:使用@AspectJ风格的切面声明。

1  启用对@AspectJ的支持

       Spring默认不支持@AspectJ风格的切面声明,为了支持需要使用如下配置:

 

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

 

这样Spring就能发现@AspectJ风格的切面并且将切面应用到目标对象。

2  声明切面

       @AspectJ风格的声明切面非常简单,使用@Aspect注解进行声明:

 

java代码:
  1. @Aspect()  
  2. Public class Aspect{  
  3. ……  
  4. }  

 

       然后将该切面在配置文件中声明为Bean后,Spring就能自动识别并进行AOP方面的配置:

 

java代码:
  1. <bean id="aspect" class="……Aspect"/>  

 

       该切面就是一个POJO,可以在该切面中进行切入点及通知定义,接着往下看吧。

 

3  声明切入点

       @AspectJ风格的命名切入点使用org.aspectj.lang.annotation包下的@Pointcut+方法(方法必须是返回void类型)实现。

 

java代码:
  1. @Pointcut(value="切入点表达式", argNames = "参数名列表")  
  2. public void pointcutName(……) {}  
  3.    

       value:指定切入点表达式;

       argNames:指定命名切入点方法参数列表参数名字,可以有多个用“,”分隔,这些参数将传递给通知方法同名的参数,同时比如切入点表达式“args(param)”将匹配参数类型为命名切入点方法同名参数指定的参数类型。

       pointcutName:切入点名字,可以使用该名字进行引用该切入点表达式。

 

java代码:
  1. @Pointcut(value="execution(* cn.javass..*.sayAdvisorBefore(..)) && args(param)", argNames = "param")  
  2. public void beforePointcut(String param) {}  

 

定义了一个切入点,名字为“beforePointcut”,该切入点将匹配目标方法的第一个参数类型为通知方法实现中参数名为“param”的参数类型。

 

4  声明通知

       @AspectJ风格的声明通知也支持5种通知类型:

 

一、前置通知:使用org.aspectj.lang.annotation 包下的@Before注解声明;

 

java代码:
  1. @Before(value = "切入点表达式或命名切入点", argNames = "参数列表参数名")  

 

       value:指定切入点表达式或命名切入点;

       argNames:与Schema方式配置中的同义。

 

接下来示例一下吧:

1、定义接口和实现,在此我们就使用Schema风格时的定义;

2、定义切面:

 

java代码:
  1. package cn.javass.spring.chapter6.aop;  
  2. import org.aspectj.lang.annotation.Aspect;  
  3. @Aspect  
  4. public class HelloWorldAspect2 {  
  5.    
  6. }  

 

3、定义切入点:

 

java代码:
  1. @Pointcut(value="execution(* cn.javass..*.sayAdvisorBefore(..)) && args(param)", argNames = "param")  
  2. public void beforePointcut(String param) {}  

 

4、定义通知:

 

java代码:
  1. @Before(value = "beforePointcut(param)", argNames = "param")  
  2. public void beforeAdvice(String param) {  
  3.     System.out.println("===========before advice param:" + param);  
  4. }  

 

5、在chapter6/advice2.xml配置文件中进行如下配置:

 

java代码:
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans  xmlns="http://www.springframework.org/schema/beans"  
  3.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.         xmlns:aop="http://www.springframework.org/schema/aop"  
  5.         xsi:schemaLocation="  
  6.            http://www.springframework.org/schema/beans  
  7.            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  8.            http://www.springframework.org/schema/aop  
  9.            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">  
  10.             
  11.   <aop:aspectj-autoproxy/>  
  12.   <bean id="helloWorldService"  
  13.             class="cn.javass.spring.chapter6.service.impl.HelloWorldService"/>  
  14.    
  15.   <bean id="aspect"  
  16.              class="cn.javass.spring.chapter6.aop.HelloWorldAspect2"/>  
  17.    
  18. </beans>  
  19.    

 

6、测试代码cn.javass.spring.chapter6.AopTest:

 

java代码:
  1. @Test  
  2. public void testAnnotationBeforeAdvice() {  
  3.     System.out.println("======================================");  
  4.     ApplicationContext ctx = new ClassPathXmlApplicationContext("chapter6/advice2.xml");  
  5.     IHelloWorldService helloworldService = ctx.getBean("helloWorldService", IHelloWorldService.class);  
  6.     helloworldService.sayBefore("before");  
  7.     System.out.println("======================================");  
  8. }  

 

 

将输出:

 

 
 

==========================================

===========before advice param:before

============say before

==========================================

 

 

 

 

 

 

 

 

      

 

切面、切入点、通知全部使用注解完成:

       1)使用@Aspect将POJO声明为切面;

       2)使用@Pointcut进行命名切入点声明,同时指定目标方法第一个参数类型必须是java.lang.String,对于其他匹配的方法但参数类型不一致的将也是不匹配的,通过argNames = "param"指定了将把该匹配的目标方法参数传递给通知同名的参数上;

       3)使用@Before进行前置通知声明,其中value用于定义切入点表达式或引用命名切入点;

       4)配置文件需要使用<aop:aspectj-autoproxy/>来开启注解风格的@AspectJ支持;

       5)需要将切面注册为Bean,如“aspect”Bean;

       6)测试代码完全一样。

 

 

二、后置返回通知:使用org.aspectj.lang.annotation 包下的@AfterReturning注解声明;

 

java代码:
  1. @AfterReturning(  
  2. value="切入点表达式或命名切入点",  
  3. pointcut="切入点表达式或命名切入点",  
  4. argNames="参数列表参数名",  
  5. returning="返回值对应参数名")  

       value:指定切入点表达式或命名切入点;

       pointcut:同样是指定切入点表达式或命名切入点,如果指定了将覆盖value属性指定的,pointcut具有高优先级;

       argNames:与Schema方式配置中的同义;

       returning:与Schema方式配置中的同义。

 

 

java代码:
  1. @AfterReturning(  
  2.     value="execution(* cn.javass..*.sayBefore(..))",  
  3.     pointcut="execution(* cn.javass..*.sayAfterReturning(..))",  
  4.     argNames="retVal", returning="retVal")  
  5. public void afterReturningAdvice(Object retVal) {  
  6.     System.out.println("===========after returning advice retVal:" + retVal);  
  7. }  

 

其中测试代码与Schema方式几乎一样,在此就不演示了,如果需要请参考AopTest.java中的testAnnotationAfterReturningAdvice测试方法。

 

三、后置异常通知:使用org.aspectj.lang.annotation 包下的@AfterThrowing注解声明;

 

java代码:
  1. @AfterThrowing (  
  2. value="切入点表达式或命名切入点",  
  3. pointcut="切入点表达式或命名切入点",  
  4. argNames="参数列表参数名",  
  5. throwing="异常对应参数名")  
  6.    

 

       value:指定切入点表达式或命名切入点;

       pointcut:同样是指定切入点表达式或命名切入点,如果指定了将覆盖value属性指定的,pointcut具有高优先级;

       argNames:与Schema方式配置中的同义;

       throwing:与Schema方式配置中的同义。

 

 

java代码:
  1. @AfterThrowing(  
  2.     value="execution(* cn.javass..*.sayAfterThrowing(..))",  
  3.     argNames="exception", throwing="exception")  
  4. public void afterThrowingAdvice(Exception exception) {  
  5.     System.out.println("===========after throwing advice exception:" + exception);  
  6. }  

 

其中测试代码与Schema方式几乎一样,在此就不演示了,如果需要请参考AopTest.java中的testAnnotationAfterThrowingAdvice测试方法。

 

四、后置最终通知:使用org.aspectj.lang.annotation 包下的@After注解声明;

 

java代码:
  1. @After (  
  2. value="切入点表达式或命名切入点",  
  3. argNames="参数列表参数名")  

       value:指定切入点表达式或命名切入点;

       argNames:与Schema方式配置中的同义;

 

 

java代码:
  1. @After(value="execution(* cn.javass..*.sayAfterFinally(..))")  
  2. public void afterFinallyAdvice() {  
  3.     System.out.println("===========after finally advice");  
  4. }  

 

其中测试代码与Schema方式几乎一样,在此就不演示了,如果需要请参考AopTest.java中的testAnnotationAfterFinallyAdvice测试方法。

 

 

五、环绕通知:使用org.aspectj.lang.annotation 包下的@Around注解声明;

 

java代码:
  1. @Around (  
  2. value="切入点表达式或命名切入点",  
  3. argNames="参数列表参数名")  

 

       value:指定切入点表达式或命名切入点;

       argNames:与Schema方式配置中的同义;

 

 

java代码:
  1. @Around(value="execution(* cn.javass..*.sayAround(..))")  
  2. public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {  
  3.     System.out.println("===========around before advice");  
  4.     Object retVal = pjp.proceed(new Object[] {"replace"});  
  5.     System.out.println("===========around after advice");  
  6.     return retVal;  
  7. }  

 

 

其中测试代码与Schema方式几乎一样,在此就不演示了,如果需要请参考AopTest.java中的annotationAroundAdviceTest测试方法。

6.4.5  引入

       @AspectJ风格的引入声明在切面中使用org.aspectj.lang.annotation包下的@DeclareParents声明:

 

java代码:
  1. @DeclareParents(  
  2. value=" AspectJ语法类型表达式",  
  3. defaultImpl=引入接口的默认实现类)  
  4. private Interface interface;  

 

       value:匹配需要引入接口的目标对象的AspectJ语法类型表达式;与Schema方式中的types-matching属性同义;

       private Interface interface指定需要引入的接口;

       defaultImpl指定引入接口的默认实现类,没有与Schema方式中的delegate-ref属性同义的定义方式;

 

java代码:
  1. @DeclareParents(  
  2.     value="cn.javass..*.IHelloWorldService+", defaultImpl=cn.javass.spring.chapter6.service.impl.IntroductiondService.class)  
  3. private IIntroductionService introductionService;  
  4.    

 

       其中测试代码与Schema方式几乎一样,在此就不演示了,如果需要请参考AopTest.java中的testAnnotationIntroduction测试方法。

   

[html] view plain copy
 
  1. <aop:config></aop:config>解析  
分享到:
评论

相关推荐

    spring-aop-aspectj-case

    - **&lt;aop:aspectj-autoproxy/&gt;**:在Spring配置文件中启用AspectJ自动代理。 4. **实际应用示例**: - 日志记录:通过切面记录方法的调用时间、参数等信息。 - 事务管理:利用AOP进行数据库事务的开启、提交、...

    Spring AOP + AspectJ in XML 配置示例

    &lt;aop:aspectj-autoproxy/&gt; &lt;!-- 配置切面的通知 --&gt; &lt;aop:config&gt; &lt;aop:aspect ref="myAspect"&gt; &lt;aop:before method="beforeAdvice" pointcut-ref="myPointcut"/&gt; &lt;aop:after method="afterAdvice" pointcut-...

    spring源码导入所需aspectj包

    &lt;aop:aspectj-autoproxy /&gt; ``` 这行配置会自动创建代理以应用切面。 3. **编写Aspect**:在Spring应用中,你可以定义一个名为`Aspect`的类,其中包含`@Before`, `@After`, `@Around`, `@Pointcut`等注解来声明...

    spring aop注解方式、xml方式示例

    &lt;aop:aspectj-autoproxy /&gt; &lt;bean id="loggingAspect" class="com.example.aspect.LoggingAspect" /&gt; ``` ### XML方式 #### 1. 定义切面 在XML配置中,我们创建一个`&lt;aop:config&gt;`元素,并定义`&lt;aop:aspect&gt;`子...

    spring对AOP的支持(使用AspectJ进行AOP演示)

    &lt;aop:aspectj-autoproxy /&gt; ``` 这行配置会告诉 Spring 使用 AspectJ 的代理模式来处理切面。 最后,我们需要确保在运行时 weaving(编织)切面。有两种方式实现 weaving:编译时 weaving 和运行时 weaving。编译...

    Spring AOP + AspectJ annotation example

    &lt;aop:aspectj-autoproxy /&gt; ``` 然后,将切面类(如`LoggingAspect`)加入到Spring容器中,这样Spring就会自动处理切面的织入。 除了基本的通知类型,AspectJ还提供了更复杂的用法,如`@Around`,它允许完全控制...

    day39 07-Spring的AOP:自动代理

    当我们在配置文件中启用&lt;aop:aspectj-autoproxy/&gt;或在代码中使用@EnableAspectJAutoProxy注解时,Spring会自动为包含切面注解(@Aspect)的bean创建代理。 切面通常由以下几个部分组成: 1. **通知(Advice)**:这...

    Spring 使用AspectJ 实现 AOP之前置通知小例子

    可以通过`&lt;aop:aspectj-autoproxy&gt;`元素来实现。 ```xml &lt;aop:aspectj-autoproxy /&gt; ``` 2. **定义切面(Aspect)**:切面是AOP的核心,它包含了通知和切入点表达式。在Java代码中,可以创建一个带有`@Aspect`注解...

    Spring2.5使用AOP需要的aspectJ

    可以通过设置`&lt;aop:aspectj-autoproxy/&gt;`元素来实现。 3. 定义切面类,其中包含通知方法。这些方法需要使用特定的注解(如`@Before`、`@After`、`@Around`等)来指定其类型和切入点表达式。 4. 使用`@Aspect`注解...

    spring AspectJ aop学习

    &lt;aop:aspectj-autoproxy /&gt; &lt;bean id="loggingAspect" class="com.example.aspect.LoggingAspect" /&gt; ``` 同时,在Maven或Gradle构建工具中引入AspectJ的依赖。 通过以上介绍,我们可以看到Spring AOP结合AspectJ...

    spring-aop实例demo

    这可以通过设置`&lt;aop:aspectj-autoproxy&gt;`或`&lt;aop:config&gt;`元素来完成。例如: ```xml &lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ...

    @AspectJ配置Spring AOP,demo

    &lt;aop:aspectj-autoproxy /&gt; &lt;bean class="com.example.aspect.LoggingAspect" /&gt; ``` 或者在Java配置中: ```java @Configuration @EnableAspectJAutoProxy public class AppConfig { @Bean public ...

    spring_MVC源码

    54. &lt;aop:aspectj-autoproxy/&gt; 55.&lt;/beans&gt; hibernate.properties数据库连接配置 [java] view plaincopy 01.dataSource.password=123 02.dataSource.username=root 03.dataSource.databaseName=test...

    Spring @AspectJ 实现AOP 入门例子

    这里,`&lt;aop:aspectj-autoproxy&gt;`元素启用了基于注解的AOP代理,`&lt;bean&gt;`标签注册了我们的`LoggingAspect`类。 最后,当Spring启动时,它会自动检测到`LoggingAspect`类,并在合适的时候调用其定义的通知。现在,...

    征服Spring AOP—— @AspectJ

    &lt;aop:aspectj-autoproxy /&gt; ``` 或者,在使用Java配置时,在`@Configuration`类中添加`@EnableAspectJAutoProxy`注解: ```java @Configuration @EnableAspectJAutoProxy public class AppConfig { // ... } ``` ...

    11spring4_aop3.rar

    第三种实现方法—通过注解来实现 签名 注解实现aop &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;beans xmlns="http://www.springframework.org/schema/beans" ... &lt;aop:aspectj-autoproxy/&gt; &lt;/beans&gt;

    Spring Aop四个依赖的Jar包

    &lt;aop:aspectj-autoproxy /&gt; ``` 然后,我们可以定义切面、切点和通知,比如: ```xml &lt;bean id="loggingAspect" class="com.example.LoggingAspect" /&gt; &lt;aop:config&gt; &lt;aop:aspect ref="loggingAspect"&gt; &lt;aop:...

    基于框架的Web开发-基于AspectJ的AOP.doc

    同时,通过`&lt;aop:aspectj-autoproxy/&gt;`元素启用AspectJ自动代理。 最后,我们可以通过测试类验证切面是否生效。测试类从`beans.xml`加载配置,获取名为`ballet`的bean(因为`Ballet`类添加了`@Component`注解),并...

    Spring AOP demo (maven)

    &lt;aop:aspectj-autoproxy /&gt; &lt;!-- 或者使用CGLIB代理 --&gt; &lt;aop:config proxy-target-class="true"&gt; &lt;/aop:config&gt; ``` 3. **定义切面**:创建一个Java类,该类将包含切点注解(@Pointcut)和通知方法。通知方法通常...

    Aop之AspectJ详解解读demo

    &lt;aop:aspectj-autoproxy /&gt; ``` **四、AspectJ的应用场景** 1. **日志记录**:在方法调用前后记录日志,便于追踪程序运行状态。 2. **事务管理**:在数据库操作前后处理事务开始和结束,确保数据一致性。 3. *...

Global site tag (gtag.js) - Google Analytics