Spring Been이란?
스프링(Spring) 컨테이너가 관리하는 자바 객체를 빈(Bean)이라 한다.
스프링 기술
- 스프링 코어
- DI, IoC, 컨테이너 : 스프링의 근간을 이루고 전체 어플리케이션을 통제하는데 활용되는 기술
- Resource, AOP, Validation, SpEL : 많은 어플리케이션에서 공통적으로 활용하기 좋은 스프링에서 제공해주는 기능
- 스프링 Web MVC
- HTTP 요청/응답 처리 : Web MVC는 계속 어플리케이션이 요청 올때까지 대기를 하고 있음, 요청이 오면 그 즉시 처리를 하고 응답을 함
- 필터, 인터셉터 : 웹에서 들어오는 요청을 필터링 하거나 공통적인 처리를 하는 용도의 기술
- 예외처리 : 웹에서 들어온 처리를 하던 중 오류가 발생했을 때 어떻게 해야 더 안전하게 처리할 수 있을까?
DI, IoC, 컨테이너
The IoC Container :: Spring Framework
The IoC Container :: Spring Framework
This chapter covers Spring’s Inversion of Control (IoC) container.
docs.spring.io
Spring과 레고
- 레고를 만들 때 편리한 점
- 바닥에 넓은 판을 두고 그 위에 이것 저것 얹으면 편하다
- 동그란 끼우는 부분이 모두 동일하므로 어떤 것들이든 서로 끼워볼 수 있다.
- 너무 높은 자유도가 없기 때문에(오히려) 뭔가 만들기 편리하다
- Spring을 쓰면 좋은 점
- Spring이라는 넓은 판때기(컨테이너) 위에 내가 만드는 클래스만 얹으면 개발이 되므로 편하다
- Spring Bean이라는 규격에 맞춰 만들기만 하면 서로가 서로를 가져다 쓰기가 좋다
- 역설적으로 너무 자유롭진 않아서 원리를 알면 그 안에서는 만들기가 편리하다
DI (Dependence Injection)
의존성 주입
- 의존성(A가 B를 사용한다, A가 B에 의존한다)
public class SimpleMovieLister {
private MovieFinder movieFinder;
쉽게 말해, 한 객체에서 다른 객체를 가져다가 쓰면 의존성이다.
- ex) 결제 서비스가 머니어댑터와 편의점 할인을 사용한다
- 결제 서비스라는 블럭에 머니어댑터, 편의점 할인을 끼움
IoC (Inversion Of Control)
제어의 역전
- 사용자가 직접 클래스를 생성하지 않고 프레임워크(스프링)가 제어하도록 함
- 지금까지 사용자가 new 연산을 통해 객체를 생성하고 메소드를 호출했다면, IoC가 적용된 경우에는 이러한 객체의 생성과 사용자 제어권을 스프링에게 넘긴다.
- 사용자는 직접 new를 이용해 생성한 객체를 사용하지 않고, 스프링에 의해 관리 당하는 자바 객체를 사용한다.
- 이 객체를 Bean(빈)이라 한다.
- 생성 전과 후에 무언가 하고 싶은게 있다면
- Bean LifeCycle callback(빈 생명주기 콜백 함수)
- CallBack 함수란?
- Call(호출) Back(나중에)하는 함수
- 우리가 여기에 무언가 담아주면 나중에(정의된 시점에) 호출해준다.
- Bean LifeCycle
- CallBack 함수란?
- Bean LifeCycle callback(빈 생명주기 콜백 함수)
Bean life cycle in Java Spring - GeeksforGeeks
A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.
www.geeksforgeeks.org
- XML을 통한 빈 등록
- 토비의 스프링, 스프링 3/4 시절까지 많이 사용
- 설정이 외부로 명확히 분리된 것을 알 수 있음
- 하지만 자동완성이나 컴파일 등으로 오타를 잡기 어렵고 타이핑 양이 많아짐
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cardAdapter" class="com.example.account.service.CardAdapter"/>
<bean id="moneyAdapter" class="com.example.account.service.MoneyAdapter"/>
<bean id="discountByConvenience" class="com.example.account.service.DiscountByConvenience"/>
<bean id="conveniencePayService" class="com.example.account.service.ConveniencePayService">
<constructor-arg name="paymentInterfaceSet">
<set>
<ref bean="cardAdapter"/>
<ref bean="moneyAdapter"/>
</set>
</constructor-arg>
<constructor-arg name="discountInterface" ref="discountByConvenience"/>
</bean>
</beans>
- XML ComponentScan을 통한 빈 등록
- 기본 빈 등록 방식은 클래스가 많을 경우 너무 번거로움
- 자동으로 등록해줄 수는 없을까?
- @Controller, @RestController, @Service, @Component, @Repository 등의 지정된 어노테이션이 붙은 클래스를 싹 빈으로 등록해주자
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://w2-2 스프링의 핵심 5
<context:component-scan base-package="com.example.account"/>
</beans>
@Component 어노테이션이 있으면 스프링 빈으로 자동 등록되는데,
@Component를 포함하는 @Controller, @Service, @Repository 어노테이션도 스프링 빈으로 자동 등록된다.
@Controller 어노테이션을 사용하면 스프링 컨테이너 안에서 관리하에 놓이게 된다.
package hello.hellospring.controller;
import org.springframework.stereotype.Controller;
@Controller
public class MemberController {
private final MemberService memberService = new MemberService();
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
}
스프링 컨테이너에 등록 하고 사용
→ 스프링 컨테이너에 등록하면 딱 하나만 등록된다.
@Autowired란 → 주입
생성자에 @Autowired가 있으면 스프링이 연관된 객체를 스프링 컨테이너에 찾아서 넣어준다.
MemberController는 스프링 컨테이너가 뜰 때 생성한다.
이 때 생성자 호출을 하는데 즉, 생성자에 @Autowired라 되어있으면 스프링 컨테이너에 있는 MemberService를 가져다가 주입시켜준다.
이렇게 객체 의존관계를 외부에서 넣어주는 것을 DI(의존성 주입)이라 한다.
만약 이 상태로 서버를 작동시키면 memberService가 스프링 컨테이너에 스프링 빈으로 등록되어 있지 않기 때문에 오류가 발생할 것이다.
즉 memberService도 스프링 빈으로 등록해주어야 한다.
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
생성자에 @Autowired를 사용하려면 객체 생성 시점에 스프링 컨테이너에서 해당 스프링 빈을 찾아서 주입한다.
생성자가 1개만 있으면 @Autowired는 생략할 수 있다.
동일하게 memberRepository도 스프링 빈으로 등록!
@Repository
public class MemoryMemberRepository implements MemberRepository {}
- JavaConfig를 통한 빈 등록
- 스프링4 때부터 XML이 아닌 JavaConfig가 많이 활용되기 시작함
- XML 설정파일이 자바 코드화 된 것
- 자동완성, 컴파일 시 정적 분석으로 오류를 잡아줌
package com.example.account.config;
import com.example.account.service.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
import java.util.HashSet;
@Configuration
public class ApplicationConfig {
@Bean
public ConveniencePayService conveniencePayService(){
return new ConveniencePayService(
new HashSet<>(Arrays.asList(moneyAdapter(), cardAdapter())),
discountByConvenience()
);
}
@Bean
public CardAdapter cardAdapter() {
return new CardAdapter();
}
@Bean
public MoneyAdapter moneyAdapter() {
return new MoneyAdapter();
}
@Bean
public DiscountByConvenience discountByConvenience() {
return new DiscountByConvenience();
}
}
- JavaConfig ComponeneScan을 통한 빈 등록
- XML의 설정 방법
- JavaConfig에서의 설정 방법
- 스프링 부트에서는 이 방식이 기본적으로 적용되어 있으며, 그래서 편리하게 빈 등록 가능
@Configuration
@ComponentScan(basePackageClasses = ConvpayApplication.class)
public class ApplicationConfig {
}