彻底搞懂SpringAOP中的@within和@target

本文是对参考连接的一个补充,只讨论@within@target的区别。如果不懂注解的、不懂AOP的先去补一下。

参考连接

概述

@within@target是在配置切点的时候使用到的两个修饰符,都是基于注解来配置切点。

比如当前有注解@A

  • "@within(com.annotation.other.A1)"该配置就是:如果某个类上标注了注解@A,那么该类中的所有方法就会被匹配为切点,并且该类的子类中没有重写的父类方法也会被匹配为切点(看不懂的别急,后面有例子)
  • "@target(com.annotation.other.A1)"该配置就是:如果某个类上标注了注解@A,那么该类中的所有方法就会被匹配为切点。

约定

本文说的子类和父类关系都是类之间的子类和父类。不涉及注解继承,也就是自定义注解中没有标注元注解–@Inherited。

@within@target正确用法是 "@within/@target(注解的全类名)",以下简写"@within/@target(@A1)"

实例

类图
在这里插入图片描述

两个自定义注解

//注解@A1
@Retention(RetentionPolicy.RUNTIME)
@Target( ElementType.TYPE)
public @interface A1 {
}

//注解@A2
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface A2 {
}

三个有继承关系的类

@A1
public  class Human {

    public void say(String sentence)
    {
        System.out.println("Human says:" + sentence);
    }

    public void run()
    {
        System.out.println("Human runs." );
    }

    public void jump()
    {
        System.out.println("Human jump." );
    }
}


@A2
public class Man  extends Human{

    @Override
    public void run()
    {
        System.out.println("Man runs." );
    }
    
    public void testMan(){
        System.out.println("Man testMan." );
    }
}

public class Boy extends Man{

    @Override
    public void jump()
    {
        System.out.println("Boy jump." );
    }

    public void test(){
        System.out.println("Bot test...");
    }
}

切面

@Aspect
@Component
public class HumanAspect {

    @Before("@within(com.annotation.other.A1)")
    public void execute1(){
        System.out.println("@within --- A1");
    }

    @Before("@target(com.annotation.other.A1)")
    public void execute2(){
        System.out.println("@target --- A1");
    }

    @Before("@within(com.annotation.other.A2)")
    public void execute3(){
        System.out.println("@within --- A2");
    }

    @Before("@target(com.annotation.other.A2)")
    public void execute4(){
        System.out.println("@target --- A2");
    }
}

配置类

@Configuration
@ComponentScan("com.annotation.other")
@EnableAspectJAutoProxy
public class HumanManager {

    @Bean(name = "human")
    public Human getHuman() {
        return new Human();
    }

    @Bean(name = "man")
    public Man getMan() {
        return new Man();
    }

    @Bean(name = "boy")
    public Boy getBoy() {
        return new Boy();
    }
}

输出结果

--------------- This is a Human ---------------
@within --- A1
@target --- A1
Human says:hello!
@within --- A1
@target --- A1
Human jump.
@within --- A1
@target --- A1
Human runs.
---------------------This is a Man ---------------
@within --- A1
@target --- A2
Human says:hello!
@within --- A1
@target --- A2
Human jump.
@within --- A2
@target --- A2
Man runs.
---------------------This is a Boy ---------------
@within --- A1
Human says:hello!
Boy jump.
@within --- A2
Man runs.
Bot test...

结合类图来分下下输出结果
在这里插入图片描述
对于Human方法的输出情况。可以确定的是,如果类上标注了@within@target指定的注解,那么该类的所有方法就会被匹配为切点。

对于Man方法的输出情况,Man只标有注解@A2,Man的父类标有注解@A1
- 继承了父类,但没有重写的方法会被@within(@A1)匹配为切点,不会被@target(@A1)匹配。

- 继承父类并在子类重写的方法不会被@within(@A1)匹配为切点,也不会被@target(@A1)匹配为切点。

- 对于@within(@A2)、@target(@A2)会匹配Man类中非继承或继承但重写或自己的方法为切点。

对于Boy类输出情况 ,Boy类上没有注解,Boy继承了Man类,Man类继承了Human类。Man类表有注解@A2,Human类标有注解@A1。 Boy重写了属于Human类的jump()方法,Boy类有自己的方法test()

  • @winthin(@A1)匹配了Boy类继承Human类但并未重写的方法,@winthin(@A2)匹配了继承自Man类但并为重写的方法。

总结

对于匹配不具有继承性且为运行时的注解

即被匹配注解标注了@Retention(RetentionPolicy.RUNTIME),但没有标注
@Inherited

  • @within会匹配到标注了指定注解的类,并且在该类的子类中,那些没有重写的父类方法也会被匹配到。
    -@target只匹配标注了指定注解的类。不涉及任何其他类。
  • 15
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOP 是一个用于实现面向切面编程的框架。它可以通过配置来实现横切关注点的模块化,并将其应用到程序的不同部分。Spring AOP 使用 AspectJ 切入点指示符来定义切入点表达式,用于匹配方法执行连接点。Spring AOP 支持以下 AspectJ 切入点指示符: 1. execution:用于匹配方法执行连接点。这是使用 Spring AOP 时要使用的主要切入点指示符。 2. within:限制匹配以连接某些类型的点(使用 Spring AOP 时在匹配类型声明的方法的执行)。 3. this:限制匹配到连接点(使用 Spring AOP 时方法的执行),其 Bean 引用(Spring AOP 代理)是给定类型的实例。 4. target:限制匹配到连接点(使用 Spring AOP 时方法的执行),其目标对象(正在代理的应用程序对象)是给定类型的实例。 5. args:限制匹配到连接点(使用 Spring AOP 时方法的执行),其参数是给定类型的实例。 6. @target:限制匹配到连接点(使用 Spring AOP 时方法的执行),其执行对象的类具有给定类型的注释。 7. @args:限制匹配到连接点(使用 Spring AOP 时方法的执行),其传递的实际参数的运行时类型具有给定类型的注释。 8. @within:限制匹配以连接具有给定注释的类型的点(使用 Spring AOP 时在具有给定注释的类型声明的方法的执行)。 9. @annotation:限制匹配到连接点的主题(在 Spring AOP 运行的方法)具有给定注释的连接点。 在使用 Spring AOP 时,需要引入 Spring AOPSpring Context 相关的包,并在配置文件进行相应的配置。可以通过 Maven 或其他构建工具来引入相关依赖。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值