Spring Boot 2.x
the small things
Highlights of the new release
- A Java 8 baseline, and Java 9 support.
- Reactive web programming support with Spring WebFlux/WebFlux.fn.
- Auto-configuration and starter POMs for reactive Spring Data Cassandra, MongoDB, Couchbase and Redis.
- Support for embedded Netty.
- HTTP/2 for Tomcat, Undertow and Jetty.
- Kotlin support.
- A brand new actuator architecture, with support for Spring MVC, WebFlux and Jersey.
- Micrometer based metrics with exporters for Atlas, Datadog, Ganglia, Graphite, Influx, JMX, New Relic, Prometheus, SignalFx, StatsD and Wavefront.
- Quartz scheduler support.
- Greatly simplified security auto-configuration.
Spring Boot 2.0
#springboot2.0
Converters for Duration type
app.timeout=180s@ConfigurationProperties("app")
class AppProperties {
private Duration timeout;
...
}@DurationUnit(ChronoUnit.SECONDS)app.timeout=P3Y6M4DT3H3M3S#springboot2.0
Updated Default 'create-drop' Handling
spring.jpa.hibernate.ddl-auto=create-dropEmbedded DB without schema manager
spring.jpa.hibernate.ddl-auto=noneotherwise
#springboot2.0
New namespaces
spring.jdbc.templatespring.jdbc.template.fetch-size=-1
spring.jdbc.template.max-rows=-1
spring.jdbc.template.query-timeout=1s#springboot2.0
New namespaces
spring.data.webspring.data.web.pageable.default-page-size=20
spring.data.web.pageable.max-page-size=2000
spring.data.web.pageable.one-indexed-parameters=false#springboot2.0
New starters
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>#springboot2.0
New starters
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
</dependency>#springboot2.0
class Person {
// mandatory fields
private final String name;
private final String surname;
// optional fields
private String nickname;
// no annotations are required if preconditions are met (details below)
public Person(String name, String surname) {
this.name = name;
this.surname = surname;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}#springboot2.0
Actuator endpoints
GET request to /actuator/scheduledtasks
{
"cron" : [ {
"runnable" : {
"target" : "com.example.Processor.processOrders"
},
"expression" : "0 0 0/3 1/1 * ?"
} ],
"fixedDelay" : [ {
"runnable" : {
"target" : "com.example.Processor.purge"
},
"initialDelay" : 5000,
"interval" : 5000
} ]
}#springboot2.0
Actuator endpoints
POST request to /actuator/loggers/{logger.name}
$ curl 'http://localhost:8080/actuator/loggers/com.example' -i -X POST \
-H 'Content-Type: application/json' \
-d '{"configuredLevel":"debug"}'$ curl 'http://localhost:8080/actuator/loggers/com.example' -i -X POST \
-H 'Content-Type: application/json' \
-d '{}'#springboot2.0
the largest of the smallest
#springboot2.0

Spring Boot 2.1
#springboot2.1
Bean overriding
@Component
class ComponentOne {
@Bean
public BeanService beanService() { ... }
}
@Component
class ComponentTwo {
@Bean
public BeanService beanService() { ... }
}#springboot2.1
Bean overriding
INFO 33228 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'beanService' with a different definition: replacing [... defined in class path resource [com/example/demo/ComponentOne.class]] with [... defined in class path resource [com/example/demo/ComponentTwo.class]]#springboot2.1
Bean overriding
WARN 36724 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideExceptionspring.main.allow-bean-definition-overriding=trueConverters for DataSize type
app.attachement-size=10MB@ConfigurationProperties("app")
class AppProperties {
private DataSize attachementSize;
...
}#springboot2.1
Converters for Duration type
#springboot2.1
@Value("${app.timeout:10s}")
private Duration timeout;Profile Expression
#springboot2.1
production & (us-east | eu-central)Works only for:
- @Profile annotation
- Multi-profile YAML Documents
- Logback configuration using <springProfile>
server:
address: 127.0.0.1
---
spring:
profiles: production & eu-central
server:
address: 192.168.1.120Task scheduling
#springboot2.1
@Configuration
@EnableScheduling
public class AppSchedulingConfiguration implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
ThreadPoolTaskScheduler threadPoolTaskScheduler =
new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(1);
threadPoolTaskScheduler.setThreadNamePrefix("app-scheduler-");
threadPoolTaskScheduler.initialize();
taskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
}
}Task scheduling
#springboot2.1
spring.task.scheduling.pool.size=1
spring.task.scheduling.thread-name-prefix=app-scheduler-Task execution
#springboot2.1
@Configuration
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(1);
executor.setMaxPoolSize(1);
executor.setQueueCapacity(1);
executor.setThreadNamePrefix("app-task-");
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
}Task execution
#springboot2.1
spring.task.execution.pool.allow-core-thread-timeout=true
spring.task.execution.pool.core-size=1
spring.task.execution.pool.keep-alive=60s
spring.task.execution.pool.max-size=1
spring.task.execution.pool.queue-capacity=1
spring.task.execution.thread-name-prefix=app-task- Logging Groups
#springboot2.1
logging.group.tomcat=org.apache.catalina,org.apache.coyote,org.apache.tomcatlogging.level.tomcat=TRACElogging.group.web=org.springframework.core.codec,org.springframework.http,\
org.springframework.web
logging.group.sql=org.springframework.jdbc.core,org.hibernate.SQLBootstrap mode for JPA setup
#springboot2.1
@EnableJpaRepositories(bootstrapMode = BootstrapMode.DEFERRED)
spring.data.jpa.repositories.bootstrap-mode=lazy#springboot2.1
New starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>#springboot2.1
Micrometer Tags
@Bean
public MeterRegistryCustomizer<MeterRegistry> configure(
@Value("${app.name}") String name) {
return new MeterRegistryCustomizer<MeterRegistry>()
{
@Override
public void customize(final MeterRegistry registry)
{
registry.config().commonTags("application", name);
}
};
}management.metrics.tags.application=app-nameSpring Boot 2.2*
Lazy initialization
#springboot2.2.0.M1
spring.main.lazy-initialization=true
Task execution and scheduling
#springboot2.2.0.M1
spring.task.execution.shutdown.await-termination=true
spring.task.execution.shutdown.await-termination-period=10sspring.task.scheduling.shutdown.await-termination=true
spring.task.scheduling.shutdown.await-termination-period=10sTest Application Arguments
#springboot2.2.0.M1
@RunWith(SpringRunner.class)
@SpringBootTest(args = "--app.test=one")
public class ApplicationArgumentsExampleTests {
@Autowired
private ApplicationArguments args;
}Spring Boot 2.x - The small things
By Arkadiusz Jurasz
Spring Boot 2.x - The small things
- 486