Spring Aop(十三)——ProxyFactoryBean创建代理对象

简介: ProxyFactoryBean创建代理对象 ProxyFactoryBean实现了Spring的FactoryBean接口,所以它跟Spring中的其它FactoryBean一样,都是基于工厂模式来获取一个bean的。

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日)
目录
相关文章
|
20天前
|
监控 安全 Java
什么是AOP?如何与Spring Boot一起使用?
什么是AOP?如何与Spring Boot一起使用?
46 5
|
24天前
|
Java 开发者 Spring
Spring AOP 底层原理技术分享
Spring AOP(面向切面编程)是Spring框架中一个强大的功能,它允许开发者在不修改业务逻辑代码的情况下,增加额外的功能,如日志记录、事务管理等。本文将深入探讨Spring AOP的底层原理,包括其核心概念、实现方式以及如何与Spring框架协同工作。
|
24天前
|
XML 监控 安全
深入调查研究Spring AOP
【11月更文挑战第15天】
36 5
|
24天前
|
Java 开发者 Spring
Spring AOP深度解析:探秘动态代理与增强逻辑
Spring框架中的AOP(Aspect-Oriented Programming,面向切面编程)功能为开发者提供了一种强大的工具,用以将横切关注点(如日志、事务管理等)与业务逻辑分离。本文将深入探讨Spring AOP的底层原理,包括动态代理机制和增强逻辑的实现。
35 4
|
8天前
|
XML 安全 Java
Spring Boot中使用MapStruct进行对象映射
本文介绍如何在Spring Boot项目中使用MapStruct进行对象映射,探讨其性能高效、类型安全及易于集成等优势,并详细说明添加MapStruct依赖的步骤。
|
3月前
Micronaut AOP与代理机制:实现应用功能增强,无需侵入式编程的秘诀
AOP(面向切面编程)能够帮助我们在不修改现有代码的前提下,为应用程序添加新的功能或行为。Micronaut框架中的AOP模块通过动态代理机制实现了这一目标。AOP将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,提高模块化程度。在Micronaut中,带有特定注解的类会在启动时生成代理对象,在运行时拦截方法调用并执行额外逻辑。例如,可以通过创建切面类并在目标类上添加注解来记录方法调用信息,从而在不侵入原有代码的情况下增强应用功能,提高代码的可维护性和可扩展性。
73 1
|
1月前
|
安全 Java 编译器
什么是AOP面向切面编程?怎么简单理解?
本文介绍了面向切面编程(AOP)的基本概念和原理,解释了如何通过分离横切关注点(如日志、事务管理等)来增强代码的模块化和可维护性。AOP的核心概念包括切面、连接点、切入点、通知和织入。文章还提供了一个使用Spring AOP的简单示例,展示了如何定义和应用切面。
123 1
什么是AOP面向切面编程?怎么简单理解?
|
1月前
|
XML Java 开发者
论面向方面的编程技术及其应用(AOP)
【11月更文挑战第2天】随着软件系统的规模和复杂度不断增加,传统的面向过程编程和面向对象编程(OOP)在应对横切关注点(如日志记录、事务管理、安全性检查等)时显得力不从心。面向方面的编程(Aspect-Oriented Programming,简称AOP)作为一种新的编程范式,通过将横切关注点与业务逻辑分离,提高了代码的可维护性、可重用性和可读性。本文首先概述了AOP的基本概念和技术原理,然后结合一个实际项目,详细阐述了在项目实践中使用AOP技术开发的具体步骤,最后分析了使用AOP的原因、开发过程中存在的问题及所使用的技术带来的实际应用效果。
66 5
|
2月前
|
Java 容器
AOP面向切面编程
AOP面向切面编程
44 0
|
3月前
Micronaut AOP与代理机制:实现应用功能增强,无需侵入式编程的秘诀
【9月更文挑战第9天】AOP(面向切面编程)通过分离横切关注点提高模块化程度,如日志记录、事务管理等。Micronaut AOP基于动态代理机制,在应用启动时为带有特定注解的类生成代理对象,实现在运行时拦截方法调用并执行额外逻辑。通过简单示例展示了如何在不修改 `CalculatorService` 类的情况下记录 `add` 方法的参数和结果,仅需添加 `@Loggable` 注解即可。这不仅提高了代码的可维护性和可扩展性,还降低了引入新错误的风险。
53 13