强制 Spring Boot 不使用 EmbeddedWebApplicationContext?

Posted

技术标签:

【中文标题】强制 Spring Boot 不使用 EmbeddedWebApplicationContext?【英文标题】:Forcing Spring Boot to NOT use EmbeddedWebApplicationContext? 【发布时间】:2014-10-04 21:47:42 【问题描述】:

我有一个 Spock 测试用例,我想在其中加载 Spring 应用程序。我有一个非常基本的 Groovy 类,它是我的配置对象:

@Configuration
@EnableAutoConfiguration
class TestConfig 
  @Bean
  Map createSillyMsgMap() 
    ["sillyMsg" : "This is a silly message"]
  
  public static void main(String[] args) 
    println "TestConfig.main($args)"
  

显然,这不是很有用,但它可以作为示例。为方便起见,我还在该类中添加了 main 方法。我的测试类只是尝试将其实例化为 Spring Boot 应用程序。像这样的:

class AppContextSpec extends Specification 
  def "testSpringApplication"() 
    given: "a Spring Configuration"
    SpringApplication app = new SpringApplication(TestConfig)
    app.headless = true 
    app.webEnvironment = false
    app.applicationContextClass = AnnotationConfigApplicationContext

    expect: "the Spring Application to be able to start"
    ConfigurableApplicationContext ctxt = app.run((String[]) ["blah"])
  

我试图通过将 webEnvironment 属性显式设置为 false 来强制 Spring Boot 不使用 EmbeddedWebApplicationContext。但无论我做什么,Spring Boot 都坚持要启动一个 Tomcat 服务器,而且它似乎确实会拉入源代码树中标有@Component 和/或@Configuration 的其他资源。类路径上还有其他几个应用程序上下文,当然还有暗示 Web 服务类型的 jar 文件,但我很惊讶类路径上的内容应该优先于通过 webEnvironment 属性进行的显式配置。我使用 Gradle 1.12 作为构建系统,Spring Boot 版本是 1.1.4,我使用的是 Groovy 2.3.6 和 Spock 0.7-groovy-2.0。对此的任何帮助表示赞赏。

我在这里做的事情完全不正常吗?谢谢。

【问题讨论】:

【参考方案1】:

您可能不应该像现在这样尝试自己引导 Spring Boot 应用程序上下文。

以下代码在不启动嵌入式 servlet 容器的情况下创建了一个集成测试环境(尽管如果您想启动嵌入式 servlet 容器,只需添加几个注释就很容易了):

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = TestConfig.class)
class ExampleSpec extends Specification 

    // ...


您还必须在测试类路径中包含 'org.spockframework:spock-spring:0.7-groovy-2.0' 依赖项

查看this Spring Boot 官方文档的一部分和this SO question

【讨论】:

谢谢!那行得通。我在测试中使用了@Autowired ApplicationContext appContext,这似乎有效。有没有更“诡异”或“Spring Bootable”的方式来获取应用程序上下文?加载后可以通过规范本身的属性使用它似乎是合乎逻辑的。 很高兴它成功了!恐怕我不知道有一种更 Spock 惯用的接线方式。 我仍然很好奇为什么我的原始测试不起作用。 Spring Boot 文档中记录了加载这样的 SpringApplication 。只是想知道它是否与 Spock 不兼容。 我没有像你尝试过的那样引导应用程序上下文,所以我没有任何指示【参考方案2】:

如果你没有编写测试,因此你不能使用@ContextConfiguration

而不是简单的SpringApplication.run(MyDomainSpringConfig.class, args);

像这样构造并运行你的 SpringApplication...

SpringApplication application = new SpringApplication(MyDomainSpringConfig.class);
application.setApplicationContextClass(AnnotationConfigApplicationContext.class);
application.run(args);

在 Spring Boot 1.2.1 中验证

【讨论】:

Anthavio,这正是我在原始问题中显示的测试中所做的,尽管测试是用 Groovy 编写的,而不是 Java :-)

以上是关于强制 Spring Boot 不使用 EmbeddedWebApplicationContext?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot gradle 插件强制 Mockito 版本

spring boot 之依赖

如何强制 Spring Boot JVM 进入 UTC 时区?

Spring Boot 未使用 Jackson Kotlin 插件

Spring Boot的特性: 自定义日志配置

Spring Boot:为执行器端点禁用 https