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

Jar*_*rud 9 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
  }

}
Run Code Online (Sandbox Code Playgroud)

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

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

System.setProperty("spring.profiles.active", "test");
Run Code Online (Sandbox Code Playgroud)

Nil*_*lsH 15

如果所有的豆类都是您的配置文件(即,在两者之间共同的DefaultContextTestContext包含相同的bean定义),定义了依赖性,如接口:

public interface SystemConfiguration {

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

}
Run Code Online (Sandbox Code Playgroud)

然后使用此接口实现每个配置文件:

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

    public SomeService getService() {
        // Create and return production service
    }
}
Run Code Online (Sandbox Code Playgroud)

然后做同样的测试.

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

    public SomeService getService() {
        // Create and return dummy service
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以将它注入你的主配置:

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

}
Run Code Online (Sandbox Code Playgroud)


Jar*_*rud 1

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

结果代码:

@ComponentScan("com.company.application.context")
@Configuration
public class ApplicationContext { }
Run Code Online (Sandbox Code Playgroud)

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

@Configuration
@Profile("default")
//Import contexts from other modules
public class ProductionContext { }
Run Code Online (Sandbox Code Playgroud)

对于测试上下文也是如此。使用以下行从主方法运行 Jetty 可以正确加载测试上下文并忽略“默认”bean:

System.setProperty("spring.active.profiles", "test");
Run Code Online (Sandbox Code Playgroud)

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