9

在我目前正在进行的一个项目中,我们需要多个配置文件,即“默认”和“测试”。为了解决这个问题,我们实现了一个主上下文类 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)中,并引用了测试环境中的文件。如果有更好的方法来定义这些配置文件,而不会将这种依赖性从生产代码引入测试代码,那当然会更好。

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

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

3 回答 3

16

如果所有 bean 在您的配置文件之间都是通用的(即两者都DefaultContext包含TestContext相同的 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;

}
于 2013-04-25T09:40:54.663 回答
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 依赖项是必要的。

于 2013-05-02T07:40:22.017 回答
0

使用 Maven 的特性来分离主应用程序上下文和测试应用程序上下文。

例如,如果您的主要应用程序上下文位于

src/main/webapp/WEB-INF/myapp-config.xml

您可以将测试应用程序上下文放入

src/test/webapp/WEB-INF/myapp-config.xml

于 2013-04-09T13:46:08.037 回答