当前位置: 首页 > 知识库问答 >
问题:

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

衡丰茂
2023-03-14

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

@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个答案

钱澄邈
2023-03-14

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

CDI寻找缺省的bean构造函数或者用@Inject注释的构造函数来获取bean的实例。

    < li >如果CDI bean没有使用@Inject显式声明构造函数,则CDI容器不会接受任何参数/默认bean构造函数。 < li>CDI bean构造函数可以有任意数量的参数,并且容器初始化/注入所有这些< br >参数,这些参数是bean构造函数的注入点。 < li>CDI bean类只能有一个带@Inject批注的构造函数。如果CDI容器发现多个用@Inject注释的构造函数,那么它抛出错误。

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

你的问题是

顺便说一句,容器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);
    }
}
耿炎彬
2023-03-14

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

 类似资料:
  • 考虑一个具有的API,如下所示: 很简单,只有页面大小和跳过计数属性。 此外,现在我还有一些类,它们也包含但未分页。 在我的测试中,我希望他们都能实现一个接口,这样我就可以用一些更基本的测试来生成一个通用的基本测试类。为此,我添加了我认为会起作用的内容: 我将PagedResults更改为: 错误 但现在编译器抱怨PagedResultBase继承的所有地方的使用情况(?)从。 但是,如果我将接口

  • 我在我的一个实用程序类中有一个方法,它接受一个集合和一个类对象,并返回一个Iterable实例,该实例可以遍历作为指定类实例的集合的所有成员。其签名为: 这对于大多数用例都非常有效,但现在我需要将其与泛型类

  • 问题内容: 我对此进行了扩展,应该可以帮助我在上下文之间传输对象: 现在它返回的对象,我应该将其强制转换为我想要的类,如下所示: 有没有办法避免这种无用的转换,如果我从类的对象调用使其返回类型? 问题答案: 更新: 有关更好的解决方案 与如何在NSManagedObjectSwift扩展中如何创建托管对象子类的实例中类似,这可以使用通用的辅助方法来完成: 请注意,我已将返回类型更改为。 并 没有

  • 现在,当我在地图上迭代时…我能以某种方式获得每个Class1对象的类型(K,V)吗??

  • 我有一个从数组中检索元素的方法,我想对几个基元类型(int[]、double[]、...)使用相同的方法。方法如下: 但是,如何获取数据的类型以使用适当的基元类型实例化selectedElements数组? 非常感谢

  • 问题内容: 我有课 和班级 关键是该方法不安全,因为我可以提供的项目与当前报告无关,但与其他报告相关,编译器不会抱怨。 是否可以用类型安全的方式编写该方法,即我们可以仅将T作为当前报表的类型作为参数传递。 问题答案: 我认为您正在寻找以下内容。 它的工作方式是: 您想用从 您要确保所有列表都属于同一类型 为了将参数绑定到从扩展的对象,您需要对自身进行参数化: 您添加需要从报表扩展的绑定 但是您要