死磕Spring之AOP篇 - Spring AOP自动代理(一)入口
该系列文章是本人在学习 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 进行处理,例如:
在 Bean 的实例化前,会调用
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation(..)方法进行处理在 Bean 出现循环依赖的情况下,会调用
SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference(..)方法对提前暴露的 Bean 进行处理在 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-aop 和 aspectjweaver 两个模块,然后通过下面的方式开启 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 {}
}
只要存在 EnableAspectJAutoProxy、Aspect、Advice、AnnotatedElement 四个 Class 对象,且 spring.aop.auto 配置为 true(没有配置则为 true),那么就会加载 AopAutoConfiguration 当前这个 Bean,而内部又使用了 @EnableAspectJAutoProxy 注解,那么表示开启 AOP。
至于这个注解或者 XML 配置的方式为什么就开启 AOP,是因为会引入 AbstractAutoProxyCreator 这个对象,具体怎么引入的,在后续文章进行分析
死磕Spring之AOP篇 - Spring AOP自动代理(一)入口的更多相关文章
- 死磕Spring之AOP篇 - Spring AOP常见面试题
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- 死磕Spring之AOP篇 - Spring AOP自动代理(二)筛选合适的通知器
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- 死磕Spring之AOP篇 - Spring AOP自动代理(三)创建代理对象
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- 死磕Spring之AOP篇 - Spring AOP注解驱动与XML配置
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- 白话Spring(基础篇)---AOP(execution表达式)
作为AOP的最后一节内容,我们来简单总结一下切面表达式上见的书写方法.下面的那内容有参考其他博文,在此先对开源博客的各位大神表示感谢! -------------------------------- ...
- 白话Spring(基础篇)---AOP(execution表达式)(转)
[一知半解,就是给自己挖坑] 作为AOP的最后一节内容,我们来简单总结一下切面表达式上见的书写方法.下面的那内容有参考其他博文,在此先对开源博客的各位大神表示感谢! ----------------- ...
- Spring第12篇—— Spring对Hibernate的SessionFactory的集成功能
由于Spring和Hibernate处于不同的层次,Spring关心的是业务逻辑之间的组合关系,Spring提供了对他们的强大的管理能力, 而Hibernate完成了OR的映射,使开发人员不用再去关心 ...
- 死磕Spring之AOP篇 - Spring AOP总览
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- 死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
随机推荐
- 「NGK每日快讯」12.3日NGK公链第30期官方快讯!
- ROS 安装完成后运行小乌龟示例程序
安装ROS成功后,在Beginner Tutorials中有一个简单的示例程序. 在Terminal中运行以下命令: $ roscore 新开一个terminal,运行以下命令,打开小乌龟窗口: $ ...
- C++算法代码——鹅卵石游戏
题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=2334 题目描述 为了消磨时光,奶牛Bessie和她的朋友Elsie喜欢玩一种她们在农 ...
- 页面导入导出EXCEL
引用 using Microsoft.Office.Interop.Excel;using System.Reflection;//反射命名空间using System.IO; protected v ...
- MPAndroidChart实现LineChart(折线图)
一.参照油管视频做法 1.引入依赖 新建Android工程,然后分别在build.gradle(Project:...)添加 maven { url 'https://jitpack.io' } 在b ...
- java实现压缩文件
原文链接:https://www.cnblogs.com/zeng1994/p/7862288.html
- smart-adminx项目导入依赖时,点击reinport时没反应且依赖全部报红的解决办法
依赖报红的解决办法 报红效果如下: 原因分析:下载jar包时,出现大量以.lastUpdated结尾的无效文件. 解决办法:使用bat批处理文件批量删除无效文件 set REPOSITORY_PATH ...
- Java基本概念:异常
一.简介 描述: 异常(Exception)指不期而至的各种状况,异常发生的原因有很多,通常包含以下几大类: 用户输入了非法数据. 要打开的文件不存在. 网络通信时连接中断,或者JVM内存溢出. 异常 ...
- docker mysql数据备份xtrabackup
一.概述 线上有一个mysql,是在docker里面运行的. 关于docker封装mysql镜像,请参考链接:https://www.cnblogs.com/xiao987334176/p/11984 ...
- Docker Hub 镜像加速器
一.概述 国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器.Docker 官方和国内很多云服务商都提供了国内加速器服务. 二.配置加速地址 Ubuntu 16.04+.De ...