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

时间:2014-09-19 11:42:40

标签: generics cdi nested-generics

我有GenericCrudController<E>封装了我的GenericCrudBO<E>的实例,而我的GenericCrudBO<E>封装了我的GenericCrudDAO<E>的实例。所以,我想要做的是,例如,我的GenericCrudController<User>默认情况下具有GenericCrudBO<User>的实现,如果有的话,当然。如果没有,我想坚持通用实现。我在项目中使用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*/}

这些是通用结构实现的一些例子:

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

现在请注意,我必须手动注入UserBO的实例并覆盖搜索方法,以便能够实现调用UserBO的搜索方法而不是GenericCrudBO的目标。我要问的是,是否可以使用某些CDI注释来执行此操作,迫使处理器根据控制器的泛型类型注入正确实现的实例。感谢

1 个答案:

答案 0 :(得分:0)

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

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

public CrudBO<T> getBo() {
    return bo.get();
}

为了说清楚,CrudBO是GenericCrudBO实现的接口,因此, 知道默认情况下GenericCrudBO是用@Default注释的,我用@Alternative注释了专门的类:

@Alternative
public class SpecializedCrudBO extends GenericCrudBO<SpecificClass>{
}

我还在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>

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