文章目录

  • 1. 前言
  • 2. 代理示例
  • 3. 问题分析
  • 4. 结尾

1. 前言

AOP,英文全称是Aspect Oriented Programming,也叫作面向切面编程。预先定义一个或多个切入点,当程序执行到切点的方法时,会先执行切面相关处理逻辑,再执行原程序代码。

注:本篇文章会结合Spring生命周期源码,介绍AOP是如何整合到Sping容器管理。不会过多地介绍一些基础知识,阅读之前,最好对AOP、CGLIB、Proxy有个基础的了解。

Spring通过动态代理实现AOP,用语言表述可能不大清楚,下面画一张图来对比一下

2. 代理示例

  • 1.创建Service接口:
public interface MyService {void test();
}
  • 2.创建ServiceImpl实现类,记得加 @Service 注解,表示由Spring容器管理:
@Service
public class MyServiceImpl implements MyService {@Autowiredprivate A a;@Overridepublic void test() {System.out.println("调用MyService.test");;}@PostConstructpublic void init(){System.out.println("MyServiceImpl PostConstruct");}
}
  • 3.创建一个@Component标记的常规类:
@Component
public class A {public void test(){System.out.println("a.test...");}
}
  • 4.创建启动类,注意看这时候没有加注解 @EnableAspectJAutoProxy ,因此Spring不会启用AOP功能:
@ComponentScan("com.example")
public class App {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(App.class);A a = ac.getBean(A.class);a.test();System.out.println(a.getClass());System.out.println("------------------------------------------");MyService service = ac.getBean(MyService.class);service.test();System.out.println(service.getClass());}
}
  • 5.执行程序,输出结果如下。此时,所有的类都是普通的JAVA对象:
MyServiceImpl PostConstruct
a.test...
class com.example.demo.A
------------------------------------------
调用MyService.test
class com.example.service.impl.MyServiceImpl
  • 6.接下来,准备实现AOP了。在前面的基础上,创建“切面类” TestAspect:
@Component
@Aspect
public class TestAspect {//这里通过通配符,表示之前的A类和MyServiceImpl类都会被代理。//具体的@Pointcut配置可以查看官网https://docs.spring.io/spring-framework/docs/5.2.13.RELEASE/spring-framework-reference/core.html#spring-core@Pointcut("execution(* com.example.*.*.*(..))")public void myPointCut(){}@Before("myPointCut()")public void before(){System.out.println("before");}
}
  • 7.在启动类增加 @EnableAspectJAutoProxy 注解,然后重新运行程序,新的执行结果如下。此时,A对象变成CGLIB创建的动态代理对象,而service变成JDK创建的动态代理对象:
MyServiceImpl PostConstruct
before
a.test...
class com.example.demo.A$$EnhancerBySpringCGLIB$$7c975a0a
------------------------------------------
before
调用MyService.test
class com.sun.proxy.$Proxy23

3. 问题分析

问题1:Spring在什么时机点进行AOP处理?

答案1:

  • 在创建Bean对象之后,调用后置处理器方法AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization()创建动态代理实现

看下面这张图,描述了Bean创建的过程和AOP的调用时机

问题2:上一步提的处理器AnnotationAwareAspectJAutoProxyCreator没有加@Component注解,为什么能被Spring扫描到并起作用?

答案2:----------------------------------------------------------------------------------------

  • Spring AOP生效必须加注解@EnableAspectJAutoProxy,该注解使用@Import将AspectJAutoProxyRegistrar加入了Spring容器

  • AspectJAutoProxyRegistrar是实现ImportBeanDefinitionRegistrar接口的处理器,在Spring扫描类的过程中,会调用所有实现类的 registerBeanDefinitions 方法

  • AspectJAutoProxyRegistrar#registerBeanDefinitions() 将 AnnotationAwareAspectJAutoProxyCreator 加入了 Spring 容器

问题3:Spring采用哪种动态代理机制,CGLIB还是JDK?

答案3:----------------------------------------------------------------------------------------

  • 默认情况下,实现了业务接口的Bean会采用JDK动态代理,例如:ServiceImpl。其他情况下,一般会采用CGLIB动态代理。
  • 设置注解 @EnableAspectJAutoProxy 的属性 proxyTargetClass = true,会强制 CGLIB 动态代理

修改之前的例子,使用注解 @EnableAspectJAutoProxy(proxyTargetClass = true) ,重新运行程序,执行结果如下:

MyServiceImpl PostConstruct
before
a.test...
class com.example.demo.A$$EnhancerBySpringCGLIB$$7c975a0a
------------------------------------------
before
调用MyService.test
class com.example.service.impl.MyServiceImpl$$EnhancerBySpringCGLIB$$98d88524

看吧… 全部变成CGLIB创建的代理对象

4. 结尾

本篇的AOP基本原理就介绍到这里了,后面有新的想法会不断补充,也欢迎大家提出新的见解。

Spring AOP实现原理解析相关推荐

  1. Spring AOP实现原理,从代理说起

    前言 为了理解Spring AOP,我们先来了解一下Java的代理模式 什么是代理? 举个例子来说明代理的作用: 假设我们想邀请一位明星,那么并不是直接联系明星,而是联系明星的经纪人,来达到同样的目的 ...

  2. spring ioc di 原理解析

    spring ioc原理(看完后大家可以自己写一个spring) 控制反转/依赖注入 其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述的那样晦涩.Java程序员都知道:java程序中 ...

  3. spring注解驱动开发-6 Spring AOP实现原理

    Spring AOP实现原理 前言 1.@EnableAspectJAutoProxy注解原理 2.AnnotationAwareAspectJAutoProxyCreator 分析 1.分析前工作, ...

  4. Spring AOP源码解析-拦截器链的执行过程

    一.简介 在前面的两篇文章中,分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在得到了 bean 的代理对象,且通知也以合适的方式插在了目标方 ...

  5. ppst——技术视频spring AOP 的原理讲解和简单实现

    ppst 技术视频--spring AOP 的原理讲解和简单实现:请访问ppst 技术视频分享平台 , www.ppst.cc,上面有最新的技术视频,推荐大家把博客录制成视频吧,可以获取收益哦 1.s ...

  6. 灵魂画手图解Spring AOP实现原理!

    本篇旨在让读者对Spring AOP实现原理有一个宏观上的认识,因此会丢失一些细节,具体实现参考:老实人Spring源码目录 阅读本篇文章前,希望读者对Spring Ioc以及Spring AOP的使 ...

  7. Spring AOP源码解析——AOP动态代理原理和实现方式

    2019独角兽企业重金招聘Python工程师标准>>> Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和 ...

  8. spring aop实现原理_Spring 异步实现原理与实战分享

    最近因为全链路压测项目需要对用户自定义线程池 Bean 进行适配工作,我们知道全链路压测的核心思想是对流量压测进行标记,因此我们需要给压测的流量请求进行打标,并在链路中进行传递,那么问题来了,如果项目 ...

  9. 【Spring】Spring底层核心原理解析

    本文内容索引: 1.Bean的生命周期底层原理 2.依赖注入底层原理 3.初始化底层原理 4.推断构造方法底层原理 5.AOP底层原理 6.Spring事务底层原理 ​但都只是大致流程,后续会针对每个 ...

最新文章

  1. Oracle Eneterprise Linux 5.8上安装Database 12c
  2. 以往计算机二级c语言填空题,计算机二级C语言考试填空题精选4
  3. 君正T20平台生成jffs2格式rootfs
  4. python装好了怎么启动车_【填空题】Python安装好后,可以直接在CMD命令行下输入( )命令, 可启动交互式编程,提示窗口如下:...
  5. 第16届电源技术专题研讨会
  6. 帆软报表数据库配置及关系
  7. 如何把DEBIAN变成UBUNTU-DESKTOP最少化安装
  8. Windows 批处理(bat)语法大全、BAT批处理基本命令总结
  9. 服务器接显示器重影,学生能够选择影音服务器中的考试试卷进行自测测试结束系统将自动批阅并显示标.doc...
  10. win7 计算机设置命令,Win7设置开机启动项命令的方法
  11. leetcode 376. 摆动序列(三种解法)
  12. 双活数据中心概念及优缺点介绍
  13. 2022UI自动化测试框架搭建 —— yaml文件管理定位元素
  14. 九键字母组合-深度优先遍历DFS
  15. 计算机机型分pc机和什么,三种等分的电脑打印纸一般指什么尺寸
  16. LDPC译码:和积译码算法(SPA)、最小和算法(MSA)、分层译码算法(LBP)、动态信息更新策略IDS(含RBP、NW-RBP、SVNF-RBP)的MATLAB实现
  17. 基站频谱扫描-高性能扫频仪 TFN FGT720A
  18. 概率论与数理统计学习笔记——第13讲——依概率收敛的意义
  19. lisp 图元 天正 自定义_AutoLISP查询图元信息
  20. Python实现undo操作

热门文章

  1. SAP附件清单的调用
  2. SAP 批次管理(Batch management)
  3. DYNP_VALUES_READ
  4. 猫眼娱乐2020年上半年交出最差答卷,下半年能满血复活吗?
  5. “家电第一股”美的集团迎来转折期?
  6. 为什么牛在天上飞 因为有人在地上吹 谈高德地图说日活过亿
  7. mysql截取最后一个斜杠_在MySQL中最后一个斜杠之后选择文本?
  8. html中的js作用,javascript中的innerHTML属性有什么作用
  9. sql 2008服务器响应慢,SQL Server 2008停止响应后,Web服务器不活动
  10. 计算机基础ABCDEF,计算机应用基础-在线作业abcdef(76页)-原创力文档