[JAVA] I haven't understood after touching Spring Boot for a month

Introduction

It's been a month since I implemented an application using Spring Boot. However, there are still many parts that I do not understand well, so I will summarize what I studied here as a note change: v:

What is DI (Dependency Injection)?

A type of IoC (Inversion of Control). There seems to be a Service Locator in the IoC, but please refer to [here](https://www.nuits.jp/entry/servicelocator-vs-dependency injection).

DI is an abbreviation for Dependency Injection, which is the basis of all Spring. To briefly explain DI, it is *** Instance Management ***.

What is instance management ...?

--In the DI container, create a new class and create an instance. --Manages whether to pass a new instance to the application every time in DI or to pass a new instance to the application once. --Instances can be easily registered and implemented in the request scope and session scope of the Servlet.

What is Dependency Injection ...? What does DI do?

See here for the meanings of "dependency" and "injection" in DI. If you don't understand the term "dependency injection", you can change it to "object injection". DI makes it easy to do the above two things at the same time, but there are many others. : point_down:

Find a DI managed class (component scan)

When Spring is started, a process called component scan runs and searches for a class with the following target annotations managed by DI. @Component @Controller @Service @Repository @Configuration @RestController @ControllerAdvice @ManagedBean @Named

Instance creation and injection

Instantiate and inject beans registered in the DI container. After collecting the DI target classes (Beans), DI creates (new) those instances. Then, the generated instance is injected (assigned) by the following method.

Injection method

***-Field injection (deprecated) ***

For field injection, just add @Autowired to the field (member variable) and the instance will be injected (assigned).

@Autowired
private SampleService sampleService;

However, it has been deprecated due to the following disadvantages ...

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

So now we use the following constructor injection:

*** ・ Constructor injection ***

@Service
@Transactional
public class SampleService {

  private final SampleRepository sampleRepository;

  // spring4.After 3 when there is one constructor@Autowired can be omitted
  @Autowired
  public SampleService(SampleRepository sampleRepository) {
    this.sampleRepository = sampleRepository;
  }

}

For easier writing, take advantage of Lombok. Just annotate @RequiredArgsConstructor to the class: point_down:

@Service
@Transactional
@RequiredArgsConstructor
public class SampleService {

  private final SampleRepository sampleRepository;

}

What is a bean?

The class managed on the DI container is called "Bean". Refers to a class with @ Component or @ Controller annotation, or a class registered in a DI container with a method written as @Bean.

How to implement DI

How to implement JavaConfig DI

First, define the bean to be registered in the DI container.

JavaConfig.java


@Configuration
public class JavaConfig {
  @Bean
  public SampleComponent sampleComponent {
    return new SampleComponent();
  }
  @Baan
  public SampleController sampleService {
    return new SampleService();
  }
}

Now, the return value of the getter with @Bean is registered as the Bean of the DI container. In JavaConfig, it is necessary to prepare methods for instances managed by DI container. However, you can set the values to be passed to the constructor etc. when creating an instance, and you can switch the JavaConfig class between the production environment and the development environment.

Annotation-based DI implementation

In annotation base, Spring automatically registers classes with @ Component and @ Controller in the DI container.

What is DI lifecycle management ...?

Lifecycle management is the management of instance creation (new) and destruction. When using a Servlet to create a Web application, the instance is registered in the Session scope or Request scope, but it is necessary to know exactly when the instance will be destroyed.

What is a scope ...?

The Session scope and Request scope are the expiration dates of instances. The expiration dates of the two scopes are different as follows.

Session scope

The expiration date is from the user logging in to logging out. For example, you can have information such as whether the user is logged in as a Session scope. The code below pulls the code I used when I created an application that uses OAuth.

OAuthDTO.java


@Data
@Component
@SessionScope
public class OAuthDTO {
  private boolean isLogin;
}

Request scope

One HTTP request expires. For example, the scope of Request is from the user login screen to the transition to the user profile screen by pressing the login button. I used it in the interceptor which is processed before the controller is called.

OAuthInterceptor.java


@Component
@RequiredArgsConstructor
@RequestScope
public class OAuthInterceptor extends HandlerInterceptorAdapter {
  private final OAuthDTO oAuthDTO;

  /** {@inheritDoc} */
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws AuthenticationException {
    if (!oAuthDTO.isLogin()) {
      throw new AuthenticationException("Please login.");
    }
    return true;
  }
}

Other scopes

*** ・ singleton *** Create only one instance when Spring starts. After creation, one instance is shared and used. Since it is the default setting, if you do not add the @ Scope annotation, it will be a singleton.

*** ・ prototype *** An instance is created each time you get a bean

*** ・ globalSession *** Instances are created for each Global Session in the portlet environment. It can be used only for Web applications that support portlets.

*** ・ application *** Instances are created for each context of the Servlet.

As mentioned above, you can easily create and destroy an instance by using the @ Scope annotation.

Things to watch out for in DI

singleton If you do not add the @ Scope annotation, the instance will be created with a singleton. That is, only one instance of the object can be created. If you are not aware of the scope, it may cause bugs.

Difference in scope

For example, if an instance of singleton scope has a session scope object.

OAuthDTO.java


@Data
@Component
@SessionScope
public class OAuthDTO {
  private boolean isLogin;
}

OAuthService.java


@Service
@RequiredArgsConstructor
public class OAuthService {
 
   private final OAuthDTO oAuthDTO;

}

~~ If this happens, the Bean (OAuthDTO.java) with the session scope will change to the singleton scope. ~~

*** Added on April 28 *** I'm sorry. This part was wrong: bow:

@SessionScope has been available since Spring 4.3 and was originally @Scope(value = “session”, proxyMode = ScopedProxyMode.TARGET_CLASS) is. So, proxyMode = ScopedProxyMode.TARGET_CLASS is called *** Scoped Proxy ***, which injects the bean wrapped in Proxy, and when you call the method of the injected bean, it actually looks from the DI container. The method is delegated to the uploaded Bean.

In other words ... No change in scope occurs. Currently, scoped-proxy makes it possible to receive things with a narrower scope than itself from the DI container without worrying about the controller or interceptor.

For prototype etc., it is good to refer to the following.

-How to use prototype scope in Spring Boot & Benchmark

However, the code in the above example is not correct. By injecting OAuthDTO.java into OAuthService.java, the Service class has a state. The Service class is not only called from the *** Controller class ***, so if you have a state bound to a specific context such as an HTTP request before the scope, it will be executed on a route that does not exist. Sometimes the question is where to source the instance.

Therefore, in the code in the above example, OAuthDTO.java should be injected into the Controller class.

For the actual implementation method, refer to the following.

-4.3. Session Management -Spring MVC 4.0 No. 029 Make component session scope -Spring Bean Scope Quick Guide -Three patterns for handling HTTP sessions with Spring Boot

Site summary that is often referred to from here

Annotation

-[List of annotations frequently used in Spring Boot](https://learning-collection.com/spring-boot%E3%81%A7%E3%82%88%E3%81%8F%E4%BD%BF%E3 % 81% 86% E3% 82% A2% E3% 83% 8E% E3% 83% 86% E3% 83% BC% E3% 82% B7% E3% 83% A7% E3% 83% B3% E4% B8 % 80% E8% A6% A7 /) -7. Spring Framework Annotation List (IT Technology Comprehensive Wiki) -Spring Boot Annotations

Lombok -Lombok --Constructor generation

Code review points

-Spring Boot Application Code Review Point

Recommended Posts

I haven't understood after touching Spring Boot for a month
How to write a unit test for Spring Boot 2
[Spring Boot] How to create a project (for beginners)
I wrote a test with Spring Boot + JUnit 5 now
Introducing Spring Boot2, a Java framework for web development (for beginners)
Spring Boot for annotation learning
I made a simple MVC sample system using Spring Boot
I tried Spring Boot introductory guide [Building a RESTful Web Service]
How to make a hinadan for a Spring Boot project using SPRING INITIALIZR
I made a simple search form with Spring Boot + GitHub Search API.
Spring Boot Introductory Guide I tried [Consuming a RESTful Web Service]
A story that I finally understood Java for statement as a non-engineer
Spring Boot for the first time
Frequent annotations for Spring Boot tests
Use DBUnit for Spring Boot test
I tried GraphQL with Spring Boot
A memo that touched Spring Boot
I tried Flyway with Spring Boot
Create a Spring Boot project in intellij and exit immediately after launching
I got stuck using snake case for variable name in Spring Boot
[Spring Boot] I stumbled upon a method call count test (Spock framework)
[LINE BOT] I made a ramen BOT with Java (Maven) + Heroku + Spring Boot (1)
ViewComponentReflex A note I saw by touching
What is a Spring Boot .original file?
WebMvcConfigurer Memorandum of Understanding for Spring Boot 2.0 (Spring 5)
I tried Lazy Initialization with Spring Boot 2.2.0
I made a plugin for IntelliJ IDEA
03. I sent a request from Spring Boot to the zip code search API
I tried to clone a web application full of bugs with Spring Boot