Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用java配置在Spring中处理多个概要文件的最佳实践是什么?_Java_Spring - Fatal编程技术网

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

使用java配置在Spring中处理多个概要文件的最佳实践是什么?,java,spring,Java,Spring,在我目前正在进行的一个项目中,我们需要多个配置文件,即“默认”和“测试”。为了解决这个问题,我们实现了一个主上下文类ApplicationContext.java,其中包含两个公共静态内部类:一个定义默认概要文件,另一个定义测试概要文件。我们的web.xml设置为目标ApplicationContext.java 代码如下: @Configuration //import common beans public class ApplicationContext { @Configurati

在我目前正在进行的一个项目中,我们需要多个配置文件,即“默认”和“测试”。为了解决这个问题,我们实现了一个主上下文类ApplicationContext.java,其中包含两个公共静态内部类:一个定义默认概要文件,另一个定义测试概要文件。我们的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");

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

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

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

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

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


如果配置文件之间的所有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;

}

我们最终得到的解决方案利用了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 { }
对于测试上下文也是如此。使用以下行从主方法运行Jetty将正确加载测试上下文并忽略“默认”bean:


该解决方案避免了从生产到测试代码的任何直接引用,尽管maven依赖关系是必要的

问题是,我们希望从java主方法启动Jetty,而不是从带有maven commandPlus的cmd启动Jetty,主要区别在于maven概要文件为每个概要文件生成不同的构建。因此,本地开发的构建不同于发布环境。在我看来,这是一种错误的方法,构建应该是相同的,以保证兼容性。考虑到我们应用程序的复杂性,这是不实际的。你提出的解决方案确实非常优雅。我们在这个解决方案中遇到的一个问题是,其中一个关键bean是在子模块中定义的,与主模块没有依赖关系(其中定义了ApplicationContext)。
System.setProperty("spring.active.profiles", "test");