文章目录

  • 概述
  • @target(M)的匹配规则
  • @within(M)的匹配规则
  • 实例
    • @target
    • @within
  • 注意事项

概述

除了@annotation和@args外,还有另外两个用于注解的切点函数,分别是@target和@within.

和@annotation @args函数一样,@target和@within也只接受注解类名作为入参。

其中@target(M)匹配任意标注了@M的目标类,而@within(M)匹配标注了@M的类及其子孙类(子类经测试匹配不到,欢迎指正


@target(M)的匹配规则

@target使用@target(注解类型全限定名)匹配当前目标对象类型的执行方法, 必须是在目标对象上声明注解,在接口上声明不起作用


@within(M)的匹配规则

经验证,目前发现和 @target(M)的匹配规则是一样的。

@within(注解类型全限定名)匹配所有持有指定注解的类里面的方法, 即要把注解加在类上. 在接口上声明不起作用 。 子孙类经测试匹配不到,如有错误烦请指出。


实例

代码已托管到Github—> https://github.com/yangshangwei/SpringMaster


@target

首先自定义一个注解用于测试用

package com.xgj.aop.spring.advisor.aspectJ.function.attarget;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** * * @ClassName: Mark* * @Description: 自定义注解* * @author: Mr.Yang* * @date: 2017年9月5日 下午12:02:46*/@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface Mark {public String value() default "";}

4个注解标注的POJO ,继承关系 C3 -->C2–> C1–> C0

package com.xgj.aop.spring.advisor.aspectJ.function.attarget;import org.springframework.stereotype.Component;/*** * * @ClassName: C0* * @Description: @Component 标注的Bean* * @author: Mr.Yang* * @date: 2017年9月5日 下午1:36:37*/@Component
public class C0 {public void methodName() {System.out.println("C0 method executed");}
}

C1类声明处标注了自定义注解@Mark

package com.xgj.aop.spring.advisor.aspectJ.function.attarget;import org.springframework.stereotype.Component;@Mark
@Component
public class C1 extends C0 {public void methodName() {System.out.println("C1 method executed");}
}

C2类声明处标注了自定义注解@Mark

package com.xgj.aop.spring.advisor.aspectJ.function.attarget;import org.springframework.stereotype.Component;@Mark
@Component
public class C2 extends C1 {public void methodName() {System.out.println("C2 method executed");}
}
package com.xgj.aop.spring.advisor.aspectJ.function.attarget;import org.springframework.stereotype.Component;@Component
public class C3 extends C2 {public void methodName() {System.out.println("C3 method executed");}
}

使用@Aspect标注的环绕增强切面

package com.xgj.aop.spring.advisor.aspectJ.function.attarget;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;/*** * * @ClassName: AtTargetAspect* * @Description: 标注了@Aspect的切面 环绕增强切面* * @author: Mr.Yang* * @date: 2017年9月5日 上午11:59:26*/@Aspect
public class AtTargetAspect {@Around("@target(com.xgj.aop.spring.advisor.aspectJ.function.attarget.Mark)")public void crossCuttingCode(ProceedingJoinPoint joinPoint)throws Throwable {System.out.println("****AtTargetAspect.crossCuttingCode() : "+ joinPoint.getSignature().getName()+ ": Before Method Execution");try {joinPoint.proceed();} finally {// Do Something useful, If you have}System.out.println("****AtTargetAspect.crossCuttingCode() : "+ joinPoint.getSignature().getName()+ ": After Method Execution");}
}

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- (1)声明Context命名空间以及Schema文件   (2)扫描类包以及应用注解定义的bean -->
<context:component-scan base-package="com.xgj.aop.spring.advisor.aspectJ.function.attarget"/><!-- 基于@AspectJ切面的驱动器 -->
<aop:aspectj-autoproxy proxy-target-class="true"/><!-- 使用了@AspectJ注解的切面类 -->
<bean class="com.xgj.aop.spring.advisor.aspectJ.function.attarget.AtTargetAspect"/></beans>

测试代码

package com.xgj.aop.spring.advisor.aspectJ.function.attarget;import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class AtTargetAspectTest {private ApplicationContext ctx;@Testpublic void test() {ctx = new ClassPathXmlApplicationContext("classpath:com/xgj/aop/spring/advisor/aspectJ/function/attarget/conf-attarget.xml");C0 c0 = ctx.getBean("c0", C0.class);C1 c1 = ctx.getBean("c1", C1.class);C2 c2 = ctx.getBean("c2", C2.class);C3 c3 = ctx.getBean("c3", C3.class);// C0没有标注了@Mark,不会被织入增强c0.methodName();// C1标注了@Mark,会被织入增强c1.methodName();// C2标注了@Mark,会被织入增强c2.methodName();// C3没有标注了@Mark,不会被织入增强c3.methodName();}
}

运行结果:

2017-09-05 13:40:56,244  INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@c24cb3: startup date [Tue Sep 05 13:40:56 BOT 2017]; root of context hierarchy
2017-09-05 13:40:56,338  INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/aspectJ/function/attarget/conf-attarget.xml]
C0 method executed
****AtTargetAspect.crossCuttingCode() : methodName: Before Method Execution
C1 method executed
****AtTargetAspect.crossCuttingCode() : methodName: After Method Execution
****AtTargetAspect.crossCuttingCode() : methodName: Before Method Execution
C2 method executed
****AtTargetAspect.crossCuttingCode() : methodName: After Method Execution
C3 method executed

C1 和 C2标注了@Mark注解,可以看到成功的织入了@Around环绕增强


@within

自定义一个注解

package com.xgj.aop.spring.advisor.aspectJ.function.atwithin;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** * * @ClassName: Mark* * @Description: 自定义注解* * @author: Mr.Yang* * @date: 2017年9月5日 下午12:02:46*/@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface Mark2 {public String value() default "";}

4个注解声明的POJO Bean

package com.xgj.aop.spring.advisor.aspectJ.function.atwithin;import org.springframework.stereotype.Component;/*** * * @ClassName: C0* * @Description: @Component 标注的Bean* * @author: Mr.Yang* * @date: 2017年9月5日 下午1:36:37*/@Component
public class A0 {public void methodName() {System.out.println("A0 method executed \n");}
}
package com.xgj.aop.spring.advisor.aspectJ.function.atwithin;import org.springframework.stereotype.Component;/*** * * @ClassName: A1* * @Description: 标注了@Mark2,可以被增强* * @author: Mr.Yang* * @date: 2017年9月5日 下午6:02:21*/@Mark2
@Component
public class A1 extends A0 {public void methodName() {System.out.println("A1 method executed");}
}
package com.xgj.aop.spring.advisor.aspectJ.function.atwithin;import org.springframework.stereotype.Component;@Component
public class A2 extends A1 {public void methodName() {System.out.println("A2 method executed");}
}
package com.xgj.aop.spring.advisor.aspectJ.function.atwithin;import org.springframework.stereotype.Component;@Component
public class A3 extends A2 {public void methodName() {System.out.println("A3 method executed");}
}

切面 实现了Ordered接口

package com.xgj.aop.spring.advisor.aspectJ.function.atwithin;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.Ordered;/*** * * @ClassName: AtWithinAspect* * @Description: 标注了@Aspect 环绕增强切面* * @author: Mr.Yang* * @date: 2017年9月5日 下午1:53:40*/@Aspect
public class AtWithinAspect implements Ordered {@Around("@within(com.xgj.aop.spring.advisor.aspectJ.function.atwithin.Mark2)")public void crossCuttingCode(ProceedingJoinPoint joinPoint)throws Throwable {System.out.println("****AtWithinAspect.crossCuttingCode() : "+ joinPoint.getSignature().getName()+ ": Before Method Execution");try {joinPoint.proceed();} finally {// Do Something useful, If you have}System.out.println("****AtWithinAspect.crossCuttingCode() : "+ joinPoint.getSignature().getName()+ ": After Method Execution \n");}@Overridepublic int getOrder() {return 1;}}

配置文件


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- (1)声明Context命名空间以及Schema文件   (2)扫描类包以及应用注解定义的bean -->
<context:component-scan base-package="com.xgj.aop.spring.advisor.aspectJ.function.atwithin"/><!-- 基于@AspectJ切面的驱动器 -->
<aop:aspectj-autoproxy proxy-target-class="true"/><!-- 使用了@AspectJ注解的切面类 -->
<bean class="com.xgj.aop.spring.advisor.aspectJ.function.atwithin.AtWithinAspect"/></beans>

测试类

package com.xgj.aop.spring.advisor.aspectJ.function.atwithin;import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class AtWithinAspectTest {private ApplicationContext ctx;@Testpublic void test() {ctx = new ClassPathXmlApplicationContext("classpath:com/xgj/aop/spring/advisor/aspectJ/function/atwithin/conf-atwithin.xml");A0 a0 = ctx.getBean("a0", A0.class);A1 a1 = ctx.getBean("a1", A1.class);A2 a2 = ctx.getBean("a2", A2.class);A3 a3 = ctx.getBean("a3", A3.class);// A0没有标注@Mark,不会被织入增强a0.methodName();// A1标注了@Mark,会被织入增强a1.methodName();// A2没有标注@Mark,不会被织入增强a2.methodName();// A3没有标注@Mark,不会被织入增强a3.methodName();}
}

运行结果:

2017-09-05 18:04:01,685  INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@c24cb3: startup date [Tue Sep 05 18:04:01 BOT 2017]; root of context hierarchy
2017-09-05 18:04:01,793  INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/aspectJ/function/atwithin/conf-atwithin.xml]
A0 method executed ****AtWithinAspect.crossCuttingCode() : methodName: Before Method Execution
A1 method executed
****AtWithinAspect.crossCuttingCode() : methodName: After Method Execution A2 method executed
A3 method executed

注意事项

如果标注了@M注解的是一个接口,则所有实现该接口的类并不匹配@within(M) . 假设接口Waiter标注了@Mark注解,但是它的实现类NaiveWaiter、NaughtyWaiter这些接口实现类灭有标注@Mark, 则@within(com.xgj.Mark) 和 @target(com,xgj.Mark)都不匹配NaiveWaiter、NaughtyWaiter。 因为@within() @target() @annotation函数都是针对目标类而言的,而非针对运行时的引用类型而言。 需要特别注意。

验证过程见github中的 com.xgj.aop.spring.advisor.aspectJ.function.atwithin2

输出结果:

2017-09-05 18:11:18,171  INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@24b9371e: startup date [Tue Sep 05 18:11:18 BOT 2017]; root of context hierarchy
2017-09-05 18:11:18,285  INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/aspectJ/function/atwithin2/beans.xml]
NaughtyWaiter:greet to XiaoGong...
NaiveWaiter:greet to Jiang...

标注在接口上的@@Monitorable,使用within ,实现类中的方法并没有匹配

Spring-AOP @AspectJ切点函数之@within()和@target相关推荐

  1. Spring-AOP @AspectJ切点函数导读

    概述 annotation execution args和args within within和target target和this 概述 切点函数是AspectJ表达式语言的核心,也是使用@Aspe ...

  2. 关于 Spring AOP (AspectJ) 你该知晓的一切

    [版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/54629058 出自[zejian ...

  3. @AspectJ切点函数之execution()

    @AspectJ切点函数之execution() execution()是最常用的切点函数,语法如下: execution(<修饰符模式>?<返回类型模式><方法名模式& ...

  4. @AspectJ切点函数详解

    @AspectJ切点函数详解 1 方法切点函数 1.1 execution() 1.1.1 通过方法签名定义切点 1.1.2 通过类定义切点 1.1.3 通过类包定义切点 1.1.4 通过方法入参定义 ...

  5. Spring AOP + AspectJ Annotation Example---reference

    In this tutorial, we show you how to integrate AspectJ annotation with Spring AOP framework. In simp ...

  6. Spring AOP / AspectJ AOP 的区别?

    Spring AOP / AspectJ AOP 的区别? Spring AOP属于运行时增强,而AspectJ是编译时增强. Spring AOP基于代理(Proxying),而AspectJ基于字 ...

  7. 关于Spring AOP中切点修饰符@annotation、@args与args约束说明

    前言 于其说这是一篇文章,不如说这是一篇笔记,主要介绍了@annotation.@args和args的作用以及一些坑点.这里主要记录一些项目用到的,没有成一套体系,网上其他文章对Spring AOP的 ...

  8. 说说 Spring 支持的 AspectJ 切点函数

    1 @annotation() 它表示标注了某个注解的所有方法. 假设有一个接口 Cook,它有两个实现类 CookA.CookB: Cook: public interface Cook {/*** ...

  9. Spring-AOP @AspectJ切点函数之target()和this()

    文章目录 概述 实例 target() this() 概述 target()切点函数通过判断目标类是否按类型匹配指定类来决定连接点是否匹配. 用于匹配当前目标对象类型的执行方法:注意是目标对象的类型匹 ...

最新文章

  1. R语言可视化散点图(scatter plot)图、为图中的部分数据点添加标签、ggrepel包来帮忙
  2. 第6周第4课:复习及扩展知识
  3. python基础-字典的增删改查
  4. 算法每日学打卡:01-21打卡(解答后面整理)
  5. mysql 5.7.14-winx64_mysql-5.7.14-winx64 解压版本安装
  6. java 获取本机mac地址并转为字符串
  7. java nextline_使用新一代Java
  8. QT编程入门系列文章之六——API 文档的使用
  9. vs2010使用教程c语言编程,VS2010的使用
  10. 三星Galaxy S4 刷入CWM Recovery和获取ROOT教程
  11. Linux相对路径和绝对路径
  12. A 5G Odyssey :2021北京漫游
  13. Vue项目实战:订单列表页面实现
  14. 28年蛰伏,易特驰打响「软件定义汽车」硬战
  15. centos7.X系统初始化脚本
  16. [原创]TenJi Game-线下玩法技巧
  17. DataGridView 单击选中一整行,只能单选,不能选择多行,只能选择一行
  18. VN.PY量化框架创始人教你做量化交易
  19. ios 计算两个时间相差秒数_iOS NSDate时间换算
  20. Order-Independent Transparency

热门文章

  1. kibana. 登陆
  2. 单片机断电后不保存程序_为什么单片机语音芯片既有flash又有EEPROM
  3. python如何修改excel数据库_python学习笔记-day7-2-【python从mysql数据库导数据到excel,读excel,修改excel】...
  4. R语言应用实战-OLS模型算法原理及应用示例
  5. 听说你想去大厂看妹子,带你看看腾讯产品运营实习面经
  6. BloomFilter——大规模数据处理利器
  7. spider-定向抓取
  8. MapReduce编程实战之“I/O”
  9. 工具类软件操作手册_全套广联达软件学习资料合集:教程+实例讲解+操作手册,一文搞定...
  10. Python入门100题 | 第070题