700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 彻底搞懂SpringAOP中的@within和@target

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

时间:2018-12-11 01:05:12

相关推荐

彻底搞懂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 {}

三个有继承关系的类

@A1public 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." );}}@A2public class Man extends Human{@Overridepublic void run(){System.out.println("Man runs." );}public void testMan(){System.out.println("Man testMan." );}}public class Boy extends Man{@Overridepublic void jump(){System.out.println("Boy jump." );}public void test(){System.out.println("Bot test...");}}

切面

@Aspect@Componentpublic 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")@EnableAspectJAutoProxypublic 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 --- A1Human says:hello!@within --- A1@target --- A1Human jump.@within --- A1@target --- A1Human runs.---------------------This is a Man ---------------@within --- A1@target --- A2Human says:hello!@within --- A1@target --- A2Human jump.@within --- A2@target --- A2Man runs.---------------------This is a Boy ---------------@within --- A1Human says:hello!Boy jump.@within --- A2Man 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只匹配标注了指定注解的类。不涉及任何其他类。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。