简体   繁体   English

当具有拦截器或装饰器的bean在CDI中有什么处理规则?

[英]what are proxing rules in CDI for beans when they have interceptor or decorator?

I ran 2 examples in weblogic ( I used a bean with dependent scope): 我在weblogic中运行了2个示例(我使用了具有依赖范围的bean):

1)the bean has not any interceptors or decorators: the bean was not proxied 1)bean没有任何拦截器或装饰器:bean没有被代理

2)the bean has a interceptors : the bean was proxied 2)bean有一个拦截器:bean被代理了

I think that there are two types of proxies in CDI: 我认为CDI中有两种代理:

1)client proxy: This proxy overrides all the non-private methods of the bean class, when these overridden methods are invoked the proxy looks up the correct instance( or proxy of second type) of the bean and then forwards the invocation onto the actual bean instance (based on this link). 1)客户端代理:此代理会覆盖Bean类的所有非私有方法,当调用这些覆盖的方法时,代理会查找Bean的正确实例(或第二种代理),然后将调用转发到实际bean实例(基于链接)。 for dependent scope this proxy is not created 对于依赖范围,不会创建此代理

2)there is another proxy for applying interceptors and decorators and it is created when the bean has decorator or interceptors 2)还有另一个代理应用拦截器和装饰器,它是在bean具有装饰器或拦截器时创建的

Is my assumption about second type of proxy correct? 我对第二种代理的假设正确吗? Does the specification say anything about it? 规范对此有何规定?

You made a nice investigation indeed and you are right for the most part. 您确实做了一个很好的调查,并且在大多数情况下是正确的。 Here are the details. 这是详细信息。

Proxy 代理

Normal scoped beans ( @ApplicationScoped , RequestScoped ,...) are indeed proxied, you don't get hold of the actual instance and what you are getting is a client proxy . 确实可以代理普通作用域的bean(@ @ApplicationScopedRequestScoped等),您不掌握实际的实例,而获得的只是一个客户端代理 With @Dependent which is not normal scoped, you basically want to inject new instance every time so there is no need to have it proxied. 随着@Dependent这是正常的范围的,你基本上要每次注入新的实例,所以没有需要把它代理。

The above has some mentions in CDI spec, albeit not precise to give implementation space in which they can manipulate - users should't really care if they have a proxy or not for calling their methods works just fine. 上面的内容在CDI规范中有所提及,尽管不够精确,无法提供可以在其中进行操作的实现空间-用户不必真正关心是否具有代理,也可以不调用它们的方法就可以了。

Interceptors and Decorators 拦截器和装饰器

Moving on to interceptors - spec says nothing about this from what I know and leaves implementations to choose freely what to do with it. 继续讲拦截器-规范从我所知道的事情上什么都没有说,而是让实现者自由选择要怎么做。 Following details are Weld-specific although from what I recall, OWB has it similar. 以下细节是焊接特定的,尽管据我回忆,OWB也有类似的细节。 There aren't really many option how to achieve it anyway. 无论如何,实际上没有太多选择。

For every interceptor/decorator, there is a "proxy" created, in fact a subclass, which allows to make interception/decoration happen. 对于每个拦截器/装饰器,都会创建一个“代理”,实际上是一个子类,该子类允许进行拦截/装饰。 This subclass replaces the original bean and all calls go through it (eg it is in the underlying bean store instead of the original instance). 该子类替换了原始bean,所有调用都通过了它(例如,它在基础bean存储中而不是原始实例中)。

Again, from user perspective, this makes no difference and you shouldn't be worried about it. 再次,从用户的角度来看,这没有什么区别,您不必担心。

Extra tooling for proxies/sublasses 代理/子平台的额外工具

Sometimes, very rarely, and most likely only when you are developing a CDI library , you may truly need to see if the injected bean is a client proxy or a subclass. 有时, 很少,最有可能只有在开发CDI库时 ,您才真正需要查看注入的bean是客户端代理还是子类。 Weld offers tools for that, every bean which has a client proxy is implementing WeldClientProxy interface from Weld API. Weld为此提供了工具,每个具有客户端代理的bean都从Weld API实现WeldClientProxy接口。 This interface allows you to grab the actual instance and some metadata. 该界面允许您获取实际实例和一些元数据。 Likewise, every intercepted and decorated bean is implementing WeldContruct as a marker interface. 同样,每个被拦截和修饰的bean都将WeldContruct实现为标记接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM