Provide default for SpringApplication main class in servlet container

By default, SpringApplication attempts to deduce the application class
by looking for a main method in the stack. This does not work when
the application is launched by a servlet container via
SpringBootServletInitializer as there's either no main method in the
stack, or the main method is that of the servlet container, rather
than the application.

This commit updates SpringBootServletInitializer to configure the
main class of the SpringApplication that it creates to be the
application's SpringBootServletInitializer subclass. This is done
prior to calling configure, so the main class can still be specified
by the application if required.

Closes gh-3061
This commit is contained in:
Andy Wilkinson 2015-06-22 13:54:47 +01:00
parent 01ba0f7571
commit cd62596e82
2 changed files with 17 additions and 1 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -57,6 +57,7 @@ import org.springframework.web.context.WebApplicationContext;
*
* @author Dave Syer
* @author Phillip Webb
* @author Andy Wilkinson
* @see #configure(SpringApplicationBuilder)
*/
public abstract class SpringBootServletInitializer implements WebApplicationInitializer {
@ -84,6 +85,7 @@ public abstract class SpringBootServletInitializer implements WebApplicationInit
protected WebApplicationContext createRootApplicationContext(
ServletContext servletContext) {
SpringApplicationBuilder builder = new SpringApplicationBuilder();
builder.main(getClass());
ApplicationContext parent = getExistingRootWebApplicationContext(servletContext);
if (parent != null) {
this.logger.info("Root context already created (using as parent).");

View File

@ -26,6 +26,7 @@ import org.hamcrest.Matcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Configuration;
@ -33,12 +34,14 @@ import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.WebApplicationContext;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
/**
* Tests for {@link SpringBootServletInitializerTests}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
public class SpringBootServletInitializerTests {
@ -72,6 +75,17 @@ public class SpringBootServletInitializerTests {
equalToSet(Config.class, ErrorPageFilter.class));
}
@SuppressWarnings("rawtypes")
@Test
public void mainClassHasSensibleDefault() throws Exception {
new WithConfigurationAnnotation()
.createRootApplicationContext(this.servletContext);
Class mainApplicationClass = (Class<?>) new DirectFieldAccessor(this.application)
.getPropertyValue("mainApplicationClass");
assertThat(mainApplicationClass,
is(equalTo((Class) WithConfigurationAnnotation.class)));
}
private Matcher<? super Set<Object>> equalToSet(Object... items) {
Set<Object> set = new LinkedHashSet<Object>();
Collections.addAll(set, items);