如何使用泛型类型的@Inject对象

时间:2013-11-15 14:51:31

标签: java java-ee cdi vaadin7

我正在我们公司的项目工作,我有一个注入对象的问题。我们考虑一下这个实体提供者:

@Stateless
@TransactionManagement 
public class EntityProviderBean<T> extends CachingMutableLocalEntityProvider<T> {

    public EntityProviderBean(Class<T> entityClass) {
        super(entityClass);
        setTransactionsHandledByProvider(false);
    }

    @PersistenceContext(unitName = CoreApplication.PERSISTENCE_UNIT)
    private EntityManager em;

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    protected void runInTransaction(Runnable operation) {
        super.runInTransaction(operation);
    }

    @PostConstruct
    public void init() {
        setEntityManager(em);
        setEntitiesDetached(false);
    }
}

并使用上面的实体提供程序扩展JPAContainer

@UIScoped
public class IncidentContainer extends JPAContainer<Incident> {

    private static final long serialVersionUID = 8360570718602579751L;

    @Inject
    EntityProviderBean<Incident> provider;

    public IncidentContainer() {
        super(Incident.class);
    }

    @PostConstruct
    protected void init() {
        setEntityProvider(provider);
    }

}

问题是(并且我理解)我无法使用类型定义@Inject对象,因为inject方法需要空白构造函数。在这里是某种解决方案如何使其工作?现在我得到了异常

org.apache.webbeans.util.InjectionExceptionUtils.throwUnsatisfiedResolutionException(InjectionExceptionUtils.java:77)

非常感谢答案:) 的Ondrej

2 个答案:

答案 0 :(得分:1)

AFAIK Bean需要一个没有参数可被注入的构造函数,或者也必须注入所有构造函数参数。您将无法满足这些要求。

答案 1 :(得分:0)

Consrtutor Injection

当CDI容器实例化bean类时,它会调用CDI bean的bean构造函数。

CDI查找默认的bean构造函数或使用@Inject注释以获取bean的实例。

  • 如果CDI bean没有使用@Inject显式声明构造函数,CDI容器将不接受任何参数/默认bean构造函数。
  • CDI bean构造函数可以有任意数量的参数,容器初始化/注入所有这些参数  作为bean构造函数的注入点的参数。
  • CDI bean类只能使用@Inject注释单个构造函数。如果CDI容器找到多个使用@Inject注释的构造函数,则会抛出错误。
  

它允许bean构造函数注入的一个优点   bean是不可变的。

您的案例中的问题是

IncidentContainer bean类没有任何默认构造函数或使用@Injection注释的构造函数。

您可以设置如下

public class IncidentContainer extends JPAContainer<Incident> {

    // @Inject no need to do filed injection here
    private EntityProviderBean<Incident> provider;

    @Inject // add this one
    public IncidentContainer(EntityProviderBean<Incident> provider) {
        super(Incident.class);
        this.provider = provider;
    }

    @PostConstruct
    protected void init() {
        setEntityProvider(provider);
    }
}

EntityProviderBean bean类没有任何默认构造函数或使用@Injection注释的构造函数。

您可以设置如下

public class EntityProviderBean<T> extends CachingMutableLocalEntityProvider<T> {

    public EntityProviderBean(Class<T> entityClass) {
        super(entityClass);
        setTransactionsHandledByProvider(false);
    }
    // add this cdi bean construtor
    @Inject
    public EntityProviderBean(Incident incident) {
        this((Class<T>) incident.getClass());
    }

    protected void runInTransaction(String operation) {
        super.runInTransaction(operation);
    }
}