[JAVA] Spring Boot application code review points

I have more opportunities to touch Spring Boot at work. Spring can make apps with fairly high productivity by making full use of annotations and related functions, but there are many parts that cause unintended behavior when used "somehow". This time, I would like to sort out the content that I often comment on during code reviews (although it is only a rudimentary point ...).

(1) Is it divided into Controller / Service / Repository?

In Spring, it is recommended to divide the processing of the entire application into the following three-layer structure class instead of writing it in a specific class.

layer Overview
Controller Class to be the contact point for requests
Service Class that implements business logic
Repository Class for data persistence

Since ** Controller ** is the entry point for requests, I think that developers who are new to Spring will be familiar with it, but if you create an app without thinking about anything, you will end up with ** Controller **. It is easy to implement business logic in **. Then, ** a Fat Controller with low maintainability and readability ** will be created, so I think it is a point to be strongly aware of the isolation of business logic.

Personally, I think it's best to focus on the following contents. The idea is.

When calling multiple types of Services in a Controller, the Controller tends to be large, so in that case, I feel that it is okay to create a ServiceFacade class that mediates between the Controller and the Service.

(2) Is the implementation considering the life cycle of the instance?

Instances managed by Spring DI container are ** Singleton ** by default. In other words, if you have a state with a member variable etc., the state (user ID etc.) will be mixed among users accessing the same application, and it will often not be the intended behavior. Basically, I think it is better to make it Stateless, but depending on the requirements, please consider changing to another scope supported by Spring.

scope range
Singleton One in the application
session One per session
prototype One for each access

By the way, if it is your own class, you can change the scope by adding @Scope annotation.

@Scope("prototype")
@Service
public class SecretService {
 //Processing implementation
}

As a check point of view

--Does the Singleton instance have a state? --Are you using another scope (session / prototype) unnecessarily?

The point is around.

(3) Are you using constructor injection?

Dependency injection (DI) is unavoidable when using Spring, but there are the following two methods if you do not write a configuration file. * I think that the definition in XML is still alive, but I think that few people are using it, so I will omit it.

--Field injection --Constructor injection

Field injection is easy because you just add @Autowired to the member variable.

@Autowired
private SecretService service;

However, it has been deprecated due to the following drawbacks. * I remember issuing a warning even in Spring.

--Mocking is not possible without using a DI container when creating test code --The final attribute cannot be added to the field and it cannot be immutable.

So unless you have a very good reason (such as a circular dependency), use constructor injection.

private final SecretService service

public MyClass(SecretService service) {
  this.service = service;
}

If the definition of the constructor is complicated, you can also use Lombok.

@AllArgsConstructor
public class MyClass {
  //TODO:Implementation
}

(4) Is there any processing that can be shared?

Spring provides HandlerInterceptor and AOP as a mechanism to define cross-cutting common processing. By utilizing these mechanisms

--Perform common preprocessing for all methods of all classes under a specific package --Common post-processing with methods that return a specific type of return value

In some cases, you don't have to implement duplicate processing. Is there a lot of ** log output ** as a common case?

  /**
   *Logger class
   */
  private final Logger logger = LoggerFactory.getLogger(MyController.class);
  
   
  /**
   *Request method sample.
   * @param form Form class
   * @param bindingResult Validation result
   * @return response
   */
  @RequestMapping(value = "/", method = RequestMethod.GET)
  public String handleRequest(@Valid MyControllerForm form, BindingResult bindingResult) {
    logger.info("Interceptor test");
    //abridgement
  }
}

Specifically

@Aspect
@Component
public class MyInterceptor {

  @Before("execution(* jp.co.cross_xross.controller..*.*(..))")
  public void beforeProcess(JoinPoint joinPoint) throws Throwable {
    //Preprocessing
  }
}

You can execute "pre-processing", "post-processing", and "alternative processing" by specifying the package name, method name, arguments, and return value as in.

(5) Have you implemented the functions provided by Spring yourself?

The material is running out soon (laughs) Spring provides functions that are often implemented as subprojects. I think that it is better to utilize the part that tends to be difficult to implement by yourself because it can be easily realized by using this function.

Subproject name Provided functions Remarks
Spring Session Session replication -
Spring Security Authentication function -
Spring Data data(RDBMS/KVS)operation -
Spring Social SNS(Facebook/Twitter/LinkedIn)Cooperation その他SNSとのCooperationも可能
Spring Batch Batch processing -
Spring AMQP RabbitMQ integration -

Afterword ...

I would like to confirm it together with the basic code review points of Java. From the perspective of pure Java code review, I refer to the articles of seniors written in qiita in the past.

-Reference information for successful method naming -Let's write some nice Java code -Code Review Checklist

Recommended Posts

Spring Boot application code review points
Code review points
Spring Boot 2.3 Application Availability
[Spring Boot] Web application creation
CICS-Run Java application-(4) Spring Boot application
Spring Boot application development in Eclipse
Write test code in Spring Boot
Spring Boot programming with VS Code
Inquiry application creation with Spring Boot
Implement Spring Boot application in Gradle
Processing at application startup with Spring Boot
Try using Spring Boot with VS Code
Start web application development with Spring Boot
Launch Nginx + Spring Boot application with docker-compose
Run WEB application with Spring Boot + Thymeleaf
Spring Boot2 Web application development with Visual Studio Code SQL Server connection
Challenge Spring Boot
Spring Boot2 Web application development with Visual Studio Code Hello World creation
Spring Boot Form
Spring Boot Memorandum
gae + spring boot
Introduction to Java development environment & Spring Boot application created with VS Code
Configure Spring Boot application with maven multi module
Run a Spring Boot project in VS Code
Create a Spring Boot application using IntelliJ IDEA
Deploy a Spring Boot application on Elastic Beanstalk
Create Spring Boot environment with Windows + VS Code
From creating a Spring Boot project to running an application with VS Code
Spring Boot application built-in Tomcat, Apache and WebSocket integration
SPRING BOOT learning record 01
Spring Boot + Heroku Postgres
What I was addicted to when developing a Spring Boot application with VS Code
Spring boot memo writing (1)
Try using OpenID Connect with Keycloak (Spring Boot application)
First Spring Boot (DI)
SPRING BOOT learning record 02
Spring Boot2 cheat sheet
Spring Boot with Spring Security Filter settings and addictive points
Spring Boot exception handling
[Spring boot] I thought about testable code by DI
Spring Boot Servlet mapping
Spring boot development-development environment-
Spring Boot learning procedure
Learning Spring Boot [Beginning]
Spring boot memo writing (2)
Spring Boot 2.2 Document Summary
[Spring Boot] DataSourceProperties $ DataSourceBeanCreationException
Spring boot tutorials Topics
Download with Spring Boot
Content-Type: application / json doesn't have charset = UTF-8 from Spring Boot 2.2
Implement REST API with Spring Boot and JPA (Application Layer)
[Java] Deploy the Spring Boot application to Azure App Service
Deploy the application created by Spring Boot to Heroku (public) ②
Sample web application that handles multiple databases in Spring Boot 1.5
Try hitting the zip code search API with Spring Boot
Deploy the application created by Spring Boot to Heroku (public) ①
Spring Boot application that specifies DB connection settings with parameters
[Spring Boot] Environment construction (macOS)
Set context-param in Spring Boot
Try Spring Boot from 0 to 100.
Generate barcode with Spring Boot