【发布时间】:2014-08-23 09:20:56
【问题描述】:
我正在为应用程序定义一个基于 Web 的通用配置模块。
这是场景用例:
你有你的应用程序,它是高度可配置的,所以你定义了一个接口来定义你的应用程序的配置,所以你用@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{
}
在应用程序级别(比如说启用 CDI 的 jsf 应用程序)
@Named
@SessionScoped
public class MyController implements Serializable{
@Inject
@Config
private AppConfig appConfig;
}
在配置库中,用户可以获取 AppConfig 的一个实例,例如:
AppConfig appConfig = ConfigManager.getInstance(AppConfig.class);
解决来自@Config 注释和环境变量和属性文件的所有要求,创建代理并连接到将提供必要配置数据的 Web 服务。
目前,开发人员可以定义生产者字段/方法。
@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
当我目前这样做时,焊接实现仍然抱怨不满意的依赖关系。
如果您能帮助我解决这个问题,我将不胜感激。
【问题讨论】: