Writing in the front

Spring Boot is the most popular Java framework for developing microservices. Spring Boot is the most popular Java framework for developing microservices. Spring Boot is the most popular Java framework for developing microservices. In this article, I’ll share with you the best practices I’ve adopted since 2016 for using Spring Boot in professional development. These are based on my personal experience and articles by some Spring Boot experts I know well.

In this article, I’ll focus on practices specific to Spring Boot (and, most of the time, Spring projects). The best practices are listed below, in no particular order.

Use custom BOms to maintain third-party dependencies

This practice is based on my experience in actual projects.

The Spring Boot project itself uses and integrates a number of open source projects, and it helps us maintain these third-party dependencies. However, there are also some parts that are not included in the actual project use, which requires us to maintain the version in the project. In a large project that includes many undeveloped modules, maintenance can be cumbersome.

What to do? In fact, the Spring IO Platform does just that, and is itself a subproject of Spring Boot, while maintaining other third-party open source libraries. We can learn from the Spring IO Platform to write our own base project platform-BOM. All business module projects should be introduced as BOM. When you upgrade a third-party dependency, you only need to upgrade the version of that dependency.

<dependencyManagement>
   <dependencies>
       <dependency>
           <groupId>io.spring.platform</groupId>
           <artifactId>platform-bom</artifactId>
           <version>Cairo-SR3</version>
           <type>pom</type>
           <scope>import</scope>
       </dependency>
   </dependencies>
</dependencyManagement>
Copy the code

Using Automatic Configuration

A major feature of Spring Boot is the use of automatic configuration. This is part of Spring Boot that simplifies your code and makes it work. Automatic configuration is activated when a specific JAR file is detected on the classpath.

The easiest way to use it is to rely on Spring Boot Starters. Therefore, if you want to integrate with Redis, you can first include:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Copy the code

If you want to integrate with MongoDB, you need to:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
Copy the code

With the help of starters, these cumbersome configurations can be well integrated and work together, and they’re all tested and proven. This goes a long way toward avoiding the dreaded Jar hell.

Dzone.com/articles/wh…

Some configuration classes can be excluded from automatic configuration by using the following annotation properties:

@EnableAutoConfiguration(exclude ={ClassNotToAutoconfigure.class})
Copy the code

But this should only be done when absolutely necessary.

The official documentation for auto-configuration can be found here:

Docs. Spring. IO/spring – the boot…

Use Spring Initializr to start a new Spring Boot project

This best practice comes from Josh Long (Spring Advocate, @starbuxman).

Spring Initializr provides a super easy way to create a new Spring Boot project and load any dependencies you might use based on your needs.

start.spring.io/

Creating an application using Initializr ensures that you have tested and verified dependencies for Spring automatic configuration. You might even find some new integrations that you might not be aware of.

Consider creating your own automated configuration for common organizational problems

This one is also from Josh Long (Spring Advocate, @starbuxman) — this practice is for power users.

If you work for a company or team that relies heavily on Spring Boot and have common issues to resolve, you can create your own automatic configuration.

This task involves a lot of work, so you need to consider when the benefits are worth the investment. It is easier to maintain a single automatic configuration than multiple slightly different custom configurations.

If this provides the Spring Boot configuration as an open source library, it will greatly simplify the configuration for thousands of users.

Design the code directory structure correctly

While allowing you a great deal of freedom, there are some basic rules worth following when designing your source code structure.

Avoid default packages. Make sure everything (including your entry points) is in a well-named package to avoid unexpected situations related to assembly and component scanning;

Keep application.java (the entry class for your Application) in the top-level source directory;

I recommend putting controllers and services in function-oriented modules, but this is optional. Some very good developers have suggested putting all controllers together. No matter what, stick to one style!

Keep @Controller simple and focused

A Controller should be very simple. You can read the description of the controller pattern section of GRASP here. You want the controller to act as a coordinator and delegate, not to perform the actual business logic. Here are the main practices:

En.wikipedia.org/wiki/GRASP (…

  • Controllers should be stateless! By default, controllers are singletons, and any state can cause a lot of problems;
  • Controllers should not execute business logic, but rely on delegates;
  • The controller should handle the HTTP layer of the application and should not be passed to the service;
  • Controllers should be designed around use cases/business capabilities.

To get into this, you need to take a closer look at best practices for designing REST apis. Whether you want to use Spring Boot or not, it’s worth learning.

Build @Service around business functions

Service is another core concept of Spring Boot. I find it best to build services around business functions/domains/use cases (whatever you want to call them).

Design services with names like AccountService, UserService, and PaymentService in your application, Rather than DatabaseService, ValidationService, CalculationService, etc.

You can decide to use a one-to-one mapping between Controler and Service, which would be ideal. But that doesn’t mean services can’t call each other!

Make the database independent of the core business logic

I wasn’t sure how best to handle database interactions in Spring Boot. After reading Robert C. Martin’s “Clear Architecture,” it became much clearer to me.

You want your database logic to be separate from the service. Ideally, you don’t want the service to know which database it is communicating with, which requires some abstraction to encapsulate the persistence of the object.

Robert C. Martin strongly states that your database is a “detail,” which means not coupling your application to a specific database. Few people used to switch databases, and I’ve noticed that using Spring Boot and modern microservices development makes things faster.

Keep the business logic unaffected by Spring Boot code

Given the lessons of Clear Architecture, you should also protect your business logic. It’s tempting to mix all the Spring Boot code together… Don’t do that. If you can resist the temptation, you will keep your business logic reusable.

Part of the service is usually called a library. It’s easier to create if you don’t remove a lot of Spring annotations from your code.

Constructor injection is recommended

This practice comes from Phil Webb (Project lead at Spring Boot, @phillip_Webb).

One way to keep your business logic safe from Spring Boot code is to use constructor injection. Not only is the @AutoWired annotation optional on the constructor, but it also makes it easy to instantiate beans without Spring.

Familiarity with concurrency models

One of the most popular articles I’ve ever written is “Introduction to Concurrency in Spring Boot.” I think the reason for this is that the field is often misunderstood and overlooked. If not used properly, there will be problems.

www.e4developer.com/2018/03/30/…

In Spring Boot, Controller and Service are singletons by default. This introduces possible concurrency problems if you are not careful. You are also usually dealing with a limited thread pool. Familiarize yourself with these concepts.

If you are using the new WebFlux style Spring Boot application, I have explained how it works in “Spring’s WebFlux/Reactor Parallelism and Backpressure”.

Strengthen the externalization of configuration management

This goes beyond Spring Boot, although it’s a common problem when people start creating multiple similar services…

You can manually configure Spring applications. If you are working with multiple Spring Boot applications, you need to make configuration management capabilities more powerful.

I recommend two main approaches:

  • Use a configuration server, such as Spring Cloud Config;
  • Store all configuration in environment variables (configurable based on git repositories).

Any one of these options (and more of the second) requires you to work less in DevOps, but this is very common in the microservices space.

Provides global exception handling

You really need a consistent way to handle exceptions. Spring Boot provides two main approaches:

  • You should use HandlerExceptionResolver to define a global exception handling strategy;
  • You can also add the @ExceptionHandler annotation to your controller, which can be useful in certain scenarios.

This is almost the same as in Spring, and Baeldung has a detailed article on error handling between REST and Spring that is well worth reading.

www.baeldung.com/exception-h…

Using the Logging Framework

You’re probably already aware of this, but you should use Logger for logging, not system.out.println () manually. This is easily done in Spring Boot with almost no configuration. Simply get the logger instance of the class:

Logger logger = LoggerFactory.getLogger(MyClass.class);
Copy the code

This is important because it allows you to set different logging levels depending on your needs.

Test your code

This is not specific to Spring Boot, but it needs a reminder — test your code! If you don’t write tests, you will write legacy code from the start.

If someone else is using your code base, it can be dangerous to change anything there. This can be even riskier when you have multiple services that depend on each other.

Because of Spring Boot best practices, you should consider using the Spring Cloud Contract for your consumer-driven Contract, which will make your integration with other services easier to use.

Using test slices makes testing easier and more focused

This practice comes from Madhura Bhave (Spring developer, @Madhurabhave23).

Testing code with Spring Boot can be tricky — you need to initialize the data layer, connect a lot of services, simulate things… It’s actually not that hard! The answer is to use test slices.

With test slices, you can connect only parts of the application as needed. This can save you a lot of time and ensure that your tests are not tied to unused content. A blog post from Spring. IO called Custom Test Slice with Spring Test 1.4 explains this technique.

Spring. IO/blog / 2016/0…

conclusion

Thanks to Spring Boot, it has never been easier to write Spring-based micro services. I hope that with these best practices, your implementation process will not only become faster, but will also be stronger and more successful in the long run. Good luck!