简体   繁体   中英

Forcing Spring Boot to NOT use EmbeddedWebApplicationContext?

I have a Spock test case where I want to load a Spring application. I have a very rudimentary Groovy class that is my config object:

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

Obviously, this is isn't very useful, but it serves as an example. For convenience, I've also added the main method in that class. My test class just tries to instantiate this as a Spring Boot Application. Something like this:

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"])
  }
}

I'm trying to force Spring Boot to NOT use the EmbeddedWebApplicationContext by explicitly setting the webEnvironment property to false. But no matter what I do, Spring Boot insists on starting a Tomcat server, and it does seem to pull in other resources in the source tree that are marked with @Component and/or @Configuration. There are several other application contexts on the classpath, and certainly jar files that imply web service kind of stuff, but I'm very surprised that what's on the classpath should take precedence over explicit configuration through the webEnvironment property. I'm using Gradle 1.12 as the build system, and the Spring Boot version is 1.1.4, and I'm using Groovy 2.3.6 with Spock 0.7-groovy-2.0. Any help with this is appreciated.

Am I doing something completely out of the norm here? Thanks.

In case where you are not writing test and therefore you can't use @ContextConfiguration

Instead of simple SpringApplication.run(MyDomainSpringConfig.class, args);

Construct and run your SpringApplication like this...

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

Verified in Spring Boot 1.2.1

You probably shouldn't be trying to bootstrap the Spring Boot application context on your own like you are doing.

The following code creates an integration testing environment without starting the embedded servlet container (although if you want to start the embedded servlet container it would be very easy to do with a couple more annotations):

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

    // ...

}

You'll also have to have the 'org.spockframework:spock-spring:0.7-groovy-2.0' dependency present on your test classpath

Check out this part of the Spring Boot official documentation and this SO question

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM