Решите, какую реализацию использовать в @Inject

У меня есть 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 ответ

Решение

Я решил проблему, используя объект 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>{
}

Я также объявил альтернативные BO и DAO в beans.xml:

<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-бины во время выполнения, это очень хорошо также потому, что мне не нужно создавать тонны шаблонных классов.

Другие вопросы по тегам