Spring AOP : 自动代理创建机制 (APC)_spring为什么会有多个apc-程序员宅基地

技术标签: spring  Spring AOP  

有时候我们会遇到相似bean定义的情况: 这些bean需要被同样的一组拦截器包裹 。如果需要这样定义的bean数量很大,那么我们需要写大量重复度很高的xml配置行或者配置代码来定义这些bean,这显然是个可以优化解决的问题。为此,Spring AOP提供了自动代理创建机制。该机制通过往容器中添加一个APC来完成该任务。一个APC其实是一个SmartInstantiationAwareBeanPostProcessor,它会介入每个bean的实例化和初始化,检测bean的特征,如果该bean符合某些特征,比如有拦截器需要应用到该bean,那么该APC就会为它自动创建一个代理对象,使用相应的拦截器包裹住该bean

Spring AOP相应的APC实现机制中,首先,框架内置实现了三个自动代理创建器(auto proxy creator,缩写为APC):

实现类 优先级
InfrastructureAdvisorAutoProxyCreator 0 – 最低优先级
AspectJAwareAdvisorAutoProxyCreator 1
AnnotationAwareAspectJAutoProxyCreator 2 – 最高优先级

以上信息可以参考 AopConfigUtils.APC_PRIORITY_LIST静态属性定义。

其次,Spring AOP提供了将这些APC注册到容器中的ImportBeanDefinitionRegistrar,比如AspectJAutoProxyRegistrar,AutoProxyRegistrar等等。这些ImportBeanDefinitionRegistrar进而被框架定义的@Enable*注解所使用,这里可以参考:

@Enable*注解 使用到的APC bean注册器
@EnableAspectJAutoProxy 直接导入AspectJAutoProxyRegistrar
@EnableGlobalMethodSecurity 间接导入AutoProxyRegistrar
@EnableReactiveMethodSecurity 间接导入AutoProxyRegistrar
@EnableTransactionManagement 间接导入AutoProxyRegistrar
@EnableCaching 间接导入AutoProxyRegistrar

最后,开发者,或者框架的某个部分,会引用上面所提到的@Enable*注解,从而导致APC注册器向容器登记相应的APC bean。进而容器启动时,APC机制就开始为我们提供服务解决文章开篇所提到的问题了。

另外,需要注意的是,在同一个Spring IoC容器中,最多只会注册一个APC bean,但实际上,容器启动过程中可能有多处在向容器注册APC bean,所使用的实现类可能是以上三者之一。那么容器最终会使用哪个APC实现类呢 ?这一点可以参考框架真正的APC bean注册逻辑AopConfigUtils#registerAutoProxyCreatorIfNecessary。简单来讲,每次APC注册行为逻辑是这样的 :

  • 检测是否存在已经注册的APC bean定义;
    1. 不存在, 则执行APC bean定义注册逻辑;
    2. 存在, 则
      • 即将注册的APC类优先级较高,则会使用这次注册的APC类代理已注册APC bean定义中的bean class
      • 即将注册的APC类优先级较低,则什么都不做,直接返回;
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/andy_zhang2007/article/details/96339148

智能推荐

oracle 回滚段快照过旧,关于快照过旧和无法扩展回滚段-程序员宅基地

文章浏览阅读814次。相信很多人都见过这样的错误,通常是一个程序运行了很久很久,突然报一个快照过旧的红色错误。那么什么叫作快照过旧呢?它是如何产生的呢?我们应当如何避免呢?快照过旧是指Oracle尝试读取一个过去时间点的表的数据,然而这些数据已经不在回滚段中存在了。为什么会有这种情况呢?这要牵涉到Oracle独特的多版本特性,它会通过回滚段来保证读数据的一致性:Oracle读取的数据,总是某一个时间点的表数据,无论后面..._快照过旧 回退段号42

使用QSerialPort内存不断增长以及原因剖析_qt程序内存只增不减-程序员宅基地

文章浏览阅读2.5k次,点赞2次,收藏13次。从Qt源码的角度分析QSerialPort可能存在的内存不断增长的原因。_qt程序内存只增不减

Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE.-程序员宅基地

文章浏览阅读2.9k次,点赞2次,收藏3次。完整的报错日志:ERROR 2019-09-24 09:27:23,160 scheme:https path:/asset/api/interface/ method:POST data:<QueryDict: {}>Traceback (most recent call last): File "/code/asset_apps/main/views/error_Trace..._request body exceeded settings.data_upload_max_memory_size.

Fiddler 抓包下载 M3U8 视频_fiddler抓包,拿m3u8,然后n_m3u8dl-cli拉回来-程序员宅基地

文章浏览阅读8.6k次,点赞7次,收藏40次。本文以下载钉钉的直播回放视频为例,介绍如何下载 M3U8 视频。_fiddler抓包,拿m3u8,然后n_m3u8dl-cli拉回来

TAO使用指南 -- 编译ACE和TAO_vs2013编写tao-程序员宅基地

文章浏览阅读5.7k次。使用的环境是: WinXP Professional + MSVC SP5TAO完全支持Win32API,(包括Windows NT, Windows 2000, Windows 95/98/ME)VC5.0和VC6.0均可编译。一. Win32+VC6.0下编译和安装ACE和TAO将网上下载的TAO软件包解压缩到某个目录,在该目录下会有ACE_wrappers目录。请按照以下步骤来执行:_vs2013编写tao

osg示例程序解析2---osganimationeasemotion_inoutexpomotion-程序员宅基地

文章浏览阅读1.1k次。本文参考文章http://blog.csdn.net/yungis/article/details/8463077#include #include #include #include #include #include #include #include #include #include #include #include class Eas_inoutexpomotion

随便推点

ScrollView中设置子控件填充满ScrollView_scrollview 允许子容器填充-程序员宅基地

文章浏览阅读3.1k次。之前写了一个水平的ScrollView,想在里面加一个LinearLayout,并填充满父控件,但是发现无论如何LinearLayout都不能填充满ScrollView,后来找到了方法Mark一下:只要在ScrollView中加上一个android:fillViewport="true"就解决了。可以看出ScrollView里面的子控件是自适应大小的。_scrollview 允许子容器填充

API设计:Swagger, Blueprint和RAML_swagger与raml的区别-程序员宅基地

文章浏览阅读2.6k次。SwaggerSwagger与RAML相比,RAML解决的问题是设计阶段的问题,而Swagger则是侧重解决现有API的文档问题,它们最大的不同是RAML需要单独维护一套文档,而Swagger则是通过一套反射机制从代码中生成文档,并且借助ajax可以直接在文档中对API进行交互。因为代码与文档是捆绑的所以在迭代代码的时候,就能方便的将文档也更新了。不会出现随着项目推移代码与文档不匹配的问题_swagger与raml的区别

损失函数——交叉熵损失函数_bp神经网络交叉熵loss曲线图-程序员宅基地

文章浏览阅读2.5k次。交叉熵代价函数(Cross-entropy cost function)是用来衡量人工神经网络(ANN)的预测值与实际值的一种方式。与二次代价函数相比,它能更有效地促进ANN的训练。在介绍交叉熵代价函数之前,本文先简要介绍二次代价函数,以及其存在的不足。一、二次代价函数的不足ANN的设计目的之一是为了使机器可以像人一样学习知识。人在学习分析新事物时,当发现自己犯的错误越大时,改正的力度就越大。比如投篮:当运动员发现自己的投篮方向离正确方向越远,那么他调整的投篮角度就应该越大,篮球就更容易投进篮筐。同理,_bp神经网络交叉熵loss曲线图

Systemverilog中时间单位以及相关系统函数_systemverilog 时间函数-程序员宅基地

文章浏览阅读1.2w次,点赞4次,收藏26次。在Systemverilog中有一些与时间相关的系统函数在TB打印log的时候会使用到,在打印log时间的时候,如果与我们预期的不一致,可以在这方面找原因。下面列出相关的系统函数$time$stime$realtime`timescale$printtimescale$time: 返回module 64bit 整数时间单位,这里的时间单位做一下说明,比如 `timescale 10ns/1ns , 时间单位就是10ns`timescale 10ns/1nsmodule test;_systemverilog 时间函数

html5游戏加入计时器,html5倒计时插件制作圆形计时器代码-程序员宅基地

文章浏览阅读285次。特效描述:html5倒计时插件 圆形计时器代码。计时器代码结构1. 引入CSS2. 引入JS3. HTML代码jQuery计时器插件TimeCircles演示1演示1(默认+美化)演示2(带控制)离2014年1月1日还有(2014年1月1日已过)倒计时10秒后结束页面开始时计时$(function(){$('#someTimer1').TimeCircles({time : {Days: {sho..._html5 圆形倒计时

ECharts -堆叠柱状图_echart 堆叠柱状图-程序员宅基地

文章浏览阅读2.8k次。ECharts 教程 基础篇ECharts数据可视化实验室,解读适合使用场景官网项目简介:ECharts 是一款由百度前端技术部开发的,基于 Javascript 的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。涵盖各行业图表,满足各种需求。项目地址:https://gitee.com/echarts/echarts现在公司刚分配一个任务,需要用到 echarts堆叠柱状图处理缺陷报表问题,以前也没有接触过,所以一边学习ECharts官网上的中文API(http://_echart 堆叠柱状图