我可以影响CDI制作人的回归类型吗?

时间:2014-07-31 05:04:48

标签: java cdi

我正在使用CDI注入Hessian服务器连接,这使我能够创建不同的服务代理。

简单示例:

@Inject HessianServer server;

NameService service;

@PostConstruct
private void init{
    service  = server.getProxy(NameService.class);
}

这很好用。但我必须启动许多服务。因此,我宁愿只是注入服务。

我自己构建了一个ServiceProducer类,它根据参数化的CDI限定符创建服务:

@Inject HessianServer server;

@Produces
@Service(serviceType = ServiceType.NAME)
NameService produce(){
    return server.getProxy(NameService.class);
}

现在我可以注入服务:

@Inject
@Service(serviceType = ServiceType.NAME)
NameService nameService;

但我需要为我想要制作的任何服务提供这样的制作方法。

我想改进Producer类,以根据限定符参数生成适合的服务实现。然后我只需要一个生产方法而不是每个我想要生产的服务。 因此,我传递classType,而不是在CDI限定符中传递枚举值。 例如,像这样的东西。

@Produces
@Service(serviceType = NameService.class)
_whatMustIReturnHere_ produce(InjectionPoint ip){
    Service service = injectionPoint.getAnnotated().getAnnotation(Service.class);
    return server.getProxy(service.getServiceType); 
}

问题是:是否甚至可以根据传递的限定符参数影响产品方法的返回类型?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:0)

虽然生成器方法的默认bean类型是Bean types of a producer method中指定的返回类型的闭包,但可以使用Portable extensions机制覆盖类型集。

为了满足您的需求,您可以创建一个CDI扩展,观察ProcessBeanAttributes事件,并覆盖相应的BeanAttributes信息,例如:

class ServiceExtension implements Extension {

    void overrideBean(@Observes final ProcessBeanAttributes<NameService> pba) {
        pba.setBeanAttributes(new BeanAttributes<NameService>() {

            public Set<Type> getTypes() {
                Set<Type> types = new HashSet<>(pba.getBeanAttributes().getTypes());
                types.add(_whatMustIReturnHere_);
                return types;
            }

            public Set<Annotation> getQualifiers() {
                return pba.getBeanAttributes().getQualifiers();
            }

            public Class<? extends Annotation> getScope() {
                return pba.getBeanAttributes().getScope();
            }

            public String getName() {
                return pba.getBeanAttributes().getName();
            }

            public Set<Class<? extends Annotation>> getStereotypes() {
                return pba.getBeanAttributes().getStereotypes();
            }

            public boolean isAlternative() {
                return pba.getBeanAttributes().isAlternative();
            }
        };
    }
}

该方法的优点在于它仍然依赖于Typesafe resolution机制,因此如果存在模糊或不满足的依赖关系,您将获得在部署应用程序期间抛出的标准异常。