使用java配置在Spring中处理多个配置文件的最佳实践是什么?

时间:2013-04-09 13:39:00

标签: java spring

在我正在进行的项目中,我们需要多个配置文件,即“默认”和“测试”。为了解决这个问题,我们实现了一个主上下文类ApplicationContext.java,它有2个公共静态内部类:其中一个定义了默认的配置文件,另一个定义了测试配置文件。我们的web.xml设置为目标ApplicationContext.java。

代码如下:

@Configuration
//import common beans
public class ApplicationContext {

  @Configuration  
  @Profile("default")
  public static class DefaultContext {
    //default beans
  }  

  @Configuration
  @Profile("test")
  public static class TestContext {
    //test beans
  }

}

我的问题是主要的上下文类ApplicationContext.java位于生产环境(即src / main / java)中,并引用了测试环境中的文件。如果有一种更好的方法来定义这些配置文件而不将此依赖关系从生产代码引入测试代码,那当然是更可取的。

我们在测试类中使用jetty实例测试了这些案例,从main方法开始。使用以下命令运行此实例:

System.setProperty("spring.profiles.active", "test");

3 个答案:

答案 0 :(得分:14)

如果所有bean在您的配置文件之间是通用的(即,DefaultContextTestContext包含相同的bean定义),请为依赖项定义接口,例如:

public interface SystemConfiguration {

    public DataSource getDataSource();
    public SomeService getService();

}

然后使用此界面实现每个配置文件:

@Profile("production")
@Configuration
public class ProductionConfiguration implements SystemConfiguration {
    public DataSource getDataSource() {
         // create and return production datasource
    }

    public SomeService getService() {
        // Create and return production service
    }
}

然后做同样的测试。

@Profile("test")
@Configuration
public class TestConfiguration implements SystemConfiguration {
    public DataSource getDataSource() {
         // create and return dummy datasource
    }

    public SomeService getService() {
        // Create and return dummy service
    }
}

然后您可以将其注入主配置:

@Configuration
public class ApplicationContext {
    @Autowired
    private SystemConfiguration systemConfiguration;

}

答案 1 :(得分:1)

我们最终使用的解决方案是使用Spring的@ComponentScan注释。各种应用程序上下文在多个maven模块中定义。但是,通过共享相同的包命名(即com.company.application.context),此注释会在测试和生产目录中查找上下文。

结果代码:

@ComponentScan("com.company.application.context")
@Configuration
public class ApplicationContext { }

假设maven依赖关系和包命名正确,则会自动找到所有生产上下文和测试上下文。生产环境如下所示:

@Configuration
@Profile("default")
//Import contexts from other modules
public class ProductionContext { }

同样适用于测试环境。使用以下行从main方法运行Jetty会正确加载测试上下文并忽略“默认”bean:

System.setProperty("spring.active.profiles", "test");

此解决方案避免了从生产到测试代码的任何直接引用,尽管maven依赖项是必需的。

答案 2 :(得分:0)

使用Maven的功能来分隔主要和测试应用程序上下文。

例如,如果您的主应用程序上下文存在于

  

的src /主/ web应用/ WEB-INF / MyApp的-config.xml中

您可以在

中放置测试应用程序上下文
  

的src /测试/ web应用/ WEB-INF / MyApp的-config.xml中