从CDI代理获取真实对象 [英] Get the real object from CDI Proxy

查看:78
本文介绍了从CDI代理获取真实对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种干净的CDI解决方案,而不是一个依赖WELD的解决方案,但到目前为止没有任何东西...

I looked for a clean CDI solution and not a WELD dependent one but so far nothing...

我需要测试对象列表中的每个元素是否我使用@Inject @Any MyInterface bean获得的是代理,当为true时,我需要获取真实的对象进行自省并获取该对象的所有属性。

I need to test if every element of a list of objects that I get with @Inject @Any MyInterface beans is a proxy, and when true I need to get the real object to do introspection and get all the properties of the object.

我的WELD实现:

MyInterface interf = obj;
if (isProxy(interf )) {
        interf = (Config) ((TargetInstanceProxy)interf ).getTargetInstance();
}

isProxy是这样定义的(CDI解决方案?):

where isProxy is so defined (CDI solution?):

public boolean isProxy(Object obj) {
    try{
        return Class.forName("org.jboss.weld.bean.proxy.ProxyObject").isInstance(obj);
    } catch (Exception e) {
        LOGGER.error("Unable to check if object is proxy", e);
    }
    return false;
}

任何建议/适应症。在官方文档中,我没有提到内省(这里

Any suggestions /Indications. In the official documentation I found no mention of introspection (here)

然后我想使用以下方法获取bean的所有属性:

And then I would like to get all the properties of the bean with something like this:

Arrays.stream(interf.getClass().getDeclaredFields()).forEach(
                        field -> extractStuff(...)
                );

我们使用Wildfly和WELD,但不想将我们绑定到CDI的实现上。
提前谢谢!

We use Wildfly and WELD but don't want to bind us to an implementation of CDI. Thanks in advance!

编辑:
问题是,更确切地说:您知道一个干净的CDI解决方案吗? WELD已已经通过 TargetInstanceProxy 实现了?不需要,如果我需要回到学校或我了解自己在写什么。。谢谢您抽出宝贵时间来帮助您!

The question is, more precisely: Do you know a clean CDI solution that WELD is already implementing with TargetInstanceProxy? Not if I need to go back to school or if I understand what I'm writing.. Thanks for taking time to help!

推荐答案

CDI故意隐藏(或不公开)内部结构,因为在针对接口进行编程时,它们对于最终用户而言并不重要。此外,由于始终应通过 调用方法,因此将其弄乱会导致奇怪的错误

CDI is intentionally hiding (or rather not exposing) the internals as they should be unimportant to end user when programming against interface.Furthermore messing with this can cause weird errors as you should always be invoking methods via proxy, not the actual instance.

所以简短的答案是-不,没有纯CDI方法可以做到这一点。
(至少不是预期的。)

So the short answer is - no, there is no pure CDI way to do this. (At least not an intended one.)

但是,看到您已经在使用Weld了,还有其他方法。除了TomEE,Weld几乎与任何其他EE服务器一起提供,因此依赖Weld API应该非常安全。
现在我为什么要这么说-在Weld 3.x(WildFly 12+)中,API扩展为包含 WeldConstruct WeldClientProxy 是由Weld sublases(拦截器/修饰器)和/或客户端代理实现的接口-有关更多信息,请参见这些类的javadocs。

However, seeing that you are using Weld already, there are other ways. Weld comes with pretty much any EE server excepting TomEE, so depending on Weld API should be pretty safe. Now why am I saying this - in Weld 3.x (WildFly 12+), the API was extended to contain WeldConstruct and WeldClientProxy which are interfaces implemented by either Weld sublasses (interceptors/decorators) and/or client proxies - see javadocs of those classes for more information.

因此,如果必须执行此操作,则可以这样添加对Weld API的依赖关系:

So if you must do this, then you could add a dependency on Weld API as such:

<dependency>
  <groupId>org.jboss.weld</groupId>
  <artifactId>weld-api</artifactId>
  <version>x.y.z</version>
</dependency>

然后,在您的代码中,您可以通过以下操作检查注入的对象是否是代理:

And then, in your code, you can check if injected object is a proxy by doing:

@Inject
Foo foo;

public void doSomething() {
  if (foo instanceof WeldClientProxy) {
    // foo is a proxy
  } else {
    // not a proxy
  }
}

如果要获取实际实例,请 WeldClientProxy 允许您获取元数据 ,从中您可以检索基础上下文实例。那是我能带给您的最接近的信息。

If you want to obtain actual instances, WeldClientProxy allows you to obtain Metadata from which you can the retrieve the underlying contextual instance. That's the closest I can get you to what you are after.

这篇关于从CDI代理获取真实对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