美文网首页
02-06 AOP学习之@args,@annotation,be

02-06 AOP学习之@args,@annotation,be

作者: 幽暗金 | 来源:发表于2018-01-11 14:11 被阅读0次

    Spring AOP @args,@annotation和bean使用示例

    @args:使用“@args(注解列表)”匹配当前执行的方法传入的参数持有指定注解的执行

    注解类型也必须是全限定类型名

    模式 描述
    @args(com.learn.annotation.Secure) 任何一个只接受一个参数的方法,且方法运行时传入的参数持有注解com.learn.annotation.Secure;动态切入点,类似于arg指示符

    @annotation:使用“@annotation(注解类型)”匹配当前执行方法持有指定注解的方法

    注解类型也必须是全限定类型名

    模式 描述
    @annotation(com.learn.annotation.Secure) 当前执行方法上持有注解com.learn.annotation.Secure将被匹配

    bean:使用“bean(Bean id或名字通配符)”匹配特定名称的Bean对象的执行方法

    Spring ASP扩展的,在AspectJ中无相应概念

    模式 描述
    bean(*Service) 匹配所有以Service命名(id或name)结尾的Bean

    示例

    @args示例

    1. 创建注解

      • 创建package命名为com.learn.annotation(根据实际情况修改)
      • 创建注解Secure,内容如下
        @Documented
        @Retention(RetentionPolicy.RUNTIME)
        @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
        public @interface Secure {
        }
        
    2. 创建实体类

      • 创建package命名为com.learn.model(根据实际情况修改)

      • 创建类User,内容如下

        public class User {
            public String getName() {
                return "user";
            }
        }
        
      • 创建Member继承User,并加上注解@Secure,内容如下

        @Secure
        public class Member extends User{
            @Override
            public String getName() {
                return "member";
            }
        }
        
      • 创建Leader继承Member,内容如下

        public class Leader extends Member{
            @Override
            public String getName() {
                return "leader";
            }
        }
        
    3. 创建服务

      • 创建package命名为com.learn.service(根据实际情况修改)

      • 创建接口IHelloService,内容如下

        public interface IHelloService {
        
            void sayHello(User user);
        
            void secureSay();
        }
        
      • 创建package命名为com.learn.service.impl(根据实际情况修改)

      • 创建接口IHelloService的实现类HelloServiceImpl,内容如下

        @Service
        public class HelloServiceImpl implements IHelloService {
        
            @Override
            public void sayHello(User user) {
                System.out.println(user.getName() + ":hello");
            }
        
        }
        
    4. 创建AOP

      • 创建package命名为com.learn.aop(根据实际情况修改)
      • 配置AOP,新建ExecutionAOP,内容如下
        @Aspect
        @Component
        public class ExecutionAop {
        
            @Before("execution(* com.learn..*(..)) && @args(com.learn.annotation.Secure)")
            public void execute1(){
                System.out.println("@args(com.learn.annotation.Secure)");
            }
        }
        
    5. 创建测试用例

      @RunWith(SpringRunner.class)
      @SpringBootTest
      public class ApplicationTests {
      
          @Resource
          private IHelloService helloService;
      
          @Test
          public void test1() {
              System.out.println("------------------User-----------------");
              helloService.sayHello(new User());
              System.out.println("------------------Member-----------------");
              helloService.sayHello(new Member());
              System.out.println("------------------Leader-----------------");
              helloService.sayHello(new Leader());
          }
          
      }
      

      运行测试用例可得到结果

      ------------------User-----------------
      user:hello
      ------------------Member-----------------
      @args(com.learn.annotation.Secure)
      member:hello
      ------------------Leader-----------------
      leader:hello
      

      由此可知,@args会根据传入的参数取动态的匹配方法。

    @annotation示例

    1. 添加方法

      • 在接口IHelloService中新增方法,内容如下

        public interface IHelloService {
            void secureSay();
        }
        
      • 在其实现类中实现该方法

        @Service
        public class HelloServiceImpl implements IHelloService {
            @Secure
            @Override
            public void secureSay() {
                System.out.println("hello");
            }
        }
        
    2. 新增AOP监听

      • ExecutionAOP中新增监听,内容如下
        @Aspect
        @Component
        public class ExecutionAop {
        
            @Before("@annotation(com.learn.annotation.Secure)")
            public void execute2(){
                System.out.println("@annotation(com.learn.annotation.Secure)");
            }
        
        }
        
    3. 创建测试用例

      @RunWith(SpringRunner.class)
      @SpringBootTest
      public class ApplicationTests {
      
          @Resource
          private IHelloService helloService;
      
          @Test
          public void test2() {
              helloService.secureSay();
          }
      
      }
      

      运行测试用例可得到结果

      @annotation(com.learn.annotation.Secure)
      hello
      

      可以看出加了注解的方法确实被AOP匹配到了。

    @bean示例

    1. 创建服务

      • com.learn.service包中创建接口IExceptService

        public interface IExceptService {
            void sayHello();
        }
        
      • com.learn.service.impl包中创建其实现类ExceptService

        @Service
        public class ExceptService implements IExceptService {
        
            @Override
            public void sayHello() {
                System.out.println("hello");
            }
        
        }
        
    2. 新增AOP监听

      • ExecutionAOP中新增监听,内容如下
        @Aspect
        @Component
        public class ExecutionAop {
            @Before("bean(*Service)")
            public void execute3(){
                System.out.println("bean(*Service)");
            }
        }
        
    3. 创建测试用例

      @RunWith(SpringRunner.class)
      @SpringBootTest
      public class ApplicationTests {
      
          @Resource
          private IExceptService exceptService;
      
          @Test
          public void test3() {
              exceptService.sayHello();
          }
      }
      

      运行测试用例可得到结果

      bean(*Service)
      hello
      

      可以看出命名以Service结尾的服务中的方法确实被AOP匹配到了。

    目录
    源码链接

    相关文章

      网友评论

          本文标题:02-06 AOP学习之@args,@annotation,be

          本文链接:https://www.haomeiwen.com/subject/mwgznxtx.html