欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring注解开发 - AOP

程序员文章站 2022-07-12 23:08:16
...

AOP

很简单,一句话:采用动态代理的方式,在程序运行期间将某段代码切入到指定位置运行的编程方式

  • 导入依赖
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>5.2.9.RELEASE</version>
            </dependency>
  • 定义业务逻辑类(MathCalculator),在业务逻辑执行的时候将日志进行打印
    public class MathCalculator {
    
        public int div(int i, int j) {
            System.out.println("MathCalculator ----> div");
            return i / j;
        }
    }
  • 定义一个日志切面类(LogAspects),切面类里面的方法需要动态感知MathCalculator.div的运行状态,给切面类的目标方法标注何时何地运行(将通知注解标记在对应的方法上),告诉Spring那个类是切面类(给切面类加一个注解:@Aspect)。每个通知方法默认可以有个一个JoinPoint 对象注入到通知中,通知中可以获取到方法名、参数等等信息
    @Aspect//告诉Spring该类是一个切面类
    public class LogAspects {
    
        @Pointcut(value = "execution(public int com.booyue.tlh.aop.MathCalculator.div(int,int))")
        public void pointCut() {
        }
    
        /**
         * JoinPoint 参数一定要出现在参数表的第一位
         *
         * @param joinPoint
         */
        @Before(value = "pointCut()")
        public void logStart(JoinPoint joinPoint) {
            System.out.println("除法运行 ----> 方法是:" + joinPoint.getSignature().toLongString() + ",参数列表是:{" + Arrays.toString(joinPoint.getArgs()) + "}");
        }
    
        @AfterReturning(pointcut = "pointCut()", returning = "result")
        public void logReturn(JoinPoint joinPoint, Object result) {
            System.out.println("除法正常返回 ----> 方法名:" + joinPoint.getSignature().toLongString() + "计算结果是:{" + result + "}");
        }
    
        @After(value = "pointCut()")
        public void logEnd(JoinPoint joinPoint) {
            System.out.println("除法结束 ----> 方法名:" + joinPoint.getSignature().toLongString() + ",参数列表是:{}");
        }
    
        @AfterThrowing(value = "pointCut()", throwing = "exception")
        public void logException(JoinPoint joinPoint, Exception exception) {
            System.out.println("除法发生异常 ----> 方法名:" + joinPoint.getSignature().toLongString() + ",异常信息:{" + exception.getMessage() + "}");
        }
    
    }
  • 将切面类和业务逻辑类都注入到Spring的IOC容器中,告诉Spring开启自动注解(在配置文件上加上注解:@EnableAspectJAutoProxy)
    @EnableAspectJAutoProxy//告诉Spring开启基于注解的AOP模式
    @Configuration//告诉Spring这里是一个配置文件
    public class MainConfigAOP {
    
        @Bean//将业务逻辑类加入到Spring的IOC容器中
        public MathCalculator mathCalculator() {
            return new MathCalculator();
        }
    
        @Bean//将切面日志类假如到Spring的IOC容器中
        public LogAspects logAspects() {
            return new LogAspects();
        }
    
    }
    
  • 执行业务逻辑,查看同调通知
       @Test
        public void testAnnotation13() {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigAOP.class);
            MathCalculator mathCalculator=context.getBean(MathCalculator.class);
            int result = mathCalculator.div(10, 5);
            System.out.println(result);
        }
    
    
    //打印回调通知
    
    除法运行 ----> 方法是:public int com.booyue.tlh.aop.MathCalculator.div(int,int),参数列表是:{[10, 5]}
    MathCalculator ----> div
    除法正常返回 ----> 方法名:public int com.booyue.tlh.aop.MathCalculator.div(int,int)计算结果是:{2}
    除法结束 ----> 方法名:public int com.booyue.tlh.aop.MathCalculator.div(int,int),参数列表是:{}
    2

     

总结步骤

  • 将业务逻辑类和切面类都注入到Spring的IOC容器中,告诉Spring那个是切面类(注解:@Aspect)
  • 切面类上的通知方法用对应的注解标注,告诉Spring何时何地运行(切入点表达式)
  • 开启基于注解的AOP功能(注解:@EnableAspectJAutoProxy)

 

相关标签: Spring Aspect