从CDI代理获取真实对象

Pao*_*f76 2 java cdi jboss-weld

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

我需要测试,如果我用@Inject @Any MyInterface的豆获得对象的列表中的每个元素是一个代理,而当真正的我需要得到真正的对象做反省和获取对象的所有属性.

我的WELD实施:

MyInterface interf = obj;
if (isProxy(interf )) {
        interf = (Config) ((TargetInstanceProxy)interf ).getTargetInstance();
}
Run Code Online (Sandbox Code Playgroud)

其中isProxy是如此定义的(CDI解决方案?):

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;
}
Run Code Online (Sandbox Code Playgroud)

任何建议/指示.在官方文档中我没有提到内省(这里)

然后我想得到bean的所有属性,如下所示:

Arrays.stream(interf.getClass().getDeclaredFields()).forEach(
                        field -> extractStuff(...)
                );
Run Code Online (Sandbox Code Playgroud)

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

编辑: 问题是,更确切地说:您是否知道WELD 已经使用TargetInstanceProxy实施的干净CDI解决方案?如果我需要回到学校或者我理解我在写什么,那就不行了.感谢您花时间帮忙!

Sil*_*rus 9

CDI故意隐藏(或者更确切地说不暴露)内部,因为它们在对接口编程时应该对最终用户不重要.此外,搞乱这种情况可能会导致奇怪的错误,因为您应该始终通过代理调用方法,而不是实际的实例.

所以简短的回答是 - 不,没有纯粹的CDI方法来做到这一点. (至少不是预期的那个.)

但是,看到你已经使用Weld,还有其他方法.除了TomEE之外,Weld几乎都有EE服务器,所以取决于Weld API应该是非常安全的.现在为什么我这样说 - 在Weld 3.x(WildFly 12+)中,API被扩展为包含WeldConstructWeldClientProxy由Weld子类(拦截器/装饰器)和/或客户端代理实现的接口 - 请参阅这些类的javadoc更多信息.

因此,如果您必须这样做,那么您可以添加对Weld API的依赖:

<dependency>
  <groupId>org.jboss.weld</groupId>
  <artifactId>weld-api</artifactId>
  <version>x.y.z</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

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

@Inject
Foo foo;

public void doSomething() {
  if (foo instanceof WeldClientProxy) {
    // foo is a proxy
  } else {
    // not a proxy
  }
}
Run Code Online (Sandbox Code Playgroud)

如果要获取实际实例,则WeldClientProxy允许您Metadata从中检索基础上下文实例.这是我能找到你所追求的最接近的人.