我有一个Java 8项目和一个JBoss 7.1.0GA服务器。
我有一个带有全局变量的批处理类
@EJB
public MyInterface delegate;
在我的ejb-jar.xml中定义为DelegateClass的实例:
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" version="3.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd">
<module-name>moduleName</module-name>
<enterprise-beans>
<session>
<ejb-name>ejbName</ejb-name>
<business-remote>MyInterface</business-remote>
<ejb-class>DelegateClass</ejb-class>
<session-type>Stateless</session-type>
</session>
</enterprise-beans>
我有MyInterface的一些实现,因此在我的类DelegateClass中,我想包装MyInterface的实现并通过枚举常量对其进行设置。
这里的代码:
@Stateless
@LocalBean
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class DelegateClass implements MyInterface {
@Inject
@Any
protected Instance<MyInterface> instance;
protected MyInterface selectedImpl;
@PostConstruct
public void init() {
selectedImpl = instance.select(MyLiteralAnnotation.create(MyEnum.value)).get();
}
这是我的文字注释类的代码:
public class MyLiteralAnnotation extends AnnotationLiteral<MyAnnotation> implements MyAnnotation {
private final MyEnum value;
private MyLiteralAnnotation(MyEnum value) {
this.value = value;
}
@Override
public MyEnum getValue() {
return value;
}
public static MyLiteralAnnotation create(MyEnum value) {
return new MyLiteralAnnotation(value);
}
}
我创建的注释:
@Retention(RetentionPolicy.RUNTIME)
@Target({ TYPE, METHOD, FIELD, PARAMETER, CONSTRUCTOR })
@Qualifier
public @interface MyAnnotation {
MyEnum getValue();
}
以及我想从instance.select(...)获得的实现
@Stateless
@LocalBean
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@MyAnnotation(MyEnum.value)
public class MyInterfaceImpl implements MyInterface {
....
}
我在服务器上调试了该应用程序,但是当我尝试使用instance.select(...)实例化selectImpl字段时,我有一个例外:
org.jboss.weld.exceptions.UnsatisfiedResolutionException WELD-001334类型为MyInterface的不合格依赖项,带有限定符@Any @MyAnnotation
有谁可以帮助我吗 ?
最佳答案
似乎发生异常是因为CDI找不到用@Any和@MyAnnotation注释的bean,因为要选择的bean仅用@MyAnnotation注释。我认为@Any在实例注入时没有必要,因为Instance能够访问MyInterface的所有实现,因此您可以选择使用@MyAnnotation(MyEnum.value)注释的实例。我从未将Instance与使用枚举的限定符一起使用。
我认为您不需要使用Instace。
以下注射无效吗?
class MyDelegate implements MyInterface{
@Inject
@MyAnnotation(MyEnum.value)
private MyInterface myInterface;
}
如果您需要委托给另一个实现,则可能需要CDI装饰器。
@Decorator
@Default // We decorate the default implementation of MyInterface or any qualified
// one you need to decorate
abstract class MyDecorator implements MyInterface {
@Inject
@MyAnnotation(MyEnum.value)
private MyInterface myInterface;
@Inject
@Delegate
private MyInterface delegate;
// Implement all methods you want to decroate
public void myMethod(){
if(condition) {
myInterface.myMethod();
} else {
delegate.myMethod();
}
}
}
您需要在beans.xml中注册装饰器
<decorators>
<class>MyDecorator</class>
</decorators>
这对您有帮助吗?