Spring Boot 2 – an overview: Spring Data and Spring Security 5

Spring Data and Spring Security are two important modules whose versions are managed by Spring Boot. Consequently, both modules are affected by the update to Spring Boot 2. New applications created directly with Spring Boot 2 usually benefit the most. Applications that are being updated must address these new aspects through active migration.
Michael Simons is a speaker at JAX 2018 and author of the book “Spring Boot – Moderne Softwareentwicklung im Spring Ökosystem“, published by dpunkt.verlag.
1 Spring Data Kay
Spring Data Kay was released in October 2017 and is now part of Spring Boot 2’s Dependency Management. Based on Spring 5, Java 8 and some new features within the Java EE-7 environment, it contains several larger and smaller subjects:
- A Redesigned Repository API
- Improved method names and signatures, Java-8
optional
- A new method of composing repositories
- Improved method names and signatures, Java-8
- Standalone Kotlin support for immutable data classes
- A way to declare the
nullability
constraints of an API - And, of course, reactive data access to stores that offer a non-blocking API (including Redis, MongoDB, Couchbase and Cassandra)
In the following I will introduce the new API and the reactive data access. The new API will, in some cases, lead to changes in the client code of existing projects. The reactive database’s access of supported stores is one of Spring Data Kays highlights.
1.1 New method names and signatures
Method names or signatures of Spring Data Kay repositories could sometimes lead to ambiguities. This was a driving factor for the interface redesign:
interface CrudRepository<T, ID> extends Repository<T, ID> { S save(S entity); Iterable<S> saveAll(Iterable<S> entities) Optional<T> findById(ID id); boolean existsById(ID id); Iterable<T> findAllById(Iterable<ID> ids); void deleteById(ID id); void delete(T entity); void deleteAll(Iterable<? extends T> entities); }
findOne
was replaced by findById
, save
and delete
using an iterable
as parameter was replaced by explicit ...all
-pendands, and a types id no longer has to be serializable.
The changes to methods and their signatures (optionally<T>
instead of a possible null value) are things that must be migrated proactively.
1.2 Composable Repositories
Spring Data repositories can now be formed from different fragments. The restriction to one basic implementation plus an additional one has been removed.
@Entity public class CustomerEntity extends Person { }
Regarding the CustomerEntity of Listing 2, a repository can now be compiled to provide CRUD operations as well as independent search and bulk operations. Listing 3 illustrates a declarative interface:
public interface CustomerRepository extends CrudRepository<CustomerEntity, Integer>, PersonFragment, CustomerBulkLoader{ }
These interfaces naturally include basic implementations. Names, for the most part, can be chosen freely, but the implementing class should end in Impl
. Listing 4 shows this quite explicitly:
public interface CustomerBulkLoader { void loadCustomers(String fileName); } public class CustomerBulkLoaderImpl implements CustomerBulkLoader { @Override public void loadCustomers(String fileName) { System.out.println("Loading customers from " + fileName); } }
Spring Data Kay no longer interferes with technically driven approaches to an application. The examples above are part of the Spring Boot books database examples.
1.3 Reactive Support
Spring Data Kay supports non-blocking, “reactive” access to a variety of different data stores. These include Redis, MongoDB, Couchbase and Cassandra, but not JPA. The JDBC API is inherently blocking, and work on reactive additions has only begun in recent months.
In order to use reactive data types, for example the implementation of Project Reactor, either a suitable driver must be included as a dependency or, as in Listing 5, a suitable spring boot starter:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId> </dependency>
The repositories can be declared as usual. Listing 6 shows a simple example and usage in a reactive REST controller:
public interface FilmRepository extends ReactiveMongoRepository<Film, String> { } @RestController public class FilmRestController { private final FilmRepository filmRepository; public FilmRestController(FilmRepository filmRepository) { this.filmRepository = filmRepository; } @GetMapping("/api/films") public Flux<Film> getAll() { return filmRepository .findAll(Sort.by("title").ascending()); } }
If MongoDB is used as a store, infinite streams are available. These are based on special collections in MongoDB that emit new objects as soon as they are added to the collection. The use of @Tailable
is shown in Listing 7:
public interface FilmWatchedEventRepository extends Repository<FilmWatchedEvent, String> { @Tailable Flux<FilmWatchedEvent> streamAllBy(); }
2 Conclusion
In all probability, Spring Data’s client code will need to be handled after a Spring Boot application upgrade, but the improved API and reactive support for many stores is worth the effort.
3 Spring Security 5
Spring Security and the automatic configuration of Spring Security by Spring Boot via corresponding starters have probably experienced the most profound changes.
3.1.1 Breaking Changes: Less Magic with Spring Boot
The automatic configuration of Spring Security via spring-boot-starter-security
has completely been reworked. While the starter in Spring Boot 1.5 made all kinds of assumptions regarding Spring Security’s default configuration, explicit configurations of the application and “built-in” defaults in Spring Boot, a new credo now applies: Spring Boot has no opinion regarding Spring Security; the defaults of Spring Security do apply. This means, for example, that content negotiation influences whether a request is offered basic or form authentication. This change of faith is accompanied by the renunciation of configuration properties regarding the security
prefix: Almost all of them have been removed. What remains – under the new spring.security prefix
– are properties for configuring an individual user, the order of the security filters and the new OAuth2 support.
By not having a preference, Spring Boot no longer has to attempt to adapt to possibly existing security configurations within the application. Once an application adjusts just one single aspect of the security filter chain, it is immediately responsible for configuring all aspects.
3.1.2 Breaking Changes: A new password storage mechanism
The question whether a password should be hashed or not is hopefully sufficiently answered. Whether a hash is safe or not, however, is a question of constant debate.
A library such as Spring Security can rarely allow deep changes; therefore, it sometimes cannot react quickly enough if, for example, a default hashing algorithm is to be changed. The Spring Security Team has decided on a thorough cleanup in version 5.
In Spring Security 4, a Noop-Password-Encoder was configured by default, now passwords are hashed with BCrypt. And yet, the default encoder is not a BCryptPasswordEncoder
, but a DelegatingPasswordEncoder
. Delegating password encoders are able to use different other password encoders, i.e. to delegate different formats. This mechanism is accompanied by a new format for storing passwords: {id}encodedPassword
. id
represents the abbreviation of a password encoder and encodedPassword
represents the hash itself. As a result, Spring Security 5 frees itself from the coupling to rigid password formats and is ready for future innovations.
The new password encoder reads and writes these formats and can be configured to handle stored passwords without identifiers using specific encoders.
In addition to these basic changes, old password encoders that were already deprecated in Spring Security 4 have been removed.
An active migration of a Spring Boot 1 application onto Spring Boot 2 and Spring Security 5 is therefore necessary in at least two cases: 1.) The application uses one of the old, now removed password encoders, or 2.) The application does not use an explicit password encoder.
In the first case, a message digest based encoder may help. In the second case, an active migration is strongly recommended, since the application used previously unhashed passwords.
The blogpost Spring Security 5: A new password storage format explains the advantages in detail and shows some possibilities for migration.
3.2 Integration with the reactive stack
One of Spring Securities key elements is the SecurityContextHolder
. This class provides central access to the principal authenticated against an application. In the synchronous web stack, where a task was answered by the same thread that accepted it, this could be implemented using a ThreadLocal
based solution. Project Reactor – also the technical basis for Reactive Security – offers via Reactor Context
an unchangeable memory area, which is bound to the processing chain of a flux
or mono
.
For an end developer, Reactive Security and Spring Security are nearly identical, both in terms of URL and method security. The Spring Boot Starter spring-boot-starter-security
provides all necessary dependencies and configures the reactive part of Spring Security by itself.
Of course, the source of the authenticatable users also had to become reactive. Alongside the well-known UserDetailsService
, the ReactiveUserDetailsService
was introduced. Listing 8 shows its use.
@Bean public ReactiveUserDetailsService userDetailsService() { return new MapReactiveUserDetailsService( User.withUsername("visitor") .password("{noop}visitor") .roles("USER") .build(), User.withUsername("film") .password("{noop}store") .roles("STORE") .build() ); }
Users with different roles (as defined in Listing 8) can then be applied to URLs, which are configured as in Listing 9:
@Bean SecurityWebFilterChain springSecurity( ServerHttpSecurity http ) { return http .authorizeExchange() .pathMatchers("/api/watchedRightNow") .authenticated() .pathMatchers("/api/filmWatched") .hasRole("STORE") .anyExchange().permitAll() .and() .build(); }
ServerHttpSecurity
is new to Spring Security 5 and, along with its old counterpart, HttpSecurity
, reflects the dualism of the old servlet specification-based structures and the new, reactive ones. Many of the known security features are already possible to configure for the reactive stack.
Just as normal method security (@PreAuthorize
and Co.) is still deliberately configured with @EnableGlobalMethodSecurity
in Spring Boot 2, so are reactive methods. @nableReactiveMethodSecurity
complements the kit.
4 Conclusion
Spring Security is one of the oldest projects in the Spring ecosystem. Created in 2003 as “Acegi Security”, it has a rich, long-standing history. I think it’s great that the team has the courage to take on such an enormous cleanup. If this library is deliberately updated, it is generally understood that such an update often requires further work. But if the update comes as part of a larger framework, it can be surprising. Nevertheless, in my opinion, the advantages outweigh the disadvantages. The lack of “magic” in the Spring environment may be irritating at first, but for me it shows that the Spring engineering team is well aware of the balance between too little and too much automatic configuration.
In the next part of this series on Spring Boot 2, I present the changes in one of Spring Boots own modules: the Spring Boot Actuator. There are also some surprises there.

The Spring Boot book will be published in late April 2018 and will cover all current topics related to Spring Boot 2. In addition to the reactive programming model with Spring 5, this includes the new actuator infrastructure, Micrometer.io support and much more. This book is intended to appeal to interested developers from the Java EE area as well as Spring developers and give them a “recipe” to handle recurring tasks from everyday business life elegantly and without distraction using Spring Boot.
Will the be an English language edition of the book or only German?
We’re not sure what the plans are but we’ll let you know if the English version is happening.
Where can i get the code?