该系列文章是本人在学习 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. go-admin在线开发平台学习-4[细节解析]

    紧接着上一期的内容,继续对go-admin的一些细节进行解析. 通用的增删改查方法 在go-admin/common/actions下封装了通用的增删改查方法.在对这些方法进行说明前,先移步到另一个文 ...

  2. Promise和async await详解

    本文转载自Promise和async await详解 Promise 状态 pending: 初始状态, 非 fulfilled 或 rejected. fulfilled: 成功的操作. rejec ...

  3. Angular的工作原理

    来源:https://www.cnblogs.com/moriah/p/6096998.html <!doctype html> <html ng-app> <head& ...

  4. 使用python编写量子线路打印的简单项目,并使用Sphinx自动化生成API文档

    技术背景 该文章一方面从量子线路的打印着手,介绍了一个简单的python量子线路工程.同时基于这个简单的小工程,我们顺带的介绍了python的API文档自动化生成工具Sphinx的基本使用方法. 量子 ...

  5. springboot对数据库密码加密

    第一步:maven引jar包 <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifa ...

  6. Windows定时重新启动(适用于server 2012 r2)

    直接看链接吧:https://jingyan.baidu.com/article/2d5afd69dd8e9d85a2e28eb7.html 开始菜单,找到"计划任务程序"; 2 ...

  7. 微信小程序(六)-项目实例(原生框架 MINA基配搭建)==01-头搜索框tabbar

    项目实例(原生框架 MINA) 1.新建小程序项目 1.用自已的小程序APPID 2.清除整理项目中初建默认无关的代码 1.app.json 中删除logs,同时删除pages下的losgs文件夹 2 ...

  8. Vue项目的创建、路由、及生命周期钩子

    目录 一.Vue项目搭建 1.环境搭建 2.项目的创建 3.pycharm配置并启动vue项目 4.vue项目目录结构分析 5.Vue根据配置重新构建依赖 二.Vue项目创建时发生了什么 三.项目初始 ...

  9. Prometheus时序数据库-数据的插入

    Prometheus时序数据库-数据的插入 前言 在之前的文章里,笔者详细的阐述了Prometheus时序数据库在内存和磁盘中的存储结构.有了前面的铺垫,笔者就可以在本篇文章阐述下数据的插入过程. 监 ...

  10. 如何在Bash脚本中引入alias

    更多精彩内容,请关注微信公众号:后端技术小屋 alias的使用 在日常开发中,为了提高运维效率,我们会用alias(命令别名)来定义命令的简称.比如在~/.bash_profile中添加: alias ...