02-03 AOP学习之this和target使用示例及对比分析

this:使用“this(类型全限定名)”匹配当前AOP代理对象类型的执行方法

注意 是AOP代理对象的类型匹配,这样就可能包括引入接口方法也可以匹配;注意this中使用的表达式必须是类型全限定名,不支持通配符

模式 描述
this(com.learn.model.Member) 当前AOP对象实现了Member接口/抽象类的某些方法,Member的父类未重载的方法不会被处理

target:使用“target(类型全限定名)”匹配当前目标对象类型的执行方法

注意 是目标对象的类型匹配,这样就不包括引入接口也类型匹配;注意target中使用的表达式必须是类型全限定名,不支持通配符

模式 描述
target(com.learn.model.Member) 当前目标对象(非AOP对象)实现了Member接口/抽象类的某些方法,Member的父类未重载的方法也会被处理
  1. 创建组件

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

    • 创建抽象类User,内容如下

      public abstract class User {
          public abstract void who();
      
          public void say() {
              System.out.println("hello");
          }
      
          public void root() {
              System.out.println("user");
          }
      }
      
    • 创建组件Member,内容如下

      @Component
      public class Member extends User{
      
          @Override
          public void who() {
              System.out.println("member");
          }
      
          public void doSomething() {
              System.out.println("member doSomething");
          }
      
          public void getCompany() {
              System.out.println("zero tec");
          }
      }
      
    • 创建组件Leader,内容如下

      @Component
      public class Leader extends Member{
          @Override
          public void say() {
              System.out.println("hello, members");
          }
      
          @Override
          public void who() {
              System.out.println("leader");
          }
      
          @Override
          public void doSomething() {
              System.out.println("leader doSomething");
          }
      
          public void self() {
              System.out.println("leader self");
          }
      }
      
  2. 创建AOP

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

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class ApplicationTests {
    
        @Resource
        private Member member;
        @Resource
        private Leader leader;
    
        // 实现
        @Test
        public void test1() {
            System.out.println("---------------member---------------");
            member.who();
            System.out.println("---------------leader---------------");
            leader.who();
        }
    
        @Test
        public void test2() {
            // 继承
            System.out.println("---------------member---------------");
            member.say();
            // 重载
            System.out.println("---------------leader---------------");
            leader.say();
        }
    
        @Test
        public void test3() {
            System.out.println("---------------member---------------");
            member.root();
            System.out.println("---------------leader---------------");
            leader.root();
        }
    
        @Test
        public void test4() {
            // 独有方法
            System.out.println("---------------member---------------");
            member.doSomething();
            // 子类重写
            System.out.println("---------------leader---------------");
            leader.doSomething();
        }
    
        @Test
        public void test5() {
            System.out.println("---------------member---------------");
            member.getCompany();
            System.out.println("---------------leader---------------");
            leader.getCompany();
        }
    
        // 独有的方法
        @Test
        public void test6() {
            System.out.println("---------------leader---------------");
            leader.self();
        }
    }
    
    1. 运行test1可得到结果

      ---------------member---------------
      this(com.learn.model.Member)
      target(com.learn.model.Member)
      member
      ---------------leader---------------
      this(com.learn.model.Member)
      target(com.learn.model.Member)
      leader
      

      由结果可知,对于重载的方法,this和target都会匹配到。

    2. 运行test2可得到结果

      ---------------member---------------
      target(com.learn.model.Member)
      hello
      ---------------leader---------------
      this(com.learn.model.Member)
      target(com.learn.model.Member)
      hello, members
      

      由结果可知,target可以匹配到未重载的方法,而this不能

    3. 运行test3可得到结果

      ---------------member---------------
      target(com.learn.model.Member)
      user
      ---------------leader---------------
      target(com.learn.model.Member)
      user
      

      和结论2一样

    4. 运行test4可得到结果

      ---------------member---------------
      this(com.learn.model.Member)
      target(com.learn.model.Member)
      member doSomething
      ---------------leader---------------
      this(com.learn.model.Member)
      target(com.learn.model.Member)
      leader doSomething
      

      由结果可知,this和target都能被继承

    5. 运行test5可得到结果

      ---------------member---------------
      this(com.learn.model.Member)
      target(com.learn.model.Member)
      zero tec
      ---------------leader---------------
      this(com.learn.model.Member)
      target(com.learn.model.Member)
      zero tec
      

      由结果可知,同上

    6. 运行test6可得到结果

      ---------------leader---------------
      this(com.learn.model.Member)
      target(com.learn.model.Member)
      leader self
      

      由结果可知,同上

    总结:

    • 两者都可继承。
    • 对于目标子类,未重载的父类方法是不能被this匹配到的,可以被target匹配到。

目录
源码链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。