1.Advisor的组成结构

在spring aop中Advisor是一个接口,代表被拦截方法需要增强的逻辑。
Advisor通常由另两个组件组成——Advice接口和Pointcut接口,其中Advice表示实际增强的逻辑入口,Pointcut表示哪些类或者哪些方法需要被拦截。

Advice

我们先看下Advice类体系图,下图是实现或者继承了Advice接口的组件

最上面一层的around、after等,代表我们在@Aspect的类中定义的各种通知方法类型。

Pointcut

Pointcut也是一个接口,包含如下方法

ClassFilter接口的作用是判断哪些类需要被拦截,MethodMatcher接口的作用是判断哪些方法需要被拦截,都是通过接口中的matches方法实现的。

2.收集对象的Advisor

在spring创建bean时,如果bean需要生成代理,那么spring会收集符合条件的所有Advisor。

1.收集已有的Advisor

下面是收集项目中已有Advisor的方法入口

第一个红框会收集实现了Advisor接口的类,这些类包括我们项目自定义的、事务advisor、缓存advisor等。
第二个红框会收集注解@Aspect类中定义的around、before等通知方法,将其包装为Advisor。
这些都是已存在的Advisor。

2.拓展Advisor
经过上述过程,Advisor集合已经有了元素。之后spring会进入如下红框处的方法 ,
该方法会加入新的advisor——DefaultPointcutAdvisor,并放入集合的最前面。
DefaultPointcutAdvisor的Advice是ExposeInvocationInterceptor类,作用是在调用代理对象方法时,将相关信息存入ThreadLocal,以在多个advisor间进行传递。

3.加入自定义的MethodInterceptor

经过上面两步,spring会开始生成代理对象了,代码如下
红框处会将自定义的MethodInterceptor接口实现类也包装为advisor,并放入advisor集合的最前面。

自定义MethodInterceptor实战见博文

  • spring aop自定义MethodInteceptor实现类

3.Advisor的排序

收集到多个Advisor之后,spring会进行排序。具体排序逻辑本文不做具体分析,只说结论:

假设集合里有before、after、afterThrowing、afterRetruning、around5种通知,以及上面提到的ExposeInvocationInterceptor,则排序后顺序为

在调用代理对象方法时,也是按照这个顺序调用advisor。

4.自定义Advisor实战

通过上面的分析,我们来自定义一个Advisor,功能是拦截方法有@Hero注解的类,并生成代理。

1.自定义注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Hero {}

2.自定义MethodMatcher

判断方法上是否有@Hero注解,如有则符合pointcut的条件。

public class CustomMethodMatcher implements MethodMatcher {@Overridepublic boolean matches(Method method, Class<?> aClass) {Method specificMethod = AopUtils.getMostSpecificMethod(method, aClass);boolean res = specificMethod.isAnnotationPresent(Hero.class);if(res){return true;}return false;}@Overridepublic boolean isRuntime() {return false;}@Overridepublic boolean matches(Method method, Class<?> aClass, Object... objects) {return false;}
}

这里我们通过AopUtils.getMostSpecificMethod(method, aClass);先拿到Method,然后再去拿注解信息。
为什么不直接用方法的参数method,通过method.isAnnotationPresent来判断呢?
除了收集advisor时会进入MethodMatcher的方法,在调用JdkDynamicAopProxy的invoke方法时,spring为了排除没必要拦截的方法,也会进入MethodMatcher的方法。
问题在于,此时我们的method是接口的方法,而不是实现类的方法,而接口方法是没有注解的,所以此时method.isAnnotationPresent拿不到,spring就不会用到对应的Advisor。
AopUtils.getMostSpecificMethod(method, aClass);是不管如何都可以拿到注解信息的,可以确保万无一失。

3.自定义Pointcut

这里ClassFilter我们直接返回true,表示所有类都匹配

public class CustomPointCut implements Pointcut {@Overridepublic ClassFilter getClassFilter() {return ClassFilter.TRUE;}@Overridepublic MethodMatcher getMethodMatcher() {return new CustomMethodMatcher();}
}

4.自定义Advice
CustomMethodInterceptor 处理实际业务逻辑

public class CustomMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation methodInvocation) throws Throwable {System.out.println("CustomMethodInterceptor");return methodInvocation.proceed();}
}

5.自定义Advisor
拥有advice和pointcut之后,我们就可以创建Advisor了

@Component
public class CustomAdvisor implements PointcutAdvisor {@Overridepublic Pointcut getPointcut() {return new CustomPointCut();}@Overridepublic Advice getAdvice() {return new CustomMethodInterceptor();}@Overridepublic boolean isPerInstance() {return false;}
}

6.service接口

