简体   繁体   English

在一场战争中有多个CDI配置文件(开发,测试版,qa,生产)?

[英]Multiple CDI configuration profiles (devel, beta, qa, production) in one war?

Having experience with the Spring DI applicationContext.xml way of declaring Dependency Injection I now try to figure out how to do the same with Java EE6 CDI. 有了使用Spring DI applicationContext.xml声明依赖注入的方法的经验,我现在试着弄清楚如何用Java EE6 CDI做同样的事情。

With Spring, I could ship my .jar with several configuration profiles like unittest.xml, devel.xml, qa.xml, production.xml and activate them using command line parameters or environment variables. 使用Spring,我可以将我的.jar与几个配置文件一起发送,例如unittest.xml,devel.xml,qa.xml,production.xml ,并使用命令行参数或环境变量激活它们。

With CDI, I could use @Alternative in beans.xml and properties in of web.xml but there seems no way of shipping multiple beans.xml for different environments. 使用CDI,我可以在beans.xml中使用@Alternative和web.xml中的属性,但似乎无法为不同的环境发送多个beans.xml。

I don't want to use Maven profiles/filters to produce 4-6 versions of my app although I understand that for some scenarios that would be the better solution (ie shipping ready build wars to customers - but I only use my wars internally so let's save compile time!) 我不想使用Maven配置文件/过滤器来生成我的应用程序的4-6版本,虽然我知道在某些情况下这将是更好的解决方案(即向客户发送准备好的构建战争 - 但我只在内部使用我的战争所以让我们节省编译时间!)

Preferably, I would also be able to load those configuration files from the file system so that they could be edited by the sysadmins without having to re-build the app. 最好,我还可以从文件系统加载这些配置文件,以便系统管理员可以编辑它们,而无需重新构建应用程序。

What is the Java EE6 way of having multiple configuration sets of dependencies and properties? 具有多个依赖关系和属性配置集的Java EE6方法是什么?

If there is none, what are the recommended alternatives as of 2013? 如果没有,那么2013年的推荐替代品是什么? Using Spring? 使用Spring? Seam? 接缝? Guice? 吉斯? I saw mentionings of Apache DeltaSpike but they still seem alpha juding from the web page. 我看到了Apache DeltaSpike的提及,但它们仍然看起来像网页上的alpha。

I'd use a dynamic producer, using a Qualifier to identify the desired environment 我使用动态生产者,使用Qualifier来识别所需的环境

// The qualifier for the production/qa/unit test 
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD,
 ElementType.FIELD, ElementType.PARAMETER})
public @interface Stage {
   String value() default "production";
}

// The interface for the stage-dependant service
public interface Greeting{
    public String sayHello();
}

// The production service
@Stage("production")
public class ProductionGreeting implements Greeting{
    public String sayHello(){return "Hello customer"; }
}

// The QA service
@Stage("qa")
public class QAGreeting implements Greeting{
    public String sayHello(){return "Hello tester"; }
}

// The common code wich uses the service
@Stateless
public class Salutation{
   @Inject Greeting greeting; 
   public String sayHello(){ return greeting.sayHello(); };
}

// The dynamic producer
public class GreetingFactory{
    @Inject
    @Any
    Instance<Greeting> greetings;        

    public String getEnvironment(){
         return System.getProperty("deployenv");
    }

    @Produces
    public Greeting getGreeting(){
        Instance<Greeting> found=greetings.select(
           new StageQualifier(getEnvironment()));
        if (!found.isUnsatisfied() && !found.isAmbiguous()){
           return found.get();
        }
        throw new RuntimeException("Error ...");
    }

    public static class StageQualifier 
      extends AnnotationLiteral<Stage> 
      implements Stage {
       private String value;

       public StageQualifier(String value){
           this.value=value;
       }
       public String value() { return value; }
     }

}

So here the container injects all available Greeting implementations into GreetingFactory , which in turn serves as @Producer for the intended one, basing the decision on the system property 'deployenv'. 所以这里容器将所有可用的Greeting实现注入GreetingFactory ,而GreetingFactory又作为预期的一个用于@Producer ,基于系统属性'deployenv'的决定。

The above answer by Carlo is good, we have all of this in DeltaSpike with the ProjectStage . Carlo的上述答案很好,我们在DeltaSpike中使用ProjectStage完成所有这些操作。 Worth taking a look at so you don't have to write it all yourself. 值得一看,所以你不必自己写。

An alternative solution is suggested by M.-Leander Reimer in his presentation Migrating a JSF-Based Web Application from Spring 3 to Java EE 7 and CDI (Slide 32), using a CDI extension: M.-Leander Reimer在他的演示文稿中使用CDI扩展建议将一个基于JSF的Web应用程序从Spring 3迁移到Java EE 7和CDI (幻灯片32),提出了另一种解决方案:

@Alternative
@Stereotype
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ProfileAlternative {
    Profile[] value();
}

public void processAnnotated(@Observes ProcessAnnotatedType<?> event) {
    ProfileAlternative pa = getProfileAlternative(event);
    if (profileAlternativeIsNotActive(pa)) {
        event.veto();
    }
 }

He uses a custom annotation @ProfileAlternative mimicking Spring's @Profile and a CDI extension observing the ProcessAnnotatedType event to veto() the type if it is annotated with a profile and the profile is not active. 他使用了自定义注释@ProfileAlternative模仿Spring的@Profile和CDI扩展观察ProcessAnnotatedType事件veto()如果它被注释与配置文件和配置文件是不活跃的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM