Java SpringAOP何时使用CGLIB代理?
我在读一些关于Spring AOP的文章时遇到了以下问题: AOP代理:AOP创建的用于实现方面的对象 合同。在Spring中,代理对象可以是JDK动态代理或 CGLIB代理。默认情况下,代理对象将是JDK动态的 代理,并且被代理的对象必须实现一个接口, 这也将由代理对象实现。但是像这样的图书馆 CGLIB也可以通过子类化来创建代理,因此 接口是不需要的 您能看看下面的结构并想象一下我们想要建议Java SpringAOP何时使用CGLIB代理?,java,spring,proxy,spring-aop,cglib,Java,Spring,Proxy,Spring Aop,Cglib,我在读一些关于Spring AOP的文章时遇到了以下问题: AOP代理:AOP创建的用于实现方面的对象 合同。在Spring中,代理对象可以是JDK动态代理或 CGLIB代理。默认情况下,代理对象将是JDK动态的 代理,并且被代理的对象必须实现一个接口, 这也将由代理对象实现。但是像这样的图书馆 CGLIB也可以通过子类化来创建代理,因此 接口是不需要的 您能看看下面的结构并想象一下我们想要建议bar()方法吗 public interface Foo { void foo(); }
bar()
方法吗
public interface Foo {
void foo();
}
public class FooImpl implements Foo {
@Override
public void foo() {
System.out.println("");
}
public void bar() {
System.out.println("");
}
}
这是否意味着在这种情况下将使用CGLIB代理?
由于JDK dynamic proxy无法实现任何接口来重写
bar()
方法。Spring只会在您要求的情况下使用CGLIB。通过将@enableSpectJautoProxy
的proxyTargetClass
元素设置为true
,可以启用此功能(对于基于注释的配置)
public interface Foo {
void foo();
}
public class FooImpl implements Foo {
@Override
public void foo() {
System.out.println("");
}
public void bar() {
System.out.println("");
}
}
@EnableAspectJAutoProxy(proxyTargetClass = true)
考虑这个最小的例子(假设您的FooImpl
是用@组件注释的
)
默认情况下,proxyTargetClass
为false
。在这种情况下,Spring将不使用CGLIB。由于@Aspect
类中的@Before
建议,Spring将决定需要使用JDK代理代理FooImpl
。不幸的是,由于这种代理行为,实际存储在上下文中的bean将是动态JDKProxy
类型(也是Foo
接口的子类型),因此尝试使用FooImpl.class
获取bean将失败
即使尝试将其作为Foo
检索,也无法调用bar()
方法,因为代理对象不是FooImpl
如果启用
proxyTargetClass
,上述代码将按预期工作,将创建CGLIB代理,并在调用建议之前调用。Spring AOP默认使用标准JDK动态代理作为AOP代理。这允许代理任何接口(或接口集)
SpringAOP也可以使用CGLIB代理。这对于代理类而不是接口是必需的。如果业务对象未实现接口,则默认情况下使用CGLIB。因为编程到接口而不是类是一种很好的做法;业务类通常将实现一个或多个业务接口。在需要建议未在接口上声明的方法的情况下,或者需要将代理对象作为具体类型传递给方法的情况下,可以强制使用CGLIB
掌握SpringAOP是基于代理的这一事实很重要。请参阅了解AOP代理,以全面了解此实现细节的实际含义
请参见Spring文档中的:
SpringAOP默认使用标准JDK动态代理作为AOP代理。这允许代理任何接口(或接口集)
SpringAOP也可以使用CGLIB代理。这对于代理类而不是接口是必需的。默认情况下,如果业务对象未实现接口,则使用CGLIB
这取决于--您是如何注入bean的?谢谢,但是您能解释一下为什么会在您的代码片段中抛出异常吗?如果我们无法检索/调用JDK dynamic proxy,那么使用JDK dynamic proxy建议该方法的目的是什么?@Pavel尽管FooImpl
由@component
注释,但由于该建议,它也是代理的目标。因此,Spring将为它创建一个代理类型的bean定义,因此不是FooImpl
。