Spring AOP部分使用JDK动态代理或者CGLIB来为目标对象创建代理。(建议尽量使用JDK的动态代理)
如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理。所有该目标类型实现的接口都将被代理。若该目标对象没有实现任何接口,则创建一个CGLIB代理。
如果你希望强制使用CGLIB代理,(例如:希望代理目标对象的所有方法,而不只是实现自接口的方法)那也可以。但是需要考虑以下问题:
无法通知(advise)Final 方法,因为他们不能被覆写。
你需要将CGLIB 2二进制发行包放在classpath下面,与之相较JDK本身就提供了动态代理
强制使用CGLIB代理需要将 <aop:config> 的 proxy-target-class 属性设为true:
<aop:config proxy-target-class="true">
...
</aop:config>当需要使用CGLIB代理和@AspectJ自动代理支持,请按照如下的方式设置 <aop:aspectj-autoproxy> 的 proxy-target-class 属性:
<aop:aspectj-autoproxy proxy-target-class="true"/>而实际使用的过程中才会发现细节问题的差别,The devil is in the detail.JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。
CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强。
Spring是依靠什么来判断采用哪种代理策略来生成AOP代理呢?以下代码就是Spring的判断逻辑
//org.springframework.aop.framework.DefaultAopProxyFactory
//参数AdvisedSupport 是Spring AOP配置相关类 public AopProxy createAopProxy(AdvisedSupport advisedSupport) throws AopConfigException { //在此判断使用JDK动态代理还是CGLIB代理
if (advisedSupport.isOptimize() || advisedSupport.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(advisedSupport)) {
if (!cglibAvailable) {
throw new AopConfigException( "Cannot proxy target class because CGLIB2 is not available. " + "Add CGLIB to the class path or specify proxy interfaces.");
}
return CglibProxyFactory.createCglibProxy(advisedSupport);
} else {
return new JdkDynamicAopProxy(advisedSupport);
}
}
advisedSupport.isOptimize()与advisedSupport.isProxyTargetClass()默认返回都是false,所以在默认情况下目标对象有没有实现接口决定着Spring采取的策略,当然可以设置advisedSupport.isOptimize()或者advisedSupport.isProxyTargetClass()返回为true,这样无论目标对象有没有实现接口Spring都会选择使用CGLIB代理。所以在默认情况下,如果一个目标对象如果实现了接口Spring则会选择JDK动态代理策略动态的创建一个接口实现类(动态代理类)来代理目标对象,可以通俗的理解这个动态代理类是目标对象的另外一个版本,所以这两者之间在强制转换的时候会抛出java.lang.ClassCastException。而所以在默认情况下,如果目标对象没有实现任何接口,Spring会选择CGLIB代理, 其生成的动态代理对象是目标类的子类。
上说的是默认情况下,也可以手动配置一些选项使Spring采用CGLIB代理。
org.springframework.transaction.interceptor.TransactionProxyFactoryBean是org.springframework.aop.framework. ProxyConfig的子类,所以可以参照ProxyConfig里的一些设置如下所示,将optimize和proxyTargetClass任意一个设置为true都可以强制Spring采用CGLIB代理。
如果当需要使用CGLIB代理和@AspectJ自动代理支持,请按照如下的方式设置 <aop:aspectj-autoproxy> 的 proxy-target-class 属性:
<aop:aspectj-autoproxy proxy-target-class="true"/>
这样使用CGLIB代理也就不会出现前面提到的ClassCastException问题了,也可以在性能上有所提高.
补充:Spring默认采用JDK动态代理机制,JDK动态代理和CGLIB的区别就在于JDK动态代理只对实现了接口的类有效,而采用CGLIB代理的类不需要实现接口
分享到:
相关推荐
在深入探讨Spring代理机制之前,我们首先应当理解代理(Proxy)模式的基本概念。代理模式是一种设计模式,它为一个对象提供一个替代或占位符,以便控制对这个对象的访问。在Spring框架中,代理机制主要用于实现AOP...
Spring的代理机制是其核心特性之一,特别是在AOP(面向切面编程)中扮演着重要角色。AOP允许程序员在不修改源代码的情况下,通过在特定的“连接点”(如方法调用)插入额外的功能,例如日志、事务管理等。Spring提供...
Spring框架是Java开发中最常用的轻量级框架之一,它的运行机制源码剖析是理解其工作原理的关键。在本文中,我们将深入探讨Spring的核心组件、依赖注入(DI)以及AOP(面向切面编程)的实现。 首先,让我们从Spring...
Spring框架提供了两种动态代理机制:JDK动态代理和CGLIB代理,它们分别基于这两种技术。 1. JDK动态代理: - 当被代理的目标对象实现了至少一个接口时,Spring会选择使用JDK动态代理。它通过反射机制生成一个实现...
Spring框架中的代理实现是面向切面编程(AOP)的核心机制之一,它允许我们在不修改原有代码的情况下,为对象添加额外的功能。在这个资源中,我们可能会看到三种不同的代理方式:JDK动态代理、CGLIB代理以及Spring AOP...
Java Spring代理模式AOP-IOC分析 一、代理模式概述 在软件设计中,代理模式是一种常用的设计模式。它可以在不修改原始代码的情况下,扩展或修改原始对象的行为。代理模式可以分为静态代理和动态代理两种。静态代理...
总之,Spring AOP通过代理机制和通知机制,为开发者提供了一种优雅的方式,来处理那些横切关注点,提高了代码的复用性和模块化,降低了系统复杂性,使得业务逻辑更加清晰,提高了开发效率。无论是静态代理还是动态...
总结来说,“spring proxy代理模仿”项目是对Spring AOP代理机制的实践与理解,通过此项目,你可以深入学习到如何在不修改原有业务代码的基础上,利用Spring的动态代理能力添加额外的功能,提升代码的可维护性和复用...
总结一下,Spring的AOP机制通过JDK动态代理和CGLIB动态代理提供了强大的横切关注点管理功能。开发者可以轻松地定义切面和通知,以实现如日志、事务管理等功能,同时保持核心业务代码的清晰和简洁。在Spring Boot项目...
总结来说,Spring AOP中的JDK动态代理机制是一种高效且灵活的实现方式,它允许我们在不修改原始代码的前提下,通过代理对象添加额外的功能。这使得我们能够更专注于业务逻辑,而不是关注点的实现。通过理解和掌握这...
**Spring AOP 实现机制详解** Spring AOP(面向切面编程)是Spring框架的核心特性之一,它允许程序员在不修改源代码的情况下,通过“切面”来插入额外的业务逻辑,如日志、事务管理等。AOP的引入极大地提高了代码的...
Spring AOP通过代理模式实现,可以在不修改源代码的情况下,向已有方法添加额外的功能。这里有三个与AOP相关的术语: 1. **AOP Before**:前置通知,是指在目标方法被调用之前执行的增强代码。在Spring中,我们可以...
通过上述分析,我们可以看到,获取Spring中代理对象的目标对象并非一件简单的事情,它涉及到Spring AOP的底层实现以及Java反射机制的运用。`AopTargetUtils`工具类提供了一种统一的方式,无论是JDK动态代理还是CGLIB...
Spring框架是Java开发中广泛使用的轻量级框架,它也提供了强大的代理机制,包括静态代理和动态代理。下面我们将深入探讨这两个概念以及Spring如何实现代理。 1. 静态代理: 静态代理是在编译时就已经明确知道代理...
JDK 动态代理是 Java 自带的动态代理机制,它只能代理接口,而不能代理类。这是因为 JDK 动态代理是基于接口的代理,它需要一个接口来生成代理类。如果我们想使用 JDK 动态代理,必须提供一个接口,并且将其实现类...
在使用Spring时,我们可能会遇到一个术语——“二次代理”,这通常涉及到Spring AOP代理机制。本文将深入探讨Spring的二次代理原因以及如何进行问题排查。 首先,我们需要理解什么是代理。在AOP中,代理是Spring...
下面将详细介绍这两种动态代理机制。 1. JDK动态代理: JDK动态代理基于Java的接口实现。如果我们的目标对象实现了至少一个接口,那么Spring会为我们创建一个代理类,该类实现了相同的接口,并在调用接口方法时...
AOP允许将横切关注点(如事务管理、日志记录等)与业务逻辑分离,通过动态代理机制,在不修改原有代码的情况下,为业务方法添加事务处理能力。下面,我们将详细介绍如何在Spring中配置事务代理。 #### 配置数据源和...