16 Best Practices in SpringBoot Production

Click above to follow “Terminal R&D Department


Set it as a "star" to master more database knowledge with you

This practice is based on my experience in actual projects.

The Spring Boot project itself uses and integrates a large number of open source projects, which help us maintain these third-party dependencies. But there are also some that are not included in the actual project use, which requires us to maintain the version in the project ourselves. If many undeveloped modules are included in a large project, it will be very cumbersome to maintain.

How to do it? In fact, Spring IO Platform does this. It is a sub-project of Spring Boot and maintains other third-party open source libraries. We can learn from Spring IO Platform to write our own basic project platform-bom, and all business module projects should be introduced in the form of BOM. In this way, when upgrading third-party dependencies, only the version of this dependency needs to be upgraded.

<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>

ff91574cfa1b0ac66e3f31cff9a01efb.png

2. Use automatic configuration

4187200cd7f5131dcc560321be505edd.png

A major feature of Spring Boot is the use of auto-configuration. This is the part of Spring Boot that simplifies your code and makes it work. Auto-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. So 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>

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

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

With the help of these starters, these cumbersome configurations can be well integrated and work together, and they are all tested and verified. This is very helpful in avoiding the dreaded Jar hell.

https://dzone.com/articles/what-is-jar-hell

Certain configuration classes can be excluded from auto-configuration by using the following annotation attributes:

@EnableAutoConfiguration(exclude={ClassNotToAutoconfigure.class})

But you should only do this when absolutely necessary.

Official documentation on auto-configuration can be found here:

https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html.

17c1d80cfa841dd554c7ad855081027c.png

3. Use Spring Initializr to start a new Spring Boot project

5306c1db32d73d387834b8174636fbf1.png

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 possible dependencies according to your needs.

https://start.spring.io/

Creating an application with Initializr ensures that you get tested and verified dependencies that work with Spring auto-configuration. You might even discover some new integrations that you might not have realized were there.

238023f1d9ff0402a2848223c2f9c985.png

4. Consider creating your own auto-configurations for common organizational issues

7e0751968da73d7e44c57dd009908de6.png

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

If you work in a company or team that relies heavily on Spring Boot and have common problems to solve, then you can create your own auto-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 Spring Boot configuration is released as an open source library, it will greatly simplify the configuration work for thousands of users.

f176cb82bc900ef24c2c7c449120693b.png

5. Correctly design the code directory structure

c4ed4b936aeffbaa8ccc3de597defef6.png

Although you are allowed a great deal of freedom, there are some basic rules worth following to design your source code structure.

Avoid default packages. Make sure everything (including your entry point) is in a well-named package so you can avoid surprises related to assembly and component scanning;

Keep Application.java (the application’s entry class) in the top-level source code directory;

I recommend putting controllers and services in function-oriented modules, but this is optional. Some very good developers suggest keeping all controllers together. Either way, stick to one style!

15dea5a368cc8f868442c6c1c633c93f.png

6. Keep @Controller simple and focused

fb3406a42abfc7687284946c69d2759d.png

Controller should be very simple. You can read about the controller pattern in GRASP here. You want the controller to be in the role of coordinating and delegating, not executing actual business logic. The following are the main practices:

https://en.wikipedia.org/wiki/GRASP(object-orienteddesign)#Controller

1. The controller should be stateless! Controllers are singletons by default, and any state can cause a lot of problems;

2. The controller should not execute business logic, but rely on delegation;

3. The controller should handle the HTTP layer of the application, this should not be passed to the service;

4. Controllers should be designed around use cases/business capabilities.

To go deep into this content, you need to further understand the best practices for designing REST APIs. Whether you want to use Spring Boot or not, it’s worth learning.

27392e11638b81035a8e9bf8c5fb7da1.png

7. Build @Service around business functions

a7c25cc25862c6c0c53e5ca1ff7f5dff.png

Service is another core concept of Spring Boot. I’ve found that services are best built around business functions/domains/use cases (whatever you call them).

Design services with names like AccountService, UserService, PaymentService in the application, compared to DatabaseService, ValidationService, CalculationService would be more appropriate.

You can decide to use a one-to-one mapping between Controler and Service, that would be ideal. But this does not mean that Services cannot call each other!

ffe41ca779a1827c79b878e8418dcaa9.png

8. Make the database independent of the core business logic

acb9fc571c14fd3ca0ccb9f58c4c0dad.png

I wasn’t sure how to best 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 separate from the service. Ideally, you don’t want the service to know which database it’s talking to, which requires some abstraction to encapsulate object persistence.

Robert C. Martin strongly states that your database is a “detail”, which means not coupling your application to a specific database. Few people have switched databases in the past, and I’ve noticed that things go much faster with Spring Boot and modern microservices development.

60cfd0a6dcf31870b05330f6d30db94f.png

9. Keep business logic free from Spring Boot code

848da3f9336c5d485768f6b6bb960b5a.png

Considering the lesson of “Clear Architecture”, you should also protect your business logic. It’s very tempting to mix all kinds of Spring Boot code together…don’t do it. If you can resist the temptation, you’ll keep your business logic reusable.

Parts of services are often called libraries. Easier to create without removing a lot of Spring annotations from the code.

de66c69650510f9c5c95dbe5f65b431e.png

10. It is recommended to use constructor injection

bd165b92d98d0184d4ec5565c5b0762f.png

This practice comes from Phil Webb (Project Lead of Spring Boot, @phillip_webb).

One way to keep business logic safe from Spring Boot code is to use constructor injection. Not only because the @Autowired annotation is optional on the constructor, but also to easily instantiate the bean without Spring.

8a6760564951169ce8f45f5ba8824cb5.png

11. Familiar with the concurrency model

3633d1f78e8f4a3587a0278b10ea2b70.png

One of the most popular articles I’ve written is “Introduction to Concurrency in Spring Boot”. I think the reason for this is that this field is often misunderstood and overlooked. If used incorrectly, problems can arise.

https://www.e4developer.com/2018/03/30/introduction-to-concurrency-in-spring-boot/

In Spring Boot, Controller and Service are singletons by default. This introduces possible concurrency issues if you’re not careful. You’re also generally dealing with a limited thread pool. Please familiarize yourself with these concepts.

If you’re using the new WebFlux style of Spring Boot applications, I’ve explained how it works in “Spring’s WebFlux/Reactor Parallelism and Backpressure”.

c8cf19b535a0fd8f7d60458950a00ada.png

12. Strengthen the externalization of configuration management

391c1e61758610ce3b821d13318ab554.png

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

You can manually handle configuration of Spring applications. If you are dealing with multiple Spring Boot applications, you need to make configuration management more powerful.

I recommend two main approaches:

1. Use a configuration server, such as Spring Cloud Config;

2. Store all configurations in environment variables (can be configured based on git warehouse).

Either of these options (the second one more so) requires you to do less work in DevOps, but this is common in the microservices world.

7cb669586beb41d4f41ef7cf000f82e3.png

13. Provide global exception handling

4e394359a5b252086fd0745bf0d71eed.png

You really need a consistent way of handling exceptions. Spring Boot provides two main approaches:

1. You should use HandlerExceptionResolver to define a global exception handling strategy; 2. You can also add the @ExceptionHandler annotation to the controller, which may be useful in some specific scenarios.

This is pretty much the same as in Spring, and Baeldung has a detailed article on error handling in REST with Spring, well worth a read.

https://www.baeldung.com/exception-handling-for-rest-with-spring

5482272a1f5fcff803744e850dfeca0d.png

14. Use a logging framework

6146abbf926c1e8254f84b557c7ea87e.png

You’re probably already aware of this, but you should be using a Logger for logging, not doing it manually with System.out.println() . This is easily done in Spring Boot with little to no configuration. Just get a logger instance of that class:

Logger logger = LoggerFactory. getLogger(MyClass. class);

This is important because it lets you set different logging levels as needed.

9cf9e3113efa4078e3e6de151874223b.png

15. Test your code

91ecbcee92bd641d954e39b76903aa4f.png

This isn’t Spring Boot specific, but it calls for a reminder – test your code! If you don’t write tests, you’re writing legacy code from the start.

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

Since there are Spring Boot best practices, you should consider using Spring Cloud Contract for your consumer-driven contracts, which will make your integration with other services easier to use.

7c2335021505157eaa7e8ca4eb1f3554.png

16. Use test slices to make testing easier and more focused

4432bf405ccb7c1953a0d3cede8fb3a2.png

This practice comes from Madhura Bhave (Spring Developer, @madhurabhave23).

Testing code with Spring Boot can be tricky – you need to initialize the data layer, wire up a bunch of services, mock things…it’s actually not that hard! The answer is to use test slices.

Using test slices, you can wire only parts of your application as needed. This saves you a lot of time and ensures 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.

https://spring.io/blog/2016/08/30/custom-test-slice-with-spring-boot-1-4

6d805a9fc731072197ebaffcb71e3dee.png

Summarize

e29ac13e318ec6e7ca4d4d530b0b57a4.png

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

Reposted from: e4develop

Link: www.jdon.com/49696

If you see this, it means you like this article, please forward and like it. At the same time, star (top) this official account can receive blog posts as soon as possible.

433eed4f30f24d2bb53ee41b60b3c416.jpeg

Reply [idea activation]You can get the activation method of idea

Reply 【Java】 Get video tutorials and materials related to java

Reply 【SpringCloud】 Get more learning materials related to SpringCloud

Reply 【python】 Get a full set of 0 basic Python knowledge manual

Reply 【2020】 Get 2020java-related interview question tutorials

Reply [Add group] to join the technical exchange group related to the terminal research and development department

read more

Before using Spring’s BeanUtils, it is recommended that you first understand these pitfalls!

lazy-mock, a tool for lazy people to generate backend mock data

Early adopters on Huawei Hongmeng OS, my first “hello world”, take off!

ByteDance side: Is i++ thread-safe?

An accident caused by SQL, the colleague was fired directly! !

Too heartbroken! Investigate that the CPU of Alibaba Cloud ECS reaches 100%

A powerful swagger-ui written by vue, a bit showy (with open source address)

Believe in yourself, there is nothing impossible, only unexpected

Get more than technology here!

a3c1f08d9788b37cbb0abc8d6c66f73c.png

a1ce114241d2d32d79f3423f9728c59a.gif

Give a “Looking” if you like it090c1958532bcc4ba7845c0b8d474fa7.g if