18 KiB
Spring Boot - Core
This module provides the core features for the other modules in the project. It is relatively unopinionated and it has minimal required dependencies which makes it usable as a stand-alone library for anyone whose tastes diverge from ours.
SpringApplication
The SpringApplication
class provides a convenient way to bootstrap a Spring application
that will be started from a main()
method. In many situations you can just delegate
to the static SpringApplication.run
method:
public static void main(String[] args) {
SpringApplication.run(MySpringConfiguration.class, args);
}
When you application starts you should see something similar to the following:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: v0.0.0.BUILD.SNAPSHOT
2013-07-31 00:08:16.117 INFO 56603 --- [ main] o.s.b.s.app.SampleApplication : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
2013-07-31 00:08:16.166 INFO 56603 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
By default INFO
logging messages will shown, including some relevant startup details
such as the user that launched the application.
Customizing SpringApplication
If the SpringApplication defaults aren't to your taste you can instead create a local instance and customize it. For example, to turn off the banner you would write:
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setShowBanner(false);
app.run(args);
}
Note that the constructor arguments passed to SpringApplication
are configuration
sources for spring beans. In most cases these will be references to @Configuration
classes, but they could also be references to XML configuration or to packages that
should be scanned.
See the SpringApplication
Javadoc for a complete list of the configuration options
Accessing command line properties
By default SpringApplication
will convert any command line option arguments (starting
with '--', e.g. --server.port=9000
) to a PropertySource
and add it to the Spring
Environment
with highest priority (taking precedence and overriding values from other
sources). Properties in the Environment
(including System properties and OS environment
variables) can always be injected into Spring components using @Value
with
placeholders, e.g.
import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*
@Component
public class MyBean {
@Value("${name}")
private String name;
// Running 'java -jar myapp.jar --name=Spring' will set this to "Spring"
// ...
}
CommandLineRunner beans
If you want access to the raw command line argument, or you need to run some specific
code once the SpringApplication
has started you can implement the CommandLineRunner
interface. The run(String... args)
method will be called on all spring beans
implementing this interface.
import org.springframework.boot.*
import org.springframework.stereotype.*
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...
}
}
You can additionally implement the org.springframework.core.Ordered
interface or use
the org.springframework.core.annotation.Order
annotation if several CommandLineRunner
beans are defined that must be called in a specific order.
Application Exit
Each SpringApplication
will register a shutdown hook with the JVM to ensure that the
ApplicationContext
is closed gracefully on exit. All the standard Spring lifecycle
callbacks (such as the DisposableBean
interface, or the @PreDestroy
annotation)
can be used.
In addition, beans may implement the org.springframework.boot.ExitCodeGenerator
interface if they wish to return a specific exit code when the application ends.
Externalized Configuration
A SpringApplication
will load properties from application.properties
in the root of
your classpath and add them to the Spring Environment
. The actual search path for the
files is:
- classpath root
- current directory
- classpath
/config
package /config
subdir of the current directory.
The list is ordered by decreasing precedence (so properties can be overridden by others
with the same name defined in later locations). In addition, profile specific properties
can also be defined using the naming convention application-{profile}.properties
(properties from these files override the default ones).
The values in application.properties
are filtered through the existing Environment
when they are used so you can refer back to previously defined values (e.g. from System
properties).
app.name: MyApp
app.description: ${app.name} is a Spring Boot application
If you don't like application.properties
as the configuration file name you can
switch to another by specifying spring.config.name
environment property. You can also
refer to an explicit location using the spring.config.location
environment property.
$ java -jar myproject.jar --spring.config.name=myproject
Note: You can also use '.yaml' files as an alternative to '.properties' (see below)_
Setting the Default Spring Profile
Spring Profiles are a way to segregate parts of the application configuration and make it
only available in certain environments. Any @Component
that is marked with @Profile
will only be loaded in the profile specified by the latter annotation.
A SpringApplication
takes this a stage further, in that you can use a
spring.profiles.active
Environment
property to specify which profiles are active.
You can specify the property in any of the usual ways, for example you could include
it in your application.properties
:
spring.profiles.active=dev,hsqldb
or specify on the command line using the switch --spring.profiles.active=dev,hsqldb
.
Application Context Initializers
Spring provides a convenient ApplicationContextInitializer
interface that can be used
to customize an ApplicationContext
before it is used. If you need to use an initializer
with your SpringApplication
you can use the addInitializers
method.
You can also specify initializers by setting comma-delimited list of class names to the
Environment
property context.initializer.classes
or by using Spring's
SpringFactoriesLoader
mechanism.
Embedded Servlet Container Support
Spring Boot introduces a new type of Spring ApplicationContext
that can be used to
start an embedded servlet container. The EmbeddedWebApplicationContext
is a special
type of WebApplicationContext
that starts the container by searching for a single
EmbeddedServletContainerFactory
bean contained within itself. We provide
TomcatEmbeddedServletContainerFactory
and JettyEmbeddedServletContainerFactory
implementations for running embedded Tomcat or Jetty.
One advantage of using a Spring bean to define the embedded container is that you can use
all the standard Spring concepts. For example, it becomes trivial to define a Tomcat
server that sets its port from an injected @Value
.
@Configuration
public class MyConfiguration {
@Value("${tomcatport:8080}")
private int port;
@Bean
public EmbeddedServletContainerFactory servletContainer() {
return new TomcatEmbeddedServletContainerFactory(this.port);
}
}
Customizing Servlet Containers
Both the Tomcat and Jetty factories extend from the base
AbstractEmbeddedServletContainerFactory
class. This provides a uniform way
to configure both containers.
Settings that you would traditionally configure in a web.xml
or via an implementation
specific configuration file can now be performed programmatically.
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setPort(9000);
factory.setSessionTimeout(10, TimeUnit.MINUTES);
factory.addErrorPages(new ErrorPage(HttpStatus.404, "/notfound.html");
return factory;
}
In addition, you can also add ServletContextInitializer
implementations which allow
you to customize the javax.servlet.ServletContext
in the same way as any Servlet 3.0
environment.
Servlets and Filters
Servlets and Filters can be defined directly as beans with the
EmbeddedWebApplicationContext
. By default, if the context contains only a single
Servlet it will be mapped to '/'. In the case of multiple Servlets beans the bean name
will be used as a path prefix. Filters will map to '/*'.
If convention based mapping is not flexible enough you can use the
ServletRegistrationBean
and FilterRegistrationBean
classes for complete control. You
can also register items directly if your bean implements the ServletContextInitializer
interface.
Using YAML instead of Properties
YAML is a superset of JSON, and as such is a very convenient format
for specifying hierarchical configuration data. The SpringApplication
class will
automatically support YAML as an alternative to properties whenever you have the
SnakeYAML library on your classpath.
Loading YAML
Spring Boot provides two convenient classes that can be used to load YAML documents. The
YamlPropertiesFactoryBean
will load YAML as Properties
and the YamlMapFactoryBean
will load YAML as a Map
.
For example, the following YAML document:
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App
Would be transformed into these properties:
environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
YAML lists are represented as comma-separated values (useful for simple String values)
and also as property keys with [index]
dereferencers, for example this YAML:
servers:
- dev.bar.com
- foo.bar.com
Would be transformed into these properties:
servers=dev.bar.com,foo.bar.com
servers[0]=dev.bar.com
servers[1]=foo.bar.com
Exposing YAML as properties in the Spring Environment.
The YamlPropertySourceLoader
class can be used to expose YAML as a PropertySource
in the Spring Environment
. This allows you to the familiar @Value
with placeholders
syntax to access YAML properties.
You can also specify multiple profile-specific YAML document in a single file by
by using a spring.profiles
key to indicate when the document applies. For example:
server:
address: 192.168.1.100
---
spring:
profiles: production
server:
address: 192.168.1.120
Typesafe Configuration Properties
Use the @Value("${property}")
annotation to inject configuration properties can
sometimes be cumbersome, especially if you are working with multiple properties or
your data is hierarchical in nature. Spring Boot provides an alternative method
of working with properties that allows strongly typed beans to govern and validate
the configuration of your application. For example:
@Component
@ConfigurationProperties(name="connection")
public class ConnectionSettings {
private String username;
private InetAddress remoteAddress;
// ... getters and setters
}
When the @EnableConfigurationProperties
annotation is applied to your @Configuration
,
any beans annotated with @ConfigurationProperties
will automatically be configured
from the Environment
properties. This style of configuration works particularly well
with the SpringApplication
external YAML configuration:
# application.yml
connection:
username: admin
remoteAddress: 192.168.1.1
# additional configuration as required
To work with @ConfigurationProperties
beans you can just inject them in the same way
as any other bean.
@Service
public class MyService {
@Autowired
private ConnectionSettings connection;
//...
@PostConstruct
public void openConnection() {
Server server = new Server();
this.connection.configure(server);
}
}
It is also possible to shortcut the registration of @ConfigurationProperties
bean
definitions by simply listing the properties classes directly in the
@EnableConfigurationProperties
annotation:
@Configuration
@EnableConfigurationProperties(ConnectionSettings.class)
public class MyConfiguration {
}
Relaxed binding
Spring Boot uses some relaxed rules for binding Environment
properties to
@ConfigurationProperties
beans, so there doesn't need to be an exact match between
the Environment
property name and the bean property name. Common examples where this
is useful include underscore separated (e.g. context_path
binds to contextPath
), and
capitalized (e.g. PORT
binds to port
) environment properties.
Spring will attempt to coerce the external application properties to the right type when
it binds to the @ConfigurationProperties
beans. If you need custom type conversion you
can provide a ConversionService
bean (with bean id conversionService
) or custom
property editors (via a CustomEditorConfigurer
bean).
@ConfigurationProperties Validation
Spring Boot will attempt to validate external configuration, by default using JSR-303
(if it is on the classpath). You can simply add JSR-303 javax.valididation
constraint
annotations to your @ConfigurationProperties
class:
@Component
@ConfigurationProperties(name="connection")
public class ConnectionSettings {
@NotNull
private InetAddress remoteAddress;
// ... getters and setters
}
You can also add a custom Spring Validator
by creating a bean definition called
configurationPropertiesValidator
.
Using Project Lombok
You can safely use Project Lombok to generate getters and
setters for your @ConfigurationProperties
. Refer to the documentation on the Lombok
for how to enable it in your compiler or IDE.
External EmbeddedServletContainerFactory configuration
Spring Boot includes a @ConfigurationProperties
annotated class called
ServerProperties
that can be used to configure the EmbeddedServletContainerFactory
.
When registered as a bean, the ServerProperties
can be used to specify:
- The port that the application listens on for its endpoints
(
server.port
defaults to8080
) - The address that the application endpoints are available on
(
server.address
defaults to all local addresses, making it available to connections from all clients). - The context root of the application endpoints (
server.context_path
defaults to '/')
If you are using Tomcat as you embedded container then, in addition to the
generic ServerProperties
, you can also bind server.tomcat.*
properties
to specify:
- The Tomcat access log pattern (
server.tomcat.accessLogPattern
) - The remote IP and protocol headers (
server.tomcat.protocolHeader
,server.tomcat.remoteIpHeader
) - The Tomcat
base directory
(server.tomcat.basedir
)
Customizing Logging
Spring Boot uses Commons Logging for all internal logging, but leaves the underlying log implementation open. Default configurations are provided for Java Util Logging, Log4J and Logback. In each case there is console output and file output (rotating, 10MB file size).
The various logging systems can be activated by including the appropriate libraries on
the classpath, and further customized by supported by providing a suitable configuration
file in the root of the classpath, or in a location specified by the Spring Environment
property logging.config
.
Depending on your logging system, the following files will be loaded:
Logging System | Customization |
---|---|
Logback | logback.xml |
Log4j | log4j.properties or log4j.xml |
JDK | logging.properties |
To help with the customization some other properties are transferred from the Spring
Environment
to System properties:
Environment | System Property | Comments |
---|---|---|
logging.file | LOG_FILE | Used in default log configuration if defined |
logging.path | LOG_PATH | Used in default log configuration if defined |
PID | PID | The current process ID is discovered if possible and not already provided |
All the logging systems supported can consult System properties when parsing their
configuration files. See the default configurations in spring-boot.jar
for examples.
Cloud Foundry Support
When a SpringApplication
is deployed to Cloud Foundry
appropriate meta-data will be exposed as Environemnt
properties. All Cloud Foundry
properties are prefixed vcap.
You can use vcap properties to access application
information (such as the public URL of the application) and service information (such
as database credentials). See ApplicationContextInitializer
Javdoc for complete details.
Further Reading
For more information about any of the classes or interfaces discussed in the document please refer to the extensive project Javadoc. If looking to reduce the amount of configuration required for your application you should consider spring-boot-autoconfigure. For operational concerns see spring-boot-actuator. For details on how to package your application into a single executable JAR file take a look at spring-boot-loader.