对 Spring bean 使用 proxy-target-class="true"

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15568112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 05:50:10  来源:igfitidea点击:

Using proxy-target-class="true" with Spring beans

springjersey

提问by cduggan

Im using Jersey Rest and want a Jersey filter to have access to some spring beans.

我使用 Jersey Rest 并希望 Jersey 过滤器能够访问一些 spring beans。

however as I've discovered from other threads, Jersey does not obtain Spring beans if they are Java proxies as opposed to generated java proxies. I want to add the proxy-target-class="true"

但是,正如我从其他线程中发现的那样,如果它们是 Java 代理而不是生成的 Java 代理,那么 Jersey 不会获得 Spring bean。我想添加 proxy-target-class="true"

What are the impacts of doing so and also can this just be set on a single bean or does it need to be set on all referenced beans?

这样做有什么影响,也可以只在单个 bean 上设置还是需要在所有引用的 bean 上设置?

回答by garst

By setting proxy-target-class="true"you will be using CGLIB2for your proxies, instead of jdk proxys.

通过设置,proxy-target-class="true"您将使用CGLIB2代理,而不是 jdk 代理。

The implications are the following, as described in de documentation:

其含义如下,如 de文档中所述

  • final methods cannot be advised, as they cannot be overriden.

  • You will need the CGLIB 2 binaries on your classpath, whereas dynamic proxies are available with the JDK. Spring will automatically warn you when it needs CGLIB and the CGLIB library classes are not found on the classpath.

  • The constructor of your proxied object will be called twice. This is a natural consequence of the CGLIB proxy model whereby a subclass is generated for each proxied object. For each proxied instance, two objects are created: the actual proxied object and an instance of the subclass that implements the advice. This behavior is not exhibited when using JDK proxies. Usually, calling the constructor of the proxied type twice, is not an issue, as there are usually only assignments taking place and no real logic is implemented in the constructor.

  • 不能建议 final 方法,因为它们不能被覆盖。

  • 您将需要类路径上的 CGLIB 2 二进制文件,而动态代理可用于 JDK。当 Spring 需要 CGLIB 并且在类路径中找不到 CGLIB 库类时,它会自动警告您。

  • 代理对象的构造函数将被调用两次。这是 CGLIB 代理模型的自然结果,为每个代理对象生成一个子类。对于每个代理实例,会创建两个对象:实际代理对象和实现建议的子类实例。使用 JDK 代理时不会出现此行为。通常,调用代理类型的构造函数两次不是问题,因为通常只发生赋值,并且构造函数中没有实现真正的逻辑。

Also, you should be able to make a "target-proxy" for a specific component by using

此外,您应该能够通过使用为特定组件制作“目标代理”

proxyMode=ScopedProxyMode.TARGET_CLASS

回答by Heri

Forcing a CGLib-Proxy although the controller formally implements an interface (SpringBoot 1.2.3.RELEASE with Spring 4.1.6.RELEASE):

尽管控制器正式实现了一个接口(SpringBoot 1.2.3.RELEASE 和 Spring 4.1.6.RELEASE),但强制使用 CGLib-Proxy:

@Controller
@Scope( proxyMode = ScopedProxyMode.TARGET_CLASS )
public class ServiceImpl implements ServiceIntf
{ .... }

This enables valid and working @RequestMapping and @Transactional annotations

这将启用有效且有效的 @RequestMapping 和 @Transactional 注释

回答by rcde0

Use the following annotation in Java Spring Config class:

在 Java Spring Config 类中使用以下注解:

@EnableAspectJAutoProxy(proxyTargetClass = true)

@EnableAspectJAutoProxy(proxyTargetClass = true)