• 基于@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 ...

  • 相关阅读:
    [前端开发]Vue组件化的思想
    [前端开发]数组中哪些方法是响应式的
    冒泡排序和选择排序
    css定位属性的运用
    JS拖拽效果的原理及实现
    Js函数的形参和实参详解
    Js中的For循环详解
    什么是盒模型?
    关于使用JS去除URL中的指定参数问题,js 对url进行某个参数的删除,并返回url
    听力的尝试
  • 原文地址:https://www.cnblogs.com/asnjudy/p/4174680.html
Copyright © 2020-2023  润新知