Over the past decade, Spring has become de facto standard in large enterprises for creating all kinds of applications. Unsurprisingly, my previous post on Spring Boot is the most popular article on this blog. In this post I’ve attempted to detail some additional aspects of Spring from perspective of creating Cloud Native applications.
Table of contents
- Spring Starter
- Properties
- Configuration Properties
- Profiles
- Spring Cloud Config
- Session Replication
- Async Controller
- Async Service
- Service Discovery
- Resources
- Conclusion
Spring Starter
- Takes care of potentially conflicting libraries that each dependency (eg: JPA, REST, Security etc.) might have.
- Provides Maven/Gradle wrappers such that builds can be reproduce without fear of incompatible versions.
- To build:
./mvnw clean install
- To run:
./mvnw spring-boot:run
- Spring Boot configures h2 (if present in classpath) and project doesn’t contain SQL datasource properties.
- IoC (Inversion of Control) helps with testing (mock injection) and centralizing resource creation & initialization, instead of doing it at call-site (eg: DataSource).
Properties
- Accessible by Website, IDE or Command Line
- Externalize properties. Inject in code using
@Value = "${property.key:defaultValueIfNotFound}"
- Spring Boot looks for
application.properties
- Choose different name using
--spring.config.name
- Default config locations
classpath:/,classpath:/config/,file:./,file:./config/
(searched in reverse order) - Choose different config locations using
--spring.config.location
- Program arguments with prefix
--
(eg:--server.port=9090
) are converted to property and added toEnvironment
- Excellent Spring Documentation
Configuration Properties
- String based properties of POJO can be auto-populated with ConfigurationProperties
Profiles
- Load environment specific properties using
application-{profile}.properties
(eg:application-uat.properties
). - This environment specific property file is loaded on top of
application.properties
(properties with same name are overridden). - Beans can also have profiles (0, 1 or more).
- Beans with no profile are always activated.
- If no profiles are active,
default
profile is activated. - In this case, beans with explicit
default
profile value are activated (if any) andapplication-default.properties
file is loaded (if present). @Configuration
classes can also have profiles.- Activate profile using JVM argument
-Dspring.profiles.active=dev,hsqldb
or any of other variants - Environment variables are normalized, and made available as properties (eg: SPRING_PROFILES_ACTIVE is converted to spring.profiles.active).
Spring Cloud Config
Server
- Externalize configuration on a separate stand-alone repository instead of keeping alongside the code.
- Cloud Foundry provides ConfigServer service to avoid having to manual create/deploy this service.
Client
- Client application can now get it’s config from the server.
- The location of server has to be defined in
bootstrap.properties
(orbootstrap.yml
). - This file is loaded before application.properties and tells client where to get the rest of config from.
- Spring Cloud server might have config properties for many applications. Thus each client typically sets a property
spring.application.name
in its bootstrap.properties. - Client also has to set the URI where config server is running, in bootstrap file. Then, on client application start, applications properties are loaded from server (including for active profile).
Security
Config application can be secured on both server and client using spring security. In this case, on client, the URL is auto-encoded to https://user:pswd@url
Refresh Scope
Refresh scope is a feature to update Spring configuration when there is a property update on config server.
Any component with annotation @RefreshScope
gets its properties refreshed.
There is also a corresponding Spring event RefreshScopeRefreshEvent
Session Replication
Spring Session helps with session replication by replacing Servlet HTTP Session API and storing the session information in Redis/Hazelcast etc. Spring Boot makes this configuration dead simple. Read more about it here
Async Controller
Spring MVC (or any servlet container) creates a thread-pool to handle servlet requests.
There is still a possibility of thread being occupied for too long by some expensive operation.
Simply wrapping the response in a Callable
makes the code run in a separate thread-pool (can be overridden by creating a TaskExecutor bean) there by
freeing the servlet thread-pool to accept more requests.
Async Service
Same concept can be extended to service calls by using @Async
and Java’s CompletableFuture
.
Service Discovery
- Service discovery is the life line of a microservices based application.
- It typically contains a well-known registry service. Components use this service to register themselves and discover other components.
- Recommended to use
spring.application.name
for all client components to allow registry/discovery using logical names. - Spring article
Resources
I used the following resources to write this article.
Conclusion
This post covers only a part of what Spring Cloud has to offer. It offers Circuit Breakers, Load Balancers, Spring Cloud Security, Event Messaging and so much more. I intend to write more on rest of the topics as soon as I have some hands-on experience.
Hit me up in the comments if I missed anything or if you have any queries.