Generics 决定在@Inject中使用什么实现

Generics 决定在@Inject中使用什么实现,generics,cdi,nested-generics,Generics,Cdi,Nested Generics,我有一个GenericCrudController,它封装了我的GenericCrudBO的一个实例,我的GenericCrudBO封装了我的GenericCrudDAO的一个实例。因此,我想做的是,例如,我的GenericCrudController默认具有GenericCrudBO的实现,当然,如果有的话。如果不是,我想坚持使用通用实现。我在项目中使用CDI,我认为这是一种方法,但我不知道使用什么注释。接下来是上述结构和场景: public abstract class GenericCon

我有一个
GenericCrudController
,它封装了我的
GenericCrudBO
的一个实例,我的
GenericCrudBO
封装了我的
GenericCrudDAO
的一个实例。因此,我想做的是,例如,我的
GenericCrudController
默认具有
GenericCrudBO
的实现,当然,如果有的话。如果不是,我想坚持使用通用实现。我在项目中使用CDI,我认为这是一种方法,但我不知道使用什么注释。接下来是上述结构和场景:

public abstract class GenericController<T extends BaseEntity> implements Serializable {
    private static final long serialVersionUID = 1L;

    protected List<T> list;
    protected T entity;
    protected T filter;

    @Inject
    @Named("crudBO")
    protected CrudBO<T> bo;

    /*IRRELEVANT CODE GOES THERE */
}

@Named("crudBO")
public class GenericCrudBO<E extends BaseEntity> implements CrudBO<E>{
    private static final long serialVersionUID = 1L;

    @Inject
    @Named("crudDAO")
    protected GenericCrudDAO<E> dao;

    @Override
    @SuppressWarnings("unchecked")
    public List<E> search(E filter) {
        Class<E> clazz = (Class<E>) filter.getClass();
        return dao.search(clazz, filter);
    }

    /*IRRELEVANT CODE GOES THERE*/
}

@Named("crudDAO")
public class GenericCrudDAO<E extends BaseEntity> implements CrudDAO<E>{/*IRRELEVANT CODE GOES THERE*/}
公共抽象类GenericController实现可序列化{
私有静态最终长serialVersionUID=1L;
受保护名单;
受保护的T实体;
受保护的T型过滤器;
@注入
@命名(“crudBO”)
受保护的CrudBO bo;
/*不相关的代码就在那里*/
}
@命名(“crudBO”)
公共类GenericCrudBO实现CrudBO{
私有静态最终长serialVersionUID=1L;
@注入
@命名为(“克鲁多”)
受保护的通用CRUDDAO dao;
@凌驾
@抑制警告(“未选中”)
公共列表搜索(E过滤器){
Class clazz=(Class)filter.getClass();
返回dao.search(clazz,filter);
}
/*不相关的代码就在那里*/
}
@命名为(“克鲁多”)
公共类GenericCrudDAO实现CrudDAO{/*不相关的代码在那里*/}
以下是通用结构实施的一些示例:

public class UserBO extends GenericCrudBO<User>{
    /*IRRELEVANT CODE GOES THERE*/
    @Override
    public List<User> search(User filter) {
        /*SPEFIFIC CODE*/
    }
}

@Named(value="userController")
@ViewScoped
public class UserController extends GenericController<User>{ 

    @Inject private UserBO userBO;

    @Override
    public void search() {
        if(filter != null) {
            list = userBO.search(filter);
        } else throw new RuntimeException();
    }
}
public类UserBO扩展了GenericCrudBO{
/*不相关的代码就在那里*/
@凌驾
公共列表搜索(用户筛选器){
/*特殊码*/
}
}
@命名(value=“userController”)
@视域
公共类UserController扩展了GenericController{
@注入私有UserBO-UserBO;
@凌驾
公开无效搜索(){
if(过滤器!=null){
list=userBO.search(过滤器);
}否则抛出新的RuntimeException();
}
}

现在请注意,我必须手动注入UserBO的一个实例并重写search方法,以实现调用UserBO的search方法而不是GenericCrudBO方法的目标。我要问的是,是否可以使用一些CDI注释来实现,强制处理器根据控制器的泛型类型注入正确实现的实例。谢谢

我使用javax.enterprise.inject.Instance对象来封装我的bo和dao解决了这个问题。这样:

@Inject
private Instance<CrudBO<T>> bo;

public CrudBO<T> getBo() {
    return bo.get();
}
@Inject
私人诉讼;
公共CrudBO getBo(){
返回bo.get();
}
让我们清楚一点,CrudBO是GenericCrudBO实现的接口, 知道默认情况下GenericCrudBO是用@default注释的,我用@Alternative注释了专用类:

@Alternative
public class SpecializedCrudBO extends GenericCrudBO<SpecificClass>{
}
@备选方案
公共类SpecializedCrudBO扩展了GenericCrudBO{
}
我还在beans.xml中声明了BO和DAO的备选方案:

<beans xmlns="http://java.sun.com/xml/ns/javaee" 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/beans_1_0.xsd">

    <alternatives>
        <class>br.com.logtec.business.SpecializedCrudBO</class>
        ...
    </alternatives>

</beans>

br.com.logtec.business.SpecializedCrudBO
...

现在,CDI可以在运行时处理我的通用java bean,这也非常好,因为我不必创建大量的样板类。

我只是通过手动实现嵌套类型的具体实例来做到这一点。由于java泛型的性质,我想没有更好的方法了。但我很高兴被证明是错的。如果你能提供一个具体的例子,那会有所帮助。到底什么是失败的?只是按照你的要求添加了一些具体的例子,希望能有所帮助:)@JohnAment