Spring Aop(十三)——ProxyFactoryBean创建代理对象
转发地址:https://www.iteye.com/blog/elim-2398673
ProxyFactoryBean创建代理对象
ProxyFactoryBean
实现了Spring的FactoryBean
接口,所以它跟Spring中的其它FactoryBean
一样,都是基于工厂模式来获取一个bean的。ProxyFactoryBean
就是用来获取一个对象的代理对象的FactoryBean
。它也是继承自ProxyCreatorSupport
类的,所以它的功能基本跟ProxyFactory
差不多,只是ProxyFactory
是用于编程式的创建代理对象。而ProxyFactoryBean
用于在Spring的bean容器中创建基于bean的代理对象。通常一个简单的ProxyFactoryBean
配置大概会是如下这样。
<bean id="proxyFactoryBeanTestService"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target"><!-- 指定被代理的对象 -->
<bean class="com.elim.learn.spring.aop.service.ProxyFactoryBeanTestService"/>
</property>
<property name="proxyTargetClass" value="true"/><!-- 指定启用基于Class的代理 -->
<!-- 指定生成的代理对象需要绑定的Advice或Advisor在bean容器中的名称 -->
<property name="interceptorNames">
<list>
<value>logAroundAdvice</value>
</list>
</property>
</bean>
在上面的示例中我们被代理的对象对应的Class是com.elim.learn.spring.aop.service.ProxyFactoryBeanTestService
,其是一个没有实现任何接口的Class,所以我们生成的代理对象最终会是基于CGLIB的代理。我们需要指定proxyTargetClass="true"
,以表示我们是倾向于使用CGLIB代理的,对于上面的配置实际上就是告诉Spring我们要使用CGLIB代理。虽然这里我们不指定proxyTargetClass="true"
时,Spring可能也会给我们使用CGLIB代理,为什么这里说是可能呢?因为ProxyFactoryBean
默认生成的bean都是单例、且在生成bean时会自动检测被代理对象实现的接口,而且proxyTargetClass
默认是false,这种情况下ProxyFactoryBean
就会自动检测被代理对象的实现的接口。按理来说我们的bean是一个没有实现接口的bean,Spring给我们去找它实现的接口是找不出来的,但是我们知道Spring的Aop是会自动为我们的对象实现一些接口的。简单的说如果我们的bean容器中配置了其它的Advisor,那么我们指定的target对象有可能就不是一个原始的bean,而是一个已经被Aop代理过的bean对象,这种bean对象,Spring Aop默认会为其实现一个Advised
接口。所以使用ProxyFactoryBean
时,如果我们的代理对象类是没有实现接口的,或者我们期望生成代理对象时是基于Class的,而不是基于Interface的,我们最好明确的指定proxyTargetClass="true"
,而不是寄希望于Spring的自动决定机制。 指定被代理对象时,除了可以直接指定target外,我们还可以通过targetName指定被代理对象在bean容器中的bean名称。 在上面的示例中我们通过interceptorNames属性指定了生成的代理对象需要应用的Advisor/Advice对应于bean容器中的bean的名称。跟ProxyFactory一样,如果我们指定的是Advice对象,则其会转换为一个匹配所有方法调用的Advisor与代理对象绑定。 在指定intercepterNames时我们也可以通过“*”指定所有beanName以XX开始的Advisor/Advice,如我们的bean容器中同时拥有“abc1Advisor”、“abc2Advisor”两个Advisor,我们期望创建的ProxyFactoryBean同时应用这两个Advisor,那我们可以不用单独指定两次,而是一次性把interceptorNames指定的一个beanName为“abc*”。需要注意的是“*”只能定义在beanName的末端。
<bean id="proxyFactoryBeanTestService"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target"><!-- 指定被代理的对象 -->
<bean class=" com.elim.learn.spring.aop.service.ProxyFactoryBeanTestService"/>
</property>
<property name="proxyTargetClass" value="true"/><!-- 指定启用基于Class的代理 -->
<!-- 指定生成的代理对象需要绑定的Advice或Advisor在bean容器中的名称 -->
<property name="interceptorNames">
<list>
<value>abc*</value>
</list>
</property>
</bean>
其它配置信息
- exposeProxy:属于从
ProxyCreatorSupport
继承过来的属性,用于定义是否需要在调用代理对象时把代理对象发布到AopContext
,默认是false
。 - singleton:用来指定
ProxyFactoryBean
生成的bean是否是单例的,默认是true
。该值对应于FactoryBean
的isSingleton()接口方法的返回值。 - frozen:属于从
ProxyCreatorSupport
继承过来的属性,用于指定代理对象被创建后是否还允许更改代理配置,通过Advised
接口更改。true
表示不允许,默认是false。 - autodetectInterfaces:表示是否在生成代理对象时需要启用自动检测被代理对象实现的接口,默认是
true
。 - proxyInterfaces:基于接口的代理时指定需要代理的接口。
- interfaces:基于接口的代理时指定需要代理的接口,属于从
ProxyCreatorSupport
继承过来的。 关于ProxyFactoryBean
的更多配置项信息可以参考Spring的API文档或ProxyFactoryBean
的源代码。
(注:本文是基于Spring4.1.0所写,Elim写于2017年5月10日)
Spring Aop(十三)——ProxyFactoryBean创建代理对象的更多相关文章
- Spring AOP 源码分析 - 创建代理对象
1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...
- Spring Aop(十四)——Aop自动创建代理对象的原理
转发地址:https://www.iteye.com/blog/elim-2398725 Aop自动创建代理对象的原理 我们在使用Spring Aop时,通常Spring会自动为我们创建目标bean的 ...
- Spring AOP源码分析(三):基于JDK动态代理和CGLIB创建代理对象的实现原理
AOP代理对象的创建 AOP相关的代理对象的创建主要在applyBeanPostProcessorsBeforeInstantiation方法实现: protected Object applyBea ...
- spring aop 源码分析(三) @Scope注解创建代理对象
一.源码环境的搭建: @Component @Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON,proxyMode = ScopedP ...
- 死磕Spring之AOP篇 - Spring AOP自动代理(三)创建代理对象
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- Spring AOP中的动态代理
0 前言 1 动态代理 1.1 JDK动态代理 1.2 CGLIB动态代理 1.2.1 CGLIB的代理用法 1.2.2 CGLIB的过滤功能 2 Spring AOP中的动态代理机制 2.1 ...
- 转:Spring AOP中的动态代理
原文链接:Spring AOP中的动态代理 0 前言 1 动态代理 1.1 JDK动态代理 1.2 CGLIB动态代理 1.2.1 CGLIB的代理用法 1.2.2 CGLIB的过滤功能 2 S ...
- Spring AOP关于cglib动态代理
一: Spring AOP的默认代理方式是jdk动态代理,还有另外一种代理方式是cglib代理,简单说前者基于接口,后者基于继承,基本思路是将被代理对象的类作为父类,然后创建子类来进行方法的调用,调用 ...
- spring---aop(4)---Spring AOP的CGLIB动态代理
写在前面 前面介绍了Spring AOP的JDK动态代理的过程,这一篇文章就要介绍下Spring AOP的Cglib代理过程. CGLib全称为Code Generation Library,是一个强 ...
随机推荐
- PHP开发中常用的字符串操作函数
1,拼接字符串 拼接字符串是最常用到的字符串操作之一,在PHP中支持三种方式对字符串进行拼接操作,分别是圆点.分隔符{}操作,还有圆点等号.=来进行操作,圆点等号可以把一个比较长的字符串分解为几行进行 ...
- flink相关
flink一.简单实时计算方案 假如现在我们有一个电商平台,每天访问的流量巨大,主要访问流量都集中在衣服类.家电类页面,那么我们想实时看到这两类页面的访问量走势(十分钟出一个统计量),当做平台的重要指 ...
- http协议头
1. ctx->AddResponseHeader("Content-Type", "application/octet-stream"); ctx-&g ...
- 【翻译】PATH究竟是什么?
最近,我试图向一个朋友解释他电脑上PATH变量是用来做什么的.我在我们所交流的平台‘the Slack group"写了一篇比较长的消息之后,我意识到这个主题可以写成一个很好的博客,所以开始 ...
- Ellipsis对象
Ellipsis对象. 写作 : ‘…’ 中文解释:省略 该对象bool测试是为真 用途: 1.用来省略代码,作用类似于pass的一种替代方案,这是python的’TBD’(未确定内容). def f ...
- Codeforces Round #470 (rated, Div. 1, based on VK Cup 2018 Round 1) 923D 947D 948E D. Picking Strings
题: OvO http://codeforces.com/contest/947/problem/D 923D 947D 948E 解: 记要改变的串为 P1 ,记目标串为 P2 由变化规则可得: ...
- keepalived+lvs+nginx高可用
环境说明: IP地址 部署应用 192.168.10.100 VIP0 192.168.10.101 VIP1 192.168.10.17 keepalived+lvs 192.168.10.16 k ...
- 关于IE8的兼容性问题
DOCTYPE 首先需要确保你的HTML页面开始部分要有DOCTYPE声明.DOCTYPE告诉浏览器使用什么样的HTML或XHTML规范来解析HTML文档,具体会影响: 对标记.attributes ...
- IDEA工具的安装、破解与配置
一.什么是IDEA? IDEA 全称 IntelliJ IDEA,是java编程语言开发的集成环境,是目前最好用的java集成开发工具.他最突出的功能是调试(Debug),可以对Java代码,Java ...
- Java进阶知识18 Spring对象依赖关系的几种写法
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...