• AOP中获取自定义注解的参数值


    目录

    一、利用注解实现AOP的基本流程

      1.1、创建一个注解,用来注解切点(pointcut)

      1.2、创建一个service,使用上面定义的注解来指定切点

      1.3、创建Aspect,增加业务逻辑

      1.4、创建Spring配置类

      1.5、测试

    二、获取自定义注解的参数

      2.1、创建带属性的自定义注解

      2.2、创建service使用带属性的自定义注解

      2.3、创建Aspect的错误示例

      2.4、创建Aspect的正确做法

      2.5、测试

    三、总结

    一、利用注解实现AOP的基本流程 

      如果特别熟悉自定义注解实现AOP,可以直接转到第二部分:跳转

      Spring中,可以通过自定义注解的方式来实现AOP,比较简单,流程如下:  

      1.1、创建一个注解,用来注解切点(pointcut)

    package cn.ganlixin.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface DemoAnnotation {
        //注意这里没有定义属性
    }
    

      

      1.2、创建一个service,使用上面定义的注解来指定切点

      这里为了节约篇幅,就不创建service接口,再创建serviceImpl来实现接口了,直接写在service中:

    package cn.ganlixin.service;
    
    import cn.ganlixin.annotation.DemoAnnotation;
    import org.springframework.stereotype.Service;
    
    @Service
    public class DemoService {
    
        @DemoAnnotation  // 使用自定义的注解,声明该方法为切点方法
        public void demo() {
            System.out.println("this is DemoService.demo()");
        }
    }
    

      

      1.3、创建Aspect,增加业务逻辑

    package cn.ganlixin.aspect;
    
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    
    @Component
    @Aspect
    public class DemoAspect {
    
        @Before("@annotation(cn.ganlixin.annotation.DemoAnnotation)")
        public void demoBefore() {
            System.out.println("this is before output message");
        }
    }
    

      

      1.4、创建Spring配置类

      主要做的是:指定包扫描路径

    package cn.ganlixin;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    
    @Configuration
    @ComponentScan("cn.ganlixin")
    @EnableAspectJAutoProxy
    public class AppConfig {
        
    }
    

      

      1.5、测试

    package cn.ganlixin;
    
    import cn.ganlixin.service.DemoService;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class AppTest {
    
        @Test
        public void testAOP1() {
            ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    
            DemoService demoService = context.getBean(DemoService.class);
            demoService.demo();
        }
    }
    

      输出:

    this is before output message
    this is DemoService.demo()
    

      

    二、获取自定义注解的参数

      2.1、创建带属性的自定义注解

      要获取自定义注解参数,就需要在自定义注解中增加几个属性,下面自定义的TestAnnotation中有两个属性:value和description。

    package cn.ganlixin.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface TestAnnotation {
        String value();
        String description() default "default description";
    }
    

      

      2.2、创建service使用带属性的自定义注解

      service中有两个方法,分别使用了自定义注解:

    package cn.ganlixin.service;
    
    import cn.ganlixin.annotation.TestAnnotation;
    import org.springframework.stereotype.Service;
    
    @Service
    public class TestService {
        
        @TestAnnotation("this is value")
        public void test1() {
            System.out.println("this is TestService.test1()");
        }
        
        @TestAnnotation(value = "this is another value", description = "this is description")
        public void test2() {
            System.out.println("this is TestService.test2()");
        }
    }
    

      

      2.3、创建Aspect的错误示例

      在写博客之前,我也搜过相关的博客,但是发现很多博客中写的都是利用@Around来实现获取注解信息,但是我如果需要在@Before中,@After中获取又怎么办呢?虽然可以通过以下骚操作,通过@Around来模拟@Before和@After,但是还是感觉不好。

      下面还是使用@Before来实现的。

    package cn.ganlixin.aspect;
    
    import cn.ganlixin.annotation.TestAnnotation;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    
    @Component
    @Aspect
    public class TestAspect {
    
        @Before("@annotation(cn.ganlixin.annotation.TestAnnotation)")
        public void one(TestAnnotation testAnonotation) {
            System.out.println(testAnonotation.value());
            System.out.println(testAnonotation.description());
        }
    }
    

      上面的代码看似没有问题,one()方法中接收一个TestAnnotation的参数,以为能够获取到切点方法的注解信息,但是,IDE会告诉你如下错误:

      

      2.4、创建Aspect的正确做法

    package cn.ganlixin.aspect;
    
    import cn.ganlixin.annotation.TestAnnotation;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    @Component
    @Aspect
    public class TestAspect {
    
        // 先创建一个方法,方法名随意,但是需要制定@annotation为刚刚自定义的注解
        @Pointcut("@annotation(cn.ganlixin.annotation.TestAnnotation)")
        public void test() {}
    
        // 使用@Before,需要先引入上面@Pointcut注解的方法名,在加上@annotation,
        // @annotation中的值,需要和action方法中的参数名称相同(必须相同,但是名称任意)
        @Before("test() && @annotation(testAnnotation)")
        public void action(TestAnnotation testAnnotation) {
            System.out.println("Annotation value : " + testAnnotation.value());
            System.out.println("Annotation description : " + testAnnotation.description());
            System.out.println("this is TestAspect.action()");
        }
    }
    

      划重点

    // 第2个示例,强调@annotation中的值,需要和方法参数名相同
    @Before("test() && @annotation(abcdef)")
    public void action2(TestAnnotation abcdef) {
        System.out.println("Annotation value : " + abcdef.value());
        System.out.println("Annotation description : " + abcdef.description());
        System.out.println("this is TestAspect.action()");
    }
    

      

       2.5、测试

      Spring的配置类不用更改,测试代码如下:

    package cn.ganlixin;
    
    import cn.ganlixin.service.TestService;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class AppTest {
        @Test
        public void testAOP2() {
            ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
            TestService testService = context.getBean(TestService.class);
            
            testService.test1();
            System.out.println("----------------------------");
            testService.test2();
        }
    }
    

      输出:

    Annotation value : this is value
    Annotation description : default description
    this is TestAspect.action()
    this is TestService.test1()
    ----------------------------
    Annotation value : this is another value
    Annotation description : this is description
    this is TestAspect.action()
    this is TestService.test2()
    

      

    三、总结

      要想是获取AOP中自定义注解的参数值,主要就一点:

      

  • 相关阅读:
    小海豚 Flow Photo 推广码3029 手机破解版下载
    centos6升级升级openssl为1.0.2u
    centos6修改yum源
    关于单点登录系统(二)
    关于使用notePad++添加sql引号
    关于MySQL海量数据分页查询
    晒书求共勉 希
    HTML5+CSS3实现的小风车转动的童年 希
    用JavaScript+CSS给自己写一个倒计时提示主页 希
    P2764 最小路径覆盖问题
  • 原文地址:https://www.cnblogs.com/-beyond/p/11387487.html
Copyright © 2020-2023  润新知