public interface TestService {void test();
}@Service
public class TestServiceImpl implements TestService{@Override@Heropublic void test() {System.out.println("test");}
}

项目启动时,spring就会针对有@Hero注解的TestServiceImpl类生成代理,代理中拥有CustomAdvisor。

聊聊spring aop中的advisor组件相关推荐

  1. Spring AOP中Pointcut,dvice 和 Advisor三个概念

    Spring  AOP中Pointcut,dvice 和 Advisor三个概念介绍 在理解了Spring的AOP后,需要重点理解的三个概念是:Pointcut    Advice   Advisor ...

  2. Spring AOP中是如何注册Advisor的?

    前置博文: Spring AOP中如何为Bean创建代理? Spring AOP中是如何注册Advisor的? Spring AOP如何为目标方法创建拦截器链? Spring AOP拦截器调用的实现 ...

  3. J2EE中使用Spring AOP框架和EJB组件(1)

    J2EE中使用Spring AOP框架和EJB组件(1) [@more@]本文介绍了一种把J2EE应用程序中的EJB转换为Spring托管组件的方法,以及转换之后可以采用的强大技术.它还给出了几个实际 ...

  4. J2EE中使用Spring AOP框架和EJB组件(6)

    J2EE中使用Spring AOP框架和EJB组件(6) [@more@] 组合和链接通知 我们已经使用了一个简单的拦截器通知来实现附加的逻辑,并且将其当作一个独立的组件进行了测试.当应该在不进行修改 ...

  5. [转载]使用SPRING AOP框架和EJB组件

    使用SPRING AOP框架和EJB组件 摘要 快速发展的开发人员社区.对各种后端技术(包括JMS.JTA.JDO. Hibernate.iBATIS等等)的支持,以及(更为重要的)非侵入性的轻量级I ...

  6. Spring AOP 中的切点是什么?如何定义切点?

    Spring AOP 中的切点是什么?如何定义切点? 什么是切点? 在 Spring AOP 中,切点(Pointcut)是指一组连接点(Join Point)的集合.连接点是程序执行过程中的某个特定 ...

  7. Spring AOP中pointcut 切点详解

    Spring AOP中pointcut 是指那些方法需要被执行"AOP",是由"Pointcut Expression"来描述的. Pointcut可以有下列方 ...

  8. java方法设置切点_java相关:Spring AOP中定义切点的实现方法示例

    java相关:Spring AOP中定义切点的实现方法示例 发布于 2020-6-6| 复制链接 摘记: 本文实例讲述了Spring AOP中定义切点的实现方法.分享给大家供大家参考,具体如下:一 配 ...

  9. Spring AOP中定义切点(PointCut)和通知(Advice)

    本文讨论一下Spring AOP编程中的两个关键问题,定义切点和定义通知,理解这两个问题能应付大部分AOP场景. 如果你还不熟悉AOP,请先看AOP基本原理,本文的例子也沿用了AOP基本原理中的例子. ...

最新文章

  1. POS主密钥与工作密钥关联详解
  2. centos 7 构造iptables开放80port
  3. python数据可视化是什么_Python数据分析:可视化
  4. installshield 脚本 在卸载过程执行_Linux下运行Jmeter脚本
  5. 对于Vue组件的初步认识(未整理)
  6. 使用Windows Server 2003搭建一个asp+access网站
  7. 【ActiveMQ】ActiveMQ在CentOS的搭建与使用
  8. 元素exist/present/visible(vanish)/enable的区别
  9. python教程视频-有没有适合零基础小白学的python教程,视频或者书籍都可以?
  10. timerfd.h中定义的函数
  11. Java 软件实践 VZone PPT Show 一次及其Perfect的演示
  12. Mydumper 多线程备份工具
  13. 鸿基酒店应收应付报表生成系统
  14. 天天QQ记牌器2.37 去广告绿色版
  15. HTML页面调用打印机打印pdf文件
  16. CSS 中的@media
  17. iOS加速器简单介绍
  18. 民间53个不传之密 ,看了不后悔
  19. SpringCloud入门总结 + 使用SpringCloud搭建微服务项目
  20. CF #768 F.Flipping Range

热门文章

  1. [SRS+docker]实现直播服务器 8 云产商直播服务
  2. 数字农业 WMS 库存操作重构及思考
  3. FreeBSD可以安装Linux软件吗,在Linux服务器上面通过网络安装FreeBSD
  4. java打印空心菱形
  5. C语言打印空心三角形代码
  6. java多线程游戏设计-弹球游戏(包含全部代码)
  7. 《计算机程序设计艺术》作者高德纳
  8. PSD统一身份认证登录系统模板
  9. 闲扯WPS Office 2005
  10. Tomcat,Jdk配置、安装及安装完成后常见问题教程(手把手教)