基于@AspectJ注解配置切面与基于XML配置切面

 1. Waiter目标类

 1 package com.smart.aop.advice.pointcut;
 2 
 3 public class Waiter {
 4 
 5     public void greetTo(String name) {
 6         System.out.println("Waiter greet to " + name + " ...");
 7     }
 8 
 9     public void serverTo(String name) {
10         System.out.println("waiter server to " + name + " ...");
11     }
12 }

2. 使用AspectJ注解定义切面

 1 package com.smart.aop.advice.aspectj;
 2 
 3 import org.aspectj.lang.annotation.Aspect;
 4 import org.aspectj.lang.annotation.Before;
 5 
 6 @Aspect
 7 public class PreGreetingAspect {
 8     
 9     @Before ("execution(* greetTo(..))") //定义连接点(连接点方位信息--前置增强, 切点--所有目标类的greetTo方法--可带任意的入参和返回值)
10     public void beforeGreeting() {    
11         System.out.println("How are you!"); //方法体为增强逻辑
12     }
13 }

3. 通过编程的方式织入切面,为Waiter生成织入了xxx切面的代理

 1 package com.smart.aop.advice.aspectj;
 2 
 3 import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
 4 import org.testng.annotations.Test;
 5 import com.smart.aop.advice.pointcut.Waiter;
 6 
 7 
 8 public class AspectJProxyTest {
 9 
10     @Test
11     public void beforeTest() {
12         
13         Waiter waiter = new Waiter();
14         AspectJProxyFactory pFactory = new AspectJProxyFactory();
15         
16         pFactory.setTarget(waiter); //设置目标实例
17         pFactory.addAspect(PreGreetingAspect.class); //添加切面类
18         
19         Waiter proxyWaiter = pFactory.getProxy(); //生成织入代理的代理对象
20         
21         /**
22          * 由切面类中的切点信息execution(* greetTo(..))
23          * 可知代理对象proxyWaiter的greetTo方法织入了切面类所定义的增强逻辑
24          */
25         proxyWaiter.greetTo("Jack"); 
26         proxyWaiter.serverTo("Jack");
27     }
28 }
输出结果:

How are you!
Waiter greet to Jack ...


waiter server to Jack ...

4. 通过Spring配置方式织入切面

1)xml 配置

1     <!-- 匹配切点的目标bean -->
2     <bean id="waiter" class="com.smart.aop.advice.pointcut.Waiter" />
3     
4     <!-- 使用@AspectJ标注的切面类 -->
5     <bean class="com.smart.aop.advice.aspectj.PreGreetingAspect" />
6     
7     <!-- 自动代理创建器,能够将@AspectJ标注的切面自动织入到目标bean中 -->
8     <bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />

2)测试

 1 package com.smart.aop.advice.aspectj;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 import org.testng.annotations.Test;
 6 
 7 import com.smart.aop.advice.pointcut.Waiter;
 8 
 9 public class SpringAspectJTest {
10 
11     
12     @Test
13     public void beforeTest() {
14         
15         
16         ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/smart/aop/advice/aspectj/beans-aspectj.xml");
17         Waiter waiter = ctx.getBean("waiter", Waiter.class);
18         
19         waiter.greetTo("Jack");
20         waiter.serverTo("Jack");
21     }
22 }

------------------------------------------------------------------------

基于XML配置切面

把切面类中的通过@Aspect和@Before("execution(* greetTo(..))")配置的‘连接点(切点和增强类型)’信息从切面类中剥离出来放到XML中配置,使原来的切面类成为真正意义上的POJO

1. 切面类 --- 成为一个普通的java类

package com.smart.aop.advice.aspectj;

public class PreGreetingAspect {
    
    public void preGreeting() {    
        System.out.println("切入代码 How are you!");
    }
}

2. 在XML中配置切面

 1     <!-- 目标bean实例 -->
 2     <bean id="waiter" class="com.smart.aop.advice.pointcut.Waiter" />
 3     <!-- 切面实例 -->
 4     <bean id="greetingAspect" class="com.smart.aop.advice.aspectj.PreGreetingAspect" />
 5     
 6     <!-- proxy-target-class
 7            true, 声明的切面使用cglib代理技术
 8            false, 声明的切面使用JDK代理技术
 9             -->
10     <aop:config proxy-target-class="true">
11         <aop:aspect ref="greetingAspect">
12             <!-- 
13               aop:before,为前置增强 
14                   method属性,指定增强方法
15                   pointcut属性,定义切点表达式
16             -->
17             <aop:before method="preGreeting" pointcut="target(com.smart.aop.advice.pointcut.Waiter) and execution(* greetTo(..))"/>
18         </aop:aspect>
19     </aop:config>

使用4-2的方法测试,验证System.out.println("切入代码 How are you!");已织入到Waiter#greeTo()方法的前面。

加入后置增强

1. 切面类

package com.smart.aop.advice.aspectj;

public class PreGreetingAspect {
    
    public void preGreeting() {    
        System.out.println("Waiter#greetTo()方法执行前织入  How are you!");
    }
    
    public void postGreeting() {
        System.out.println("Waiter#greetTo()方法执行后织入 Byte!");
    }
}

2. XML配置

 1     <!-- 目标bean实例 -->
 2     <bean id="waiter" class="com.smart.aop.advice.pointcut.Waiter" />
 3     <!-- 切面实例 -->
 4     <bean id="greetingAspect" class="com.smart.aop.advice.aspectj.PreGreetingAspect" />
 5     
 6     
 7     <!-- proxy-target-class
 8            true, 声明的切面使用cglib代理技术
 9            false, 声明的切面使用JDK代理技术
10             -->
11     <aop:config proxy-target-class="true">
12     
13         <aop:pointcut id="greetToPointcut" 
14                 expression="target(com.smart.aop.advice.pointcut.Waiter) and execution(* greetTo(..))" />
15                 
16         <!-- 定义一个切面greetingAspect -->
17         <aop:aspect ref="greetingAspect">
18             <!-- 
19               aop:before,为前置增强 
20                   method属性,指定增强方法
21                   pointcut属性,定义切点表达式
22             -->
23             <aop:before method="preGreeting" pointcut-ref="greetToPointcut"/>
24         </aop:aspect>
25         
26         <aop:aspect ref="greetingAspect">
27             <aop:after method="postGreeting" pointcut-ref="greetToPointcut"/>
28         </aop:aspect>
29     </aop:config>

3. 测试

1     @Test
2     public void beforeTest() {
3         
4         ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/smart/aop/advice/aspectj/beans-aspectj.xml");
5         Waiter waiter = ctx.getBean("waiter", Waiter.class);
6         
7         waiter.greetTo("Jack");
8         waiter.serverTo("Jack");
9     }

输出结果:

Waiter#greetTo()方法执行前织入 How are you!
Waiter greet to Jack ...
Waiter#greetTo()方法执行后织入 Byte!
waiter server to Jack ...

原文地址:https://www.cnblogs.com/asnjudy/p/4174680.html