2015-04-20 3 views
3

В этот вопрос будут находить ссылки my blog post Я написал год назад.Dynamic CDI Injection во время выполнения

Хотя я использую специальный идентификатор CDI для своего DAO, мне хотелось знать, есть ли подход к динамическому внедрению DAO.

Причина, по которой я спрашиваю, заключается в следующем. На данный момент у меня есть 3 квалификатора CDI, @HibernateDAO (для типа Hibernate Session injection DAO), @JPADAO (для JPA конкретных DAO) и @JDBCDAO (для чисто JDBCDAO). Это требует, чтобы я должен был указать его для каждой конкретной реализации и после инъекции.

@Inject @JPADAO 
private CustomerDAO customerDAO; 

Есть ли лучший подход, который позволит мне добавлять различные ароматы DAO без необходимости изменять код, скомпилировать и развернуть?

Я хочу представить MongoDB в следующем выпуске моего проекта, и я думаю, если я могу отойти от @MongoDBDAO и инъекции, как,

@Inject @MongoDBDAO 
private CustomerDAO customerDAO; 

Я знаю, что CDI Injection может позволить по умолчанию и альтернативные инъекции. Я хочу иметь возможность того, что другие разработчики могут использовать переопределение реализации по умолчанию с другим подклассом и иметь возможность вводить его без изменения существующего кода службы.

Что-то этого эффекта:

@Inject @DAO 
private CustomerDAO customerDAO; 

Где @DAO может быть любой DAO любой вкус (даже с 3-й партии) и как-то карта @DAO сначала найти альтернативу, если он не найден, используется реализация по умолчанию ,

Спасибо.

Oh! Это решение должно быть строго работать с последним (как текущее время написания) Спецификация Java EE CDI. Используемая технология:

  • RedHat JBoss Wildfly 8.2.0 Final (полностью совместимый с Java EE 7).
  • Java 8.
  • API Java EE 7 API.

Я не буду использовать решение, использующее Spring Framework, поскольку оно может помочь другим разработчикам Spring.

+3

Вы проверили это? http://docs.oracle.com/javaee/7/tutorial/cdi-adv002.htm#GJSDF – assylias

+0

Gee, спасибо! Как я пропустил это? Позвольте мне заглянуть в нее быстро. :-) –

ответ

2

Если вы хотите ввести Daos в общем во время выполнения, я бы рекомендовал этот подход.

@Qualifier 
@Retention(RUNTIME) 
@Target({TYPE,METHOD,FIELD,PARAMETER}) 
public @interface DAO{ 

    String value(); 
} 

//Dont worry, CDI allows this quite often than not ;) 
public class DAOImpl extends AnnotationLiteral<DAO> implements DAO { 

    private final String name; 
    public DAOImpl(final String name) { 
    this.name = name; 
    } 

    @Override 
    public String value() { 
    return name; 
    } 
} 

Где это необходимо.

@ApplicationScoped; //Or Whatever 
public class MyDAOConsumer { 

    @Inject 
    @Any 
    private Instance<DAOService> daoServices; 

    //Just as an example where you can get the dynamic configurations for selecting daos. 
    //Even from property files, or system property. 
    @Inject 
    private MyDynamicConfigurationService myDanamicConfigurationService; 

    public void doSomethingAtRuntime() { 
    final String daoToUse = myDanamicConfigurationService.getCurrentConfiguredDaoName(); 
    final DAO dao = new DAOImpl(daoToUse); 

    //Careful here if the DaoService does not exist, you will get UnsatisfiedException 
    final DAOService daoService = daoServices.select(dao).get(); 
    daoService.service(); 
    } 
} 

И натолкнувшись, вы можете настроить, какое dao использовать во время работы без пота. И без изменения крошечного кода.

+1

Как разработчики третьей стороны смогут интегрировать свои службы/DAO с использованием этого подхода? Им придется изменить код, добавив их DAO в свой собственный «MyDynamicConfigurationService» и скомпилировать. Должен быть более простой подход, когда они не касаются корневого кода, но имеют настраиваемый код, который может быть зарегистрирован либо с помощью конфигурации XML, либо с аннотацией, а контейнер CDI знает, как вводить его без проблем. –

+2

Я сказал: '' MyDynamicConfigurationService'' - это просто способ получить динамическую конфигурацию. Это может быть системная переменная, которая может быть установлена ​​при запуске системы или во время выполнения. Как вы указываете внешнюю конфигурацию, действительно ваш выбор, но ваше приложение требует конфигурации, не так ли? – maress

+0

Должен ли класс DAOServic реализовывать интерфейс DAO? –

3

Я бы забыл о пользовательских аннотации и использовал метод продюсера. В этом методе вы можете найти класс, который вы хотите создать из файла xml или файла конфигурации, или любым способом, которым вы хотите это сделать.

Взгляните на Producer Methods в учебное пособие по Java EE.

+0

Я хочу избежать пользовательской настройки, так как мне придется познакомить ее с сторонними разработчиками с помощью учебника и обучения. Я хотел бы использовать существующие технологии CDI. –

+0

При создании экземпляров классов с новыми, вы не получите инъекцию CDI в класс. Если вы сделаете это, как показано ниже, это сработает. –

+1

Для этого нужны методы изготовления. Они позволяют создавать объект, который управляет CDI. – mamboking

Смежные вопросы