Расширение CDI для стереотипов и прокси-интерфейсов

#java #cdi #weld

#java #cdi #сварка

Вопрос:

Я определяю веб-модуль общей конфигурации для приложений.

Это сценарий использования:

У вас есть свое приложение, которое легко настраивается, поэтому вы определяете интерфейс, чтобы определить конфигурации для вашего приложения, и поэтому вы комментируете интерфейс с помощью @Config аннотации.

 @Config
public interface AppConfig{
  boolean isPropertySet();
  String getHeaderTitleLabel();
}
  

Аннотация @Config является одновременно маркером поставщика конфигурации и стереотипом CDI:

 @Documented
@Inherited
@Retention(RUNTIME)
@Target({FIELD, PARAMETER, TYPE, METHOD})
@Qualifier
@Named
@SessionScoped
public @interface Config{
}
  

На уровне приложения (допустим, приложение jsf с поддержкой CDI)

 @Named
@SessionScoped
public class MyController implements Serializable{
  @Inject
  @Config
  private AppConfig appConfig; 
}
  

В библиотеке конфигурации пользователь может получить экземпляр AppConfig, например:

 AppConfig appConfig = ConfigManager.getInstance(AppConfig.class);
  

который разрешает все требования из аннотации @Config, переменной среды и файла свойств, создайте прокси и подключитесь к веб-службе, которая предоставит необходимые данные конфигурации.

В настоящее время рабочая реализация заключается в том, чтобы разработчик определил поле / метод производителя.

 @Stateless
public class ConfigProducer{

 @Produces
 @Config
 public AppConfig getInstance(){
   return ConfigManager.getInstance(AppConfig.class);
 }
}
  

Если бы вы определили несколько appconfigs на основе разных модулей проекта, это не было бы громоздким, но могло бы вызвать небольшие неудобства. Я просто хочу, чтобы мои пользователи выполняли инъекцию так, как они это делали бы: @Inject EntityManager em; не прибегая к тому, как она создается.

Я определил расширение CDI для регистрации реализации AppConfig и включения его для внедрения.

 public class ConfigExtension implements Extension{

 public void observeProcessAnnotatedType(@Observes ProcessAnnotatedType patEvent){}
 public void observerBeforeBeanDiscovery(@Observes BeforeBeanDiscovery bbdEvent){}
 public void observeAfterBeanDiscovery(Observes AfterBeanDiscovery abd){}
 public<T,X> void observeProcessInjectionPoint(@Observes ProcessInjectionPoint<T,X> pipEvent, BeanManager bm){}
 public<T,X> void observeProcessInjectionTarget(@Observes ProcessInjectionTarget<T,X> pipEvent, BeanManager bm){}

}
  

Моя текущая проблема заключается в том, какое событие правильного наблюдателя регистрирует реализацию AppConfig?
Я посмотрел на Bean, и некоторые из наиболее запутанных частей — это

 Bean.getBeanClass(); //should i return Proxy.getProxyClass() here?
Bean.getTypes(); //and here?
Bean.create(CreationalContext<T> cc); //at this point i need to return the proxy for AppConfig.class
  

Когда я делаю это в настоящее время, реализация weld по-прежнему жалуется на неудовлетворенную зависимость.

Я был бы признателен за помощь в том, как это сделать.

Ответ №1:

После прочтения спецификации CDI я пришел к выводу, что у меня нет контроля над созданием экземпляра контекстной ссылки.

Об этом упоминалось в разделе

7.1. Ограничение при создании экземпляра компонента

Если приложению требуется больше контроля над созданием экземпляра контекстного экземпляра, может использоваться метод или поле производителя.

Так что, по сути, мне нужно проверить другие фреймворки на предмет того, что я хочу сделать, или мои пользователи просто должны определить своих собственных производителей для каждого интерфейса AppConfig, который они объявляют.

http://docs.jboss.org/cdi/spec/1.0/pdf/JSR-299-FD.pdf

Комментарии:

1. Вы могли бы проверить, подходят ли вам дополнения конфигурации, предоставляемые deltaspike: deltaspike.apache.org/configuration.html