UML结构图如下:

Advised:AOP proxies工厂配置项接口,具体配置包括 Method Interceptors,Advice,Advisors和其他接口

ProxyCreatorSupport:proxy工厂的基类,提供了便利的方法来配置AopProxyFactory

属性:

private AopProxyFactory aopProxyFactory;  //aopproxy工厂类
private List<AdvisedSupportListener> listeners = new LinkedList<>();

核心方法:

1.createAopProxy

protected final synchronized AopProxy createAopProxy() {if (!this.active) {activate();}return getAopProxyFactory().createAopProxy(this);}

实现了模板方法模式,子类通过调用createAopProxy方法来创建aopProxy

DefaultAopProxyFactory:AopProxyFactory默认实现,根据配置项创建CGLIB或者JDK Proxy

核心方法:

1.createAopProxy

描述:

1.默认情况下,全部生成JDKDynamicAopProxy

2.根据配置的isProxyTargetClass属性值:接口生成JDKDynamicAopProxy,对象生成CglibProxy

ProxyFactory:AOP Proxy的工厂类,通过简单的方式来创建AOP Proxy

属性:

TargetSource targetSource;
private List<Class<?>> interfaces = new ArrayList<>();

核心方法:

public Object getProxy() {return createAopProxy().getProxy();}public Object getProxy(@Nullable ClassLoader classLoader) {return createAopProxy().getProxy(classLoader);}

ProxyFactoryBean:基于Spring IOC模块的BeanFactory定义的Bean生成的AOP proxy工厂类

实现接口:

public class ProxyFactoryBean extends ProxyCreatorSupportimplements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware

核心方法:

1.getObject()

/*** Return a proxy. Invoked when clients obtain beans from this factory bean.* Create an instance of the AOP proxy to be returned by this factory.* The instance will be cached for a singleton, and create on each call to* {@code getObject()} for a proxy.* @return a fresh AOP proxy reflecting the current state of this factory*/@Overridepublic Object getObject() throws BeansException {initializeAdvisorChain();if (isSingleton()) {return getSingletonInstance();}else {if (this.targetName == null) {logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +"Enable prototype proxies by setting the 'targetName' property.");}return newPrototypeInstance();}}

备注:

1.根据属性值的内容(bean name)在BeanFactory获取到对应的Spring Bean,添加到advisors列表

2.根据singleton的内容,决定生成singleton bean instance还是 prototype bean instance

2.initializeAdvisorChain

/*** Create the advisor (interceptor) chain. Advisors that are sourced* from a BeanFactory will be refreshed each time a new prototype instance* is added. Interceptors added programmatically through the factory API* are unaffected by such changes.*/private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {if (this.advisorChainInitialized) {return;}if (!ObjectUtils.isEmpty(this.interceptorNames)) {if (this.beanFactory == null) {throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));}// Globals can't be last unless we specified a targetSource using the property...if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {throw new AopConfigException("Target required after globals");}// Materialize interceptor chain from bean names.for (String name : this.interceptorNames) {if (logger.isTraceEnabled()) {logger.trace("Configuring advisor or advice '" + name + "'");}if (name.endsWith(GLOBAL_SUFFIX)) {if (!(this.beanFactory instanceof ListableBeanFactory)) {throw new AopConfigException("Can only use global advisors or interceptors with a ListableBeanFactory");}addGlobalAdvisor((ListableBeanFactory) this.beanFactory,name.substring(0, name.length() - GLOBAL_SUFFIX.length()));}else {// If we get here, we need to add a named interceptor.// We must check if it's a singleton or prototype.Object advice;if (this.singleton || this.beanFactory.isSingleton(name)) {// Add the real Advisor/Advice to the chain.advice = this.beanFactory.getBean(name);}else {// It's a prototype Advice or Advisor: replace with a prototype.// Avoid unnecessary creation of prototype bean just for advisor chain initialization.advice = new PrototypePlaceholderAdvisor(name);}addAdvisorOnChainCreation(advice, name);}}}this.advisorChainInitialized = true;}

备注:遍历interceptorNames数组,通过BeanFactoryUtils.beanNamesForTypeIncludingAncestors或者 BeanFactory.getBean方法 来获取 advisor和Interceptor bean instance,并添加到Advisors列表

3.getSingletonInstance和newPrototypeInstance

/*** Return the singleton instance of this class's proxy object,* lazily creating it if it hasn't been created already.* @return the shared singleton proxy*/private synchronized Object getSingletonInstance() {if (this.singletonInstance == null) {this.targetSource = freshTargetSource();if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {// Rely on AOP infrastructure to tell us what interfaces to proxy.Class<?> targetClass = getTargetClass();if (targetClass == null) {throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");}setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));}// Initialize the shared singleton instance.super.setFrozen(this.freezeProxy);this.singletonInstance = getProxy(createAopProxy());}return this.singletonInstance;}
/*** Create a new prototype instance of this class's created proxy object,* backed by an independent AdvisedSupport configuration.* @return a totally independent proxy, whose advice we may manipulate in isolation*/private synchronized Object newPrototypeInstance() {// In the case of a prototype, we need to give the proxy// an independent instance of the configuration.// In this case, no proxy will have an instance of this object's configuration,// but will have an independent copy.if (logger.isTraceEnabled()) {logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this);}ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());// The copy needs a fresh advisor chain, and a fresh TargetSource.TargetSource targetSource = freshTargetSource();copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain());if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {// Rely on AOP infrastructure to tell us what interfaces to proxy.Class<?> targetClass = targetSource.getTargetClass();if (targetClass != null) {copy.setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));}}copy.setFrozen(this.freezeProxy);if (logger.isTraceEnabled()) {logger.trace("Using ProxyCreatorSupport copy: " + copy);}return getProxy(copy.createAopProxy());}

备注:getSingletonInstance和newPrototypeInstance区别在于SingletonInstance只会初始化一次,newPrototypeInstance每次都会重新创建

Spring-AOP模块的Advised分析相关推荐

  1. spring aop源码实现分析

    1. 先分析Advice before执行Cglib2AopProxy的intercept方法: /*** General purpose AOP callback. Used when the ta ...

  2. spring aop分析(一)

    一.简介 Spring Aop模块采用了代理(Proxy)机制来实现AOP功能,在运行过程中aop框架大致可以分成三个阶段:创建代理.计算拦截器链.处理调用. 在"创建代理"阶段, ...

  3. 【Spring】Spring AOP源码分析-导读(一)

    文章目录 1.简介 2.AOP 原理 3.AOP 术语及相应的实现 3.1 连接点 - Joinpoint 3.2 切点 - Pointcut 3.3 通知 - Advice 3.4 切面 - Asp ...

  4. Spring原理学习系列之三:Spring AOP原理(从源码层面分析)-------上部

    引言 本文是Spring原理分析的第三篇博文,主要阐述Spring AOP相关概念,同时从源码层面分析AOP实现原理.对于AOP原理的理解有利于加深对Spring框架的深入理解.同时我也希望可以探究S ...

  5. 深入聊一聊 Spring AOP 实现机制

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 本文转载于公众号:吉姆餐厅ak 概述 AOP(Aspect-Oriented Programmin ...

  6. Spring IOC 容器源码分析系列文章导读

    1. 简介 前一段时间,我学习了 Spring IOC 容器方面的源码,并写了数篇文章对此进行讲解.在写完 Spring IOC 容器源码分析系列文章中的最后一篇后,没敢懈怠,趁热打铁,花了3天时间阅 ...

  7. Spring学习总结(9)——Spring AOP总结

    spring IOC和AOP是Spring框架的两大核心基石,本文将对Spring AOP做一个系统的总结. 什么是AOP AOP(Aspect-Oriented Programming,面向切面编程 ...

  8. 深入聊一聊 Spring AOP 实现机制!

    作者 | 张书康 责编 | 郭   芮 AOP(Aspect-Oriented Programming,即面向切面编程.Spring Aop 在 Spring框架中的地位举足轻重,主要用于实现事务.缓 ...

  9. AOP的实现原理 —— 静态代理 和 动态代理( Spring AOP)

    文章目录 一.AOP是什么? 二.静态代理 -- AspectJ 2.1.举例说明 三. 动态代理 3.1.JDK 动态代理 3.1.1. 核心类: 3.1.2. 示例1--JDK动态代理 3.2.C ...

  10. spring AOP策略模式使用

    1.策略模式 The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them inte ...

最新文章

  1. 远程办公时,有哪些提高沟通效率的技巧?
  2. 安装Ubuntu 14.04后要做的5件事情
  3. 2020-12-03 The Geometry of Rotations and Rigid-Body Motions (刚体运动和旋转的几何表示,罗德里格参数)
  4. tomcat的诡异的端口占用问题
  5. D/A转换器(华师)
  6. 中国联通辟谣“不支持华为”:恶意诽谤 将通过法律手段维护权益
  7. 将日期变为中文星期几
  8. php怎么取json数组元素个数,json,数组_取出json数据中的某一项组成一个数组?,json,数组,php - phpStudy...
  9. 布朗运动、伊藤引理、BS公式(后篇)
  10. 微信小程序查询数据库总条数
  11. 商标注册后的注意事项
  12. HashMap的put过程
  13. 在padavan运行wifidog
  14. 炼数成金《数据分析与SAS》课程
  15. Android 应用市场链接上传地址
  16. 2020快手前端暑期实习面经
  17. maven、gradle 设置MANIFEST.MF配置
  18. html如何删除网页边框,如何从HTML表中完全删除边框
  19. 治疗狗狗常见疾病药品备忘
  20. Codewars刷题升级 (Python)5Kyu Pete, the baker 皮特,面包师

热门文章

  1. 什么是后端开发?后端能做什么?全栈工程师又是什么?
  2. 电源纹波怎么测量,纹波和噪声的区别
  3. PyTorch 轻松节省显存的小技巧
  4. Matlab识别拨号音,电话拨号音识别全解.ppt
  5. html+css 模仿制作百度注册页面
  6. Geometric Transformation(几何变换)
  7. mybatis mysql连接时区_MySQL时区的查看和设置
  8. Android实现网络视频播放
  9. 群晖docker实现IPV6访问
  10. SLG手游卡牌类游戏机器人逻辑算法