Let’s go

What is Spring framework?

It is an open-source framework that allows convenient Java programming.

1) Can maintain Java objects (beans) as a lightweight container

Each object(bean)’s lifecycle like creation and destruction is maintained and a wanted object can be received from Spring.

2) Through IoC, allows decoupling of application

Control authority is issued not to the user, but the framework. Thus, according to 필요, Spring calls user’s code accordingly

3) Supports DI

If there is a 의존성 in between layers or services, the Spring framework connects those 의존성s

4) Supports Aspect-Oriented Programming (AOP)

Where several modules share a certain feature like transaction, logging and security, these features can be 분리 and maintained (모듈화).

In case an additional feature that a module allocates to a core business logic overlaps amongst others, can use AOP.

AOP advantages: 1) Remove repetitive code 2) Increase code reusability 3) Easy to adapt to change

Difference between Spring and Spring boot

1) Auto Configuration feature

Spring is known as “xml hell” because at the start of Spring project, you need to do a variety of environment settings. But Spring Boot automates this process, we just have to add “spring boot starter dependency” to finish setting up and can use internal Tomcat server.

Dependency Injection DI

DI refers to instead of creating a needed object, get this object externally and use it. This allows object’s decoupling and increases code reusability.

3 ways - constructor, field injection (@Autowired) and setter but we all know constructor is best right? ^^ cuz it 1) avoids circular references 2) ensures immutability 3) suitable for test cases

제어의 역전 IOC

IOC refers to the control 제어권 of all objects’ lifecycle is not to the coder, but to the IOC container. When Spring creates these objects in its IOC container, it gives DI within objects and registers these objects as “beans”.

How to register Bean

1) Easy way is to use @Component annotation, that is detected through component scan. @Controller, @Service and @Repository all includes this @Component annotation.

2) Create a 설정 클래스 separately and add @Configuration annotation to it. In that class, create method that registers bean, and add @Bean annotation, which automatically generates bean object.

1-liner: @Component or @Bean

Spring’s singleton pattern

When Spring creates beans, default is singleton. Spring generates and manages this singleton object through its container so that whenever a request comes, it does not create an object each time. Instead, it shares this already-made singleton object for efficient usage.

Advantage: 1) no need static method or private constructor to code OOP way 2) easy to test

Spring’s prototype pattern

Unlike singleton, prototype bean is whenever there is request for bean, container creates an object each time and returns that. As you can see, advantage of Spring is we can just change bean scope easily. The setting for bean scope is @Scope annotation and if you want to set prototype, do @Scope(“prototype”).

About bean’s lifecycle

Creation of IOC Container -> Spring bean created -> DI -> 초귀화 콜백 method called -> use bean -> 소멸 전 콜백 method called -> Spring exits

Bean 생명주기 콜백 ways

1) Interface implementation (InitialsingBean, DisposableBean) 2) At setting, allocate 초기화 and 종료 methods 3) @PostConstruct and @PreDestroy annotation

Difference between @RequestBody, @RequestParam and @ModelAttribute

@RequestBody converts incoming client’s HTTP body’s content in JSON format to java object through MessageConverter. The value is not injected but converted (using Reflection) so without constructor, getter and setter, variables are normally 할당ed.

@RequestParam is to get just one HTTP parameter. The default is true (default=true) so you MUST have a parameter. If not, can cause Error 400 and if it is optional parameter, need to set required=false.

@ModelAttribute is to inject HTTP Body content and HTTP parameters through constructor, getter or setter. The value, unlike @RequestBody, is not converted but injected, so variables without constructor, getter or setter are not updated.

When are the methods generated by Lombok actually created?

Lombok creates additional code when methods are at the compilation stage. This is called annotation processing, which is a technique that Java compiler analyses annotations and takes care of them during compilation stage.

(This is why when we add Lombok library, CompileOnly and AnnotationProcessor are also added)

VO, BO, DAO, DTO

Data Access Object (DAO) - object to approach DB’s data (Repository or Mapper)

Business Object (B0) - object that uses several DAO to handle business logic (Service)

Data Transfer Object (DTO) - object for data transfer between layers (layers mean Controler, Repository, View, etc)

Value Object (VO) - object that saves actual real data

Transactional

Adding @Transactional on method or class, through AOP a proxy object that inherits Target object, or interface that Target inherits, is created.

When proxy method is called, transaction is done before and after target method.

@Transactional is applied on Bean’s method A. When Bean’s method B is called that internally calls method A, what is the flow?

Proxy only happens when client calls a Target object. So if target object’s method calls its other method, proxy does not work. (client should call to make proxy work) So since method A is not 프록시로 감싸진 method, normal code instead of transaction is executed.

method A exisis in Service and in that method, calls 3 local transactions. If we add @Transactional to method A, what is the flow?

calling local transaction means call transactional methods from another Service object.

It depends on transaction’s spread level but if the default of Required is applied, all local 3 transactions are combined with the parent transaction A.

This makes sense cuz if there is a problem in parent transaction A or any of the 3 local transactions, they are all in 1 same transaction so can all rollback changes.

Why do we use @Transactional’s readOnly property

In transaction where it is not used for edit or delete but just for ReadOnly purposes.

It is used cuz Persistence Context does not need to manage this entity so can increase memory efficiency and also can mark it as “데어터 변경 불가능” logic, which increases code reusability.

For transactions that have no readOnly property, 데이터 조회 결과 entity is managed by PC, so 1차 caching and dirty checking is possible and done. But when querying, instance snapshot (to see if there is any changes) is generated and saved so this unfortunately increases memory usage.

N +1 issue and solution

For 1 query, N additional unwanted queries are done. Problem arises cuz when querying an entity that has 연관관계, it queries that table and then, queries all joined tables separately. Use “fetch join”. This 미리 combines and joins these 2 tables so that it brings all the data at once.