迁移到 CDI 1.2 焊接异常
Migrating to CDI 1.2 WELD Exception
在 Liberty 中迁移到 CDI 1.2 后,我的应用程序开始抛出一个 WELD 异常,我不清楚如何解决:
org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: Unsatisfied dependencies for type DataHandler with qualifiers @Any @DataHandlerBean WELD-001475: The following beans match by type, but none have matching qualifiers:
- Session bean [class com.ibm.blueargus.feed.PathSquadHandler with qualifiers [@DataHandlerBean @Any]; local interfaces are [DataHandler],
- Session bean [class com.ibm.blueargus.feed.DownAccessPointDataHandler with qualifiers [@DataHandlerBean @Named @Any]; local interfaces are [DataHandler],
- Session bean [class com.ibm.blueargus.feed.ATTTicketDataHandler with qualifiers [@DataHandlerBean @Any]; local interfaces are [DataHandler],
- Session bean [class com.ibm.blueargus.feed.WirelessClientDataHandler with qualifiers [@Named @DataHandlerBean @Any]; local interfaces are [DataHandler]
这发生在我select基于自定义注释值创建 bean 时 - 应用程序需要能够根据存储在数据库中的条件执行特定的 EJB 实现。如何更新我的代码以使用 CDI 1.1 并仍然允许基于自定义限定符值的 EJB 实现的动态 selection?有没有更好的方法可以提供相同的一般功能?
限定符规范
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface DataHandlerBean {
String value();
}
注释实现:
public class DataHandlerBeanQualifier extends AnnotationLiteral <DataHandlerBean> implements DataHandlerBean {
private String value;
public DataHandlerBeanQualifier (String value) {
this.value=value;
}
@Override
public String value() {
return this.value;
}
}
EJB 接口:
@Local
public interface DataHandler {
public void extractData (Monitor monitor, DataFeed dataFeed) throws Exception;
}
示例 EJB 实现:
@Stateless
@DataHandlerBean("downAccessPointHandler")
public class DownAccessPointDataHandler implements DataHandler {
导致问题的业务逻辑 EJB(片段):
monitor.getDataHandler() 中的值用于 select 适当的 EJB 实现以传递控制以进行进一步处理。
@Stateless
public class DataScannerImpl implements DataScanner {
public static Logger logger = Logger.getLogger(DataScanner.class.getName());
@Inject
@Any
private Instance <DataHandler> dataHandlerInstance;
private String processMonitorList(List <Monitor> monitorList, boolean forceLoad) {
...
try {
dataHandler = dataHandlerInstance.select(new DataHandlerBeanQualifier(monitor.getDataHandler())).get();
dataHandler.extractData(monitor, dataFeed);
monitor.setDataFeed(dataFeed);
} catch ( Exception e ) {
e.printStackTrace();
logger.warn("Could not execute dataHandler: " + monitor.getDataHandler(), e);
}
...
}
}
这一切在我以前的 WebSphere v8.5 生产环境中都运行良好。 Web 应用程序使用的是 CDI 1.0。
当前环境(server.xml):
<featureManager>
<feature>javaee-7.0</feature>
<feature>webProfile-7.0</feature>
<feature>ejbPersistentTimer-3.2</feature>
<feature>ldapRegistry-3.0</feature>
<feature>appSecurity-2.0</feature>
<feature>localConnector-1.0</feature>
<feature>jaxrs-2.0</feature>
<feature>jaxrsClient-2.0</feature>
<feature>servlet-3.1</feature>
<feature>jpa-2.1</feature>
</featureManager>
您必须有一个 @Producer
方法,该方法将通过实现 DataScanner
接口
的 4 类 注入
4 类 必须用 4 个不同的注释进行注释
根据您的业务逻辑,生产者将select和"produce"正确实施
然后你可以在你需要的地方直接注入"DataScanner"
:
@Inject
private DataHandler dataHandlerInstance;
中有描述
在文档中,生产者在 "PaymentProcessor"
接口的两种实现之间进行选择:"@Synchronous PaymentProcessor syncPaymentProcessor"
和 "@Asynchronous PaymentProcessor asyncPaymentProcessor"
问题是由数据库值中的拼写错误引起的,导致 monitor.getDataHandler()
到 return bean 名称的值实际上并不存在。
在 Liberty 中迁移到 CDI 1.2 后,我的应用程序开始抛出一个 WELD 异常,我不清楚如何解决:
org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: Unsatisfied dependencies for type DataHandler with qualifiers @Any @DataHandlerBean WELD-001475: The following beans match by type, but none have matching qualifiers:
- Session bean [class com.ibm.blueargus.feed.PathSquadHandler with qualifiers [@DataHandlerBean @Any]; local interfaces are [DataHandler],
- Session bean [class com.ibm.blueargus.feed.DownAccessPointDataHandler with qualifiers [@DataHandlerBean @Named @Any]; local interfaces are [DataHandler],
- Session bean [class com.ibm.blueargus.feed.ATTTicketDataHandler with qualifiers [@DataHandlerBean @Any]; local interfaces are [DataHandler],
- Session bean [class com.ibm.blueargus.feed.WirelessClientDataHandler with qualifiers [@Named @DataHandlerBean @Any]; local interfaces are [DataHandler]
这发生在我select基于自定义注释值创建 bean 时 - 应用程序需要能够根据存储在数据库中的条件执行特定的 EJB 实现。如何更新我的代码以使用 CDI 1.1 并仍然允许基于自定义限定符值的 EJB 实现的动态 selection?有没有更好的方法可以提供相同的一般功能?
限定符规范
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface DataHandlerBean {
String value();
}
注释实现:
public class DataHandlerBeanQualifier extends AnnotationLiteral <DataHandlerBean> implements DataHandlerBean {
private String value;
public DataHandlerBeanQualifier (String value) {
this.value=value;
}
@Override
public String value() {
return this.value;
}
}
EJB 接口:
@Local
public interface DataHandler {
public void extractData (Monitor monitor, DataFeed dataFeed) throws Exception;
}
示例 EJB 实现:
@Stateless
@DataHandlerBean("downAccessPointHandler")
public class DownAccessPointDataHandler implements DataHandler {
导致问题的业务逻辑 EJB(片段): monitor.getDataHandler() 中的值用于 select 适当的 EJB 实现以传递控制以进行进一步处理。
@Stateless
public class DataScannerImpl implements DataScanner {
public static Logger logger = Logger.getLogger(DataScanner.class.getName());
@Inject
@Any
private Instance <DataHandler> dataHandlerInstance;
private String processMonitorList(List <Monitor> monitorList, boolean forceLoad) {
...
try {
dataHandler = dataHandlerInstance.select(new DataHandlerBeanQualifier(monitor.getDataHandler())).get();
dataHandler.extractData(monitor, dataFeed);
monitor.setDataFeed(dataFeed);
} catch ( Exception e ) {
e.printStackTrace();
logger.warn("Could not execute dataHandler: " + monitor.getDataHandler(), e);
}
...
}
}
这一切在我以前的 WebSphere v8.5 生产环境中都运行良好。 Web 应用程序使用的是 CDI 1.0。
当前环境(server.xml):
<featureManager>
<feature>javaee-7.0</feature>
<feature>webProfile-7.0</feature>
<feature>ejbPersistentTimer-3.2</feature>
<feature>ldapRegistry-3.0</feature>
<feature>appSecurity-2.0</feature>
<feature>localConnector-1.0</feature>
<feature>jaxrs-2.0</feature>
<feature>jaxrsClient-2.0</feature>
<feature>servlet-3.1</feature>
<feature>jpa-2.1</feature>
</featureManager>
您必须有一个 @Producer
方法,该方法将通过实现 DataScanner
接口
的 4 类 注入
4 类 必须用 4 个不同的注释进行注释
根据您的业务逻辑,生产者将select和"produce"正确实施
然后你可以在你需要的地方直接注入"DataScanner"
:
@Inject
private DataHandler dataHandlerInstance;
中有描述
在文档中,生产者在 "PaymentProcessor"
接口的两种实现之间进行选择:"@Synchronous PaymentProcessor syncPaymentProcessor"
和 "@Asynchronous PaymentProcessor asyncPaymentProcessor"
问题是由数据库值中的拼写错误引起的,导致 monitor.getDataHandler()
到 return bean 名称的值实际上并不存在。