该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读。

Spring 版本:5.1.14.RELEASE

在开始阅读 Spring AOP 源码之前,需要对 Spring IoC 有一定的了解,可查看我的 《死磕Spring之IoC篇 - 文章导读》 这一系列文章

了解 AOP 相关术语,可先查看 《Spring AOP 常见面试题) 》 这篇文章

该系列其他文章请查看:《死磕 Spring 之 AOP 篇 - 文章导读》

通过上一篇文章《Spring AOP 总览》我们对 Spring AOP 有了一个整体的认识,那么从本篇文章开始,我们一起来看看 Spring AOP 和 Spring IoC 是如何整合的,自动代理的过程做了哪些事情?

首先我们得清楚 Bean 的加载过程,整个过程中会调用相应的 BeanPostProcessor 对正在创建 Bean 进行处理,例如:

  1. 在 Bean 的实例化前,会调用 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation(..) 方法进行处理

  2. 在 Bean 出现循环依赖的情况下,会调用 SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference(..) 方法对提前暴露的 Bean 进行处理

  3. 在 Bean 初始化后,会调用 BeanPostProcessor#postProcessAfterInitialization(..) 方法对初始化好的 Bean 进行处理

Spring AOP 则是通过上面三个切入点进行创建代理对象,实现自动代理

  • 在 Spring AOP 中主要是通过第 3 种 BeanPostProcessor 创建代理对象,在 Bean 初始化后,也就是一个“成熟态”,然后再尝试是否创建一个代理对象;
  • 2 种方式是为了解决 Bean 循环依赖的问题,虽然 Bean 仅实例化还未初始化,但是出现了循环依赖,不得不在此时创建一个代理对象;
  • 1 种方式是在 Bean 还没有实例化的时候就提前创建一个代理对象(创建了则不会继续后续的 Bean 的创建过程),例如 RPC 远程调用的实现,因为本地类没有远程能力,可以通过这种方式进行拦截。

对于 Bean 的加载过程不清楚的小伙伴可以查看我的《死磕Spring之IoC篇 - 文章导读》这篇文章,或者直接查看《死磕Spring之IoC篇 - Bean 的创建过程》 这篇文章

Spring AOP 自动代理的实现主要由 AbstractAutoProxyCreator 完成,它实现了 BeanPostProcessor、SmartInstantiationAwareBeanPostProcessor 和 InstantiationAwareBeanPostProcessor 三个接口,那么这个类就是 Spring AOP 的入口,在这里将 Advice 织入我们的 Bean 中,创建代理对象。

如何激活 AOP 模块?

如何开启 Spring 的 AOP 模块,首先我们需要引入 spring-aopaspectjweaver 两个模块,然后通过下面的方式开启 AOP:

  • 添加 @EnableAspectJAutoProxy 注解
  • 添加 <aop:aspectj-autoproxy /> XML 配置

备注:在 Spring Boot 中使用 AOP 可以不需要上面两种配置,因为在 Spring Boot 中当你引入上面两个模块后,默认开启,可以看到下面这个配置类:

package org.springframework.boot.autoconfigure.aop;

@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration { @Configuration
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
public static class JdkDynamicAutoProxyConfiguration {} @Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
public static class CglibAutoProxyConfiguration {}
}

只要存在 EnableAspectJAutoProxyAspectAdviceAnnotatedElement 四个 Class 对象,且 spring.aop.auto 配置为 true(没有配置则为 true),那么就会加载 AopAutoConfiguration 当前这个 Bean,而内部又使用了 @EnableAspectJAutoProxy 注解,那么表示开启 AOP。

至于这个注解或者 XML 配置的方式为什么就开启 AOP,是因为会引入 AbstractAutoProxyCreator 这个对象,具体怎么引入的,在后续文章进行分析

死磕Spring之AOP篇 - Spring AOP自动代理(一)入口的更多相关文章

  1. 死磕Spring之AOP篇 - Spring AOP常见面试题

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

  2. 死磕Spring之AOP篇 - Spring AOP自动代理(二)筛选合适的通知器

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

  3. 死磕Spring之AOP篇 - Spring AOP自动代理(三)创建代理对象

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

  4. 死磕Spring之AOP篇 - Spring AOP注解驱动与XML配置

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

  5. 白话Spring(基础篇)---AOP(execution表达式)

    作为AOP的最后一节内容,我们来简单总结一下切面表达式上见的书写方法.下面的那内容有参考其他博文,在此先对开源博客的各位大神表示感谢! -------------------------------- ...

  6. 白话Spring(基础篇)---AOP(execution表达式)(转)

    [一知半解,就是给自己挖坑] 作为AOP的最后一节内容,我们来简单总结一下切面表达式上见的书写方法.下面的那内容有参考其他博文,在此先对开源博客的各位大神表示感谢! ----------------- ...

  7. Spring第12篇—— Spring对Hibernate的SessionFactory的集成功能

    由于Spring和Hibernate处于不同的层次,Spring关心的是业务逻辑之间的组合关系,Spring提供了对他们的强大的管理能力, 而Hibernate完成了OR的映射,使开发人员不用再去关心 ...

  8. 死磕Spring之AOP篇 - Spring AOP总览

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

  9. 死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

随机推荐

  1. Java基本概念:多态

    一.简介 描述: 多态性是面向对象编程中的一个重要特性,主要是用来实现动态联编的.换句话说,就是程序的最终状态只有在执行过程中才被决定,而非在编译期间就决定了.这对于大型系统来说能提高系统的灵活性和扩 ...

  2. c++中深层复制(浅层复制运行错误)成功运行-----sample

    下面随笔给出c++中深层复制(浅层复制运行错误)成功运行------sample. 浅层复制与深层复制 浅层复制 实现对象间数据元素的一一对应复制. 深层复制 当被复制的对象数据成员是指针类型时,不是 ...

  3. Jacobi与SOR迭代法的实现与性能比较及均匀间距与Chebyshev插值的实现、性能分析及二者生成的插值误差比较

    这篇文章给出(1)Jacobi与SOR迭代法的实现与性能比较及(2)均匀间距与Chebyshev插值的实现.性能分析及二者生成的插值误差比较,给出完整的实现代码,没有进行性能优化,仅供参考. (1)J ...

  4. 医学图像 | DualGAN与儿科超声心动图分割 | MICCAI

    文章转自微信公众号:「机器学习炼丹术」 作者:炼丹兄(已授权) 联系方式:微信cyx645016617(欢迎交流共同进步) 论文名称:"Dual Network Generative Adv ...

  5. 剑指 Offer 60. n个骰子的点数 + 动态规划 + 空间优化

    剑指 Offer 60. n个骰子的点数 Offer_60 题目详情 题解分析 package com.walegarrett.offer; /** * @Author WaleGarrett * @ ...

  6. HDOJ-6621(线段树+二分法)

    K-th Closest Distance HDOJ-6621 本题可以使用线段树解决,结点存本结点对应的所有元素,并按照从小打到排序 最后使用二分法求解答案.因为题目中有绝对值,所以需要使用两次查找 ...

  7. 【DB宝42】MySQL高可用架构MHA+ProxySQL实现读写分离和负载均衡

    目录 一.MHA+ProxySQL架构 二.快速搭建MHA环境 2.1 下载MHA镜像 2.2 编辑yml文件,创建MHA相关容器 2.3 安装docker-compose软件(若已安装,可忽略) 2 ...

  8. mysql-canal-rabbitmq 安装部署教程

    原文 1.1. 开启 MySQL 的 binlog 日志 修改 my.cnf 或 my.ini(windows), 添加配置项: # binlog 日志存放路径 log-bin=D:\env\mysq ...

  9. 关于PHP的isset()函数

      1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 <meta cha ...

  10. Java基础:常用基础dos命令

    打开cmd的方式1.开始+系统+命令提示符2.win键+R 输入cmd 打开控制台3.在任意的文件夹下,按住shift键+鼠标右键点击,在此处打开命令提示行4.在资源管理器的地址栏前面加上cmd路径 ...