我有一个带有2个模块的EAR应用程序。一个WEB和一个EJB模块。
EJB模块中有一些服务被注入到WEB模块的类中,效果很好。但是某些服务需要基于用户上下文的配置,该配置仅在WEB模块中可用。因此,我尝试将生产者添加到WEB模块。
结构如下:
app-ear
|
+- app-ejb
| |
| +- Service
| +- ServiceConnector
|
+- app-web
|
+- ServiceConnectorProducer
这是该代码的简化版本:
将连接器注入到(EJB)中的服务类
public class Service {
@Inject
private ServiceConnector connector;
}
将处理服务连接的连接器类:(EJB)
public class ServiceConnector {
private final Config config;
public ServiceConnector(final Config config) {
this.config = config;
}
}
ServiceConnector
的制作人:(WEB)
public class ServiceConnectorProducer {
@Produces
public ServiceConnector produce(UserContext userCtx) {
// ... create config and set data from user context
return new ServiceConnector(config);
}
}
这时在注入点无法识别生产者,并且我得到了一个不满意的依赖性错误:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type ServiceConnector with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private Service.connector
at Service.connector(Service.java:0)
即使生产者是由容器加载的,也会发生这种情况:
WELD-000106: Bean: Producer Method [ServiceConenctor] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces public ServiceConenctorProducer.produce(UserContext)]
当我通过添加默认构造函数使ServiceConnector
可以被容器发现时,却出现了模棱两可的依赖项错误:
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type ServiceConnector with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private Service.connector
at Service.connector(Service.java:0)
Possible dependencies:
- Producer Method [ServiceConnector] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces public ServiceConnector.produce(UserContext)],
- Managed Bean [class ServiceConnector] with qualifiers [@Any @Default]
之后,我尝试了以下方法来解决模棱两可的依赖关系。
-https://stackoverflow.com/a/22985035(添加限定词)
-https://stackoverflow.com/a/36056972(使用@Any
)
-https://stackoverflow.com/a/29449040/11117616(使用@Vetoed
)
但是所有这些解决方案都会导致未满足的依赖性错误。
WELD-001408: Unsatisfied dependencies for type ServiceConnector with qualifiers @SessionService
at injection point [BackedAnnotatedField] @Inject @SessionService private Service.connector
at Service.connector(Service.java:0)
WELD-001475: The following beans match by type, but none have matching qualifiers:
- Managed Bean [class ServiceConnector] with qualifiers [@Any @Default]
因此,我现在不知道如何解决情况。如何获得ServiceConnector
才能在WEB模块中生成?
答案 0 :(得分:0)
您最有可能遵守Java EE伞规范的可见性限制。 EAR中某些档案(EAR / lib,EJB jar,WAR)可以查看和访问的内容受到限制。然后,CDI在注入时遵循相同的模式。
根据应用服务器解释规范的方式,这些规则的实现可能会略有不同。现在,如果您不想阅读规范(谁做了,嗯?;-),那么您可以at this SO answer进行总结,尽管并不详尽。
也就是说,在您的情况下,WAR文件可以访问EJB的内容,反之亦然。 用CDI术语来说,这意味着EJB jar不会“看到”您在那里的生产者方法。
对于当您使ServiceConnector
一个bean时看到的模棱两可的依赖异常-我不确定100%没有复制器和一些调试是什么。这可能是在EAR中完成验证的方式的错误,也可能是有意的,因为从理论上讲,从WAR档案库中您可以看到两个ServiceConnector
类型的bean。
关于如何解决此问题-我能想到的一件事是CDI扩展(按照Weld的解释)横跨整个EAR。因此,无论使用哪种存档,使用CDI扩展名来注册Bean 都可能为您工作。如果您采用这种方式,请查看AfterBeanDiscovery
observer并在那里注册bean。