Java 没有为注入创建接口的 EE bean
Java EE bean with interface not being created for injection
我有一个简单的案例,我有一个 REST 服务 MyService
,应该注入一个 BeanB
类型的 bean beanB
,它实现了接口 BeanBInterface
。我得到的错误是 classic WELD-001408 如下所示:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type BeanBInterface with qualifiers @BeanBQualifier
at injection point [BackedAnnotatedField] @Inject @BeanBQualifier public com.example.MyService.beanB
at com.example.MyService.beanB(MyService.java:0)
REST 服务:
import javax.ws.rs.Path;
import javax.inject.Inject;
@Path("/")
public class MyService {
@Inject
@BeanBQualifier(BeanBQualifier.Type.PROD)
public BeanBInterface beanB;
public MyService() {}
}
Bean 接口:
public interface BeanBInterface {
}
Bean 实现:
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.enterprise.inject.Produces;
@Startup
@Singleton
@BeanBQualifier(BeanBQualifier.Type.PROD)
public class BeanB implements BeanBInterface {
private String name = "B";
public BeanB() {}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
}
Bean 限定词
import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE})
public @interface BeanBQualifier {
Type value();
enum Type{PROD, TEST}
}
Beans.xml(在 META-INF/beans.xml 中尝试过,也在 WEB-INF/beans.xml 中尝试过)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="annotated">
</beans>
我也试过 bean-discovery-mode="all"
但没有成功。
如果我将 beanB
声明为使用具体的 class BeanB
而不是它在 MyService
中的接口,它就可以工作(但这违背了界面):
如果我向 MyService
添加一个 @Produces
工厂方法来构建 bean,它也可以工作,但这违背了让容器为我实例化我的 bean 的目的:
@javax.enterprise.inject.Produces
public static BeanB get() {
return new BeanB();
}
但是如果这个@Produces 工厂方法returns 接口将不起作用:
@javax.enterprise.inject.Produces
public static BeanBInterface get() {
return new BeanB();
}
EJB 有一些关于哪些接口实际公开为实现的奇怪规则。只有标记为@Local/@Remote 的接口才会被公开。如果要将 bean 与接口和 class 一起使用,则需要将 @LocalBean 添加到 ejb。
简而言之:在接口中添加@Local或在BeanB中添加@Local(BeanBInterface.class)
我有一个简单的案例,我有一个 REST 服务 MyService
,应该注入一个 BeanB
类型的 bean beanB
,它实现了接口 BeanBInterface
。我得到的错误是 classic WELD-001408 如下所示:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type BeanBInterface with qualifiers @BeanBQualifier
at injection point [BackedAnnotatedField] @Inject @BeanBQualifier public com.example.MyService.beanB
at com.example.MyService.beanB(MyService.java:0)
REST 服务:
import javax.ws.rs.Path;
import javax.inject.Inject;
@Path("/")
public class MyService {
@Inject
@BeanBQualifier(BeanBQualifier.Type.PROD)
public BeanBInterface beanB;
public MyService() {}
}
Bean 接口:
public interface BeanBInterface {
}
Bean 实现:
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.enterprise.inject.Produces;
@Startup
@Singleton
@BeanBQualifier(BeanBQualifier.Type.PROD)
public class BeanB implements BeanBInterface {
private String name = "B";
public BeanB() {}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
}
Bean 限定词
import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE})
public @interface BeanBQualifier {
Type value();
enum Type{PROD, TEST}
}
Beans.xml(在 META-INF/beans.xml 中尝试过,也在 WEB-INF/beans.xml 中尝试过)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="annotated">
</beans>
我也试过 bean-discovery-mode="all"
但没有成功。
如果我将 beanB
声明为使用具体的 class BeanB
而不是它在 MyService
中的接口,它就可以工作(但这违背了界面):
如果我向 MyService
添加一个 @Produces
工厂方法来构建 bean,它也可以工作,但这违背了让容器为我实例化我的 bean 的目的:
@javax.enterprise.inject.Produces
public static BeanB get() {
return new BeanB();
}
但是如果这个@Produces 工厂方法returns 接口将不起作用:
@javax.enterprise.inject.Produces
public static BeanBInterface get() {
return new BeanB();
}
EJB 有一些关于哪些接口实际公开为实现的奇怪规则。只有标记为@Local/@Remote 的接口才会被公开。如果要将 bean 与接口和 class 一起使用,则需要将 @LocalBean 添加到 ejb。
简而言之:在接口中添加@Local或在BeanB中添加@Local(BeanBInterface.class)