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的源码中,`org.springframework.aop.framework.ProxyFactoryBean`是创建代理的主要类,它会根据目标类是否有接口选择JDK动态代理或CGLIB。`org.aopalliance.intercept.MethodInterceptor`接口定义了...
在源码层面,`org.springframework.aop.framework.ProxyFactoryBean`是创建代理的主要类,它会根据目标对象是否实现接口来选择合适的代理方式。如果目标类实现了接口,那么使用JDK动态代理;否则,使用CGLIB代理。`...
spring-aop.jar包含了这些代理机制的相关类,如`org.springframework.aop.framework.ProxyFactoryBean`,它是创建代理对象的工厂。 2. **切面(Aspect)**:切面是AOP的核心概念,它封装了关注点的逻辑。在Spring中...
在Spring框架中,AOP允许开发者定义“切面”——将这些关注点封装的模块,然后在运行时自动地“织入”到目标对象中。 1. **切面定义**: - 在Spring AOP中,切面可以由一个或多个通知(advises)组成,包括前置...
虽然ApplicationContext本身不直接处理AOP,但它通过配合AOP代理(如DefaultListableBeanFactory中的ProxyFactoryBean)和Advisor,实现了AOP的配置和应用。 8. **其他功能**: ApplicationContext还支持Bean的懒...
通过阅读源码,我们可以学习如何定义切面、切入点表达式和通知类型,并理解Spring如何在运行时生成代理对象以实现AOP功能。 再者,Spring的事务管理也是其关键特性之一。Spring提供了编程式和声明式事务管理两种...
在源码中,`Advisor`、`Pointcut`和`Advice`等接口是描述切面的关键,而`ProxyFactoryBean`或`AspectJAutoProxyCreator`则是创建代理对象的工具。 Spring还提供了大量的模块,如数据访问/集成(DAO)、Web MVC、JMS...
例如,`AspectJ`支持允许开发者使用注解或XML配置来定义切面,而`ProxyFactoryBean`和`AspectJAutoProxyCreator`等工具则帮助Spring自动创建代理对象,实现在运行时对方法调用的拦截。 此外,`springframework-...
在1.0-rc1版本中,Spring通过代理模式实现了AOP,主要体现在`org.springframework.aop`包下的类,如`ProxyFactoryBean`和`AspectJAdvice`等。 3. **数据访问支持**:Spring 1.0-rc1对JDBC进行了封装,提供了一套...
12.4springaop的代理工厂 253 12.4.1选择合适的代理 253 12.4.2proxyfactory 254 12.4.3proxyfactorybean 254 12.5项目实战——输出日志 256 本章小结 258 课后练习 259 第13章 spring与javaee持久化数据...
`ProxyFactoryBean`和`AspectJAutoProxyCreator`是创建代理对象的两个关键类。 - `Advisor`接口和它的实现(如`PointcutAdvisor`和`BeforeAdvice`)封装了切点表达式和通知逻辑,`Pointcut`定义了何时应用通知,`...
`ProxyFactoryBean`和`AspectJAutoProxyCreator`是实现AOP的关键类,前者创建代理对象,后者基于AspectJ实现AOP。 3. **DI(Dependency Injection)**:DI是IoC的一种具体实现,通过容器将依赖关系注入到对象中,而...
3. **面向切面编程**:Spring的AOP模块允许我们定义“切面”——封装关注点如日志、事务管理的模块。在源码中,你会看到Advisor、Pointcut、Aspect等概念的实现,以及如何通过ProxyFactoryBean或AspectJ自动代理来...