CDI Bean的方法可以返回它创建的托管Bean吗?

时间:2016-03-21 19:32:02

标签: java cdi

我有以下设置:

@Applicationscoped
@Transactional(txtype.Requires_new)
Public class querybean {

    @Inject ExternalSysrltem externalSystemProxy;

    Public Handle gethandleByKey(String key) {
        return new Handle(/*do external Systems Query, returns an ExternalHandle Object*/)
    }

    Public static class Handle {
        ExternalHandle eh;
        /*protected so that User of class cannot Instantiate it otherwise that by getHandleByKey()*/
        Protected Handle(ExternalHandle arg) {
            This.eh = arg;
        }

        Public String getHandleInfo() {
            Return This.eh.getName() + "/" + this.eh.getState()..;
            /*generally wrap the ExternallHandle with businesslogic to hide direct access to the complex ExternalService's Interface*/
        }
    }
}

我可以让Handle成为可以使用@Transactional注释的托管Bean,并且仍然可以通过查询外部系统在运行时在getHandleByKey方法中创建它吗?

1 个答案:

答案 0 :(得分:1)

静态内部类可以是spec的bean。 在您的示例中,由于其构造函数,它不是bean。 如评论中所述,您可以使用生产者,但不能拦截生产的bean(此处使用@Transaction

如果你想保留你的模式,你将不得不创建一个非常复杂的扩展,因为它应该在低级别工作,以确保拦截器被激活。

我建议您在ExternalHandle Bean中逐出Handle分辨率,以便使用String来构建它。

首先使用非绑定成员创建一个限定符,以将信息传递给构造函数。

@Target({TYPE, METHOD, PARAMETER, FIELD})
@Retention(RUNTIME)
@Documented
@Qualifier
public @interface Keyed {

    @Nonbinding
    String key();
}

然后为注释创建文字,以允许创建具有给定key值的注释实例。

public class KeyedLiteral extends AnnotationLiteral<Keyed> implements Keyed {

    private final String key;

    public KeyedLiteral(String key) {
        this.key = key;
    }

    @Override
    public String key() {
        return key;
    }
}

使用programmatic查询和InjectionPoint传输您的密钥值。你的代码就像:

@Applicationscoped
@Transactional(txtype.Requires_new)
Public class querybean {
    @Inject
    @Any
    Instance<Handle> handles;

    Public Handle gethandleByKey(String key) {
        return instances.select(new KeyedLiteral(key)).get()
    }

    @Dependent
    @Transactional
    @Keyed("") //enforce the presence of the annotation for the constructor
    Public static class Handle {

        ExternalHandle eh;

        // needed to make the bean proxyable (mandatory for the interceptor bound)) 
        Protected Handle() {}

        @Inject
        Protected Handle(InjectionPoint ip, ExternalSysrltem externalSystem) {
            String key=ip.getAnnotated().getAnnotation(Keyed.class).key();
            eh = /*do external Systems Query, returns an ExternalHandle Object from key and externalSystem*/
        }

        Public String getHandleInfo() {
            Return This.eh.getName() + "/" + this.eh.getState()..;
            /*generally wrap the ExternallHandle with businesslogic to hide direct access to the complex ExternalService's Interface*/
        }
    }
}