【问题标题】:How to @Inject object with generic type如何@Inject 具有泛型类型的对象
【发布时间】:2013-11-15 14:51:31
【问题描述】:

我正在我们公司从事项目,但在注入对象时遇到问题。让我们考虑一下我有这个实体提供者:

@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 对象,因为注入方法需要空白构造函数。这里有某种解决方案如何使它起作用吗?现在我遇到了异常

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

非常感谢您的回答 :) 翁德瑞

【问题讨论】:

    标签: java jakarta-ee cdi vaadin7


    【解决方案1】:

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

    【讨论】:

    • 是的,我知道 :) 我很好奇是否有某种我不知道的解决方案。否则,我将列出明确创建的这些容器。
    • 在我的项目中,我刚刚为用于 JPAContainer 的每个实体创建了一个提供程序类。
    【解决方案2】:

    Consrtutor 注入

    当 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);
        }
    }
    

    【讨论】:

    • 嘿,谢谢你的想法,但是当我想在某个地方@Inject IncidentContainer 时,我仍然遇到同样的错误。
    • 终于让它工作了。我可以注入 IncidentContainer,但是当我想将一些实体保存到其中时,我得到了javax.persistence.TransactionRequiredException。那是因为@TransactionManagement 注释,这显然不起作用:(你有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 2016-05-05
    • 2013-01-08
    • 1970-01-01
    • 2014-08-14
    • 2022-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多