【问题标题】:Can I influence the return type of a CDI producer?我可以影响 CDI 生产者的返回类型吗?
【发布时间】:2014-07-31 05:04:47
【问题描述】:

我正在使用 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;

但是我需要这样一种生产方法来处理我想要生产的任何类型的服务。

我想改进生产者类以根据限定符参数生成合适的服务实现。然后我只需要一种生产方法,而不是为我想要生产的每个服务提供一种方法。 因此,我没有在 CDI 限定符中传递枚举值,而是传递了 classType。 比如这样的。

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

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

【问题讨论】:

  • 您的所有实现至少需要一个通用接口或超类型。
  • 嗯。这是不可能的,因为我无法影响接口及其实现。所以我想答案很简单:不,不可能。
  • 是的。这就是 cdi 的工作原理。容器需要注入一个实例并寻找一个生产者。因此,您将需要一个返回该类型的生产者。
  • 感谢您的洞察力。

标签: java cdi


【解决方案1】:

虽然生产者方法的默认 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 机制,因此如果存在不明确或不满足的依赖关系,您将在应用程序部署期间获得标准异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-04
    • 2023-03-29
    • 2013-06-16
    • 1970-01-01
    • 2015-04-08
    • 1970-01-01
    • 2022-10-12
    • 1970-01-01
    相关资源
    最近更新 更多