
객체를 내가 직접 생성하고 연결하지 않고,
스프링 컨테이너가 객체 생성과 의존관계를 관리하도록 맡기는 것
예제 코드
public class OrderService {
private PaymentService paymentService = new PaymentService();
}
OrderService가 직접:
PaymentService 객체 생성예제 코드
@Service
public class OrderService {
private final PaymentService paymentService;
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
@Service
public class PaymentService {
}
PaymentService 객체를 누가 만드는가?(생성) → Spring ContainerOrderService에 누가 넣어주는가?(주입) → Spring Container객체에 대한 제어권이 개발자 → 프레임워크로 넘어갔기 때문에 IoC(제어의 역전)라고 한다.
DI는 IoC를 구현하는 대표적인 방법으로,
필요한 객체를 내부에서 직접 생성하지 않고 외부에서 전달받는 것이다.
public class OrderService {
private PaymentService paymentService;
}
OrderService가 정상적으로 동작하려면 PaymentService가 필요하다.OrderService → (의존관계) → PaymentService public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
PaymentService를 외부에서 넣어준다.| 개념 | 의미 |
|---|---|
| IoC | 객체 생성/관리의 제어권을 Spring에 넘기는 설계원칙 |
| DI | 필요한 객체를 외부에서 주입하는 방식 |
| Spring Container | IoC와 DI를 실제로 수행하는 주체 |
@Service, @Component, @Repository, @Controller이 붙은 클래스는ApplicationContext가 IoC Container 역할을 한다. IoC Container
│
├── 📦 BeanFactory
│ └─ Bean 관리의 가장 기본 기능
│
└── 📦 ApplicationContext
└─ BeanFactory 기능 + 여러 부가 기능
BeanFactory : 기본적인 Bean 생성/조회/관리 기능을 제공ApplicationContext : BeanFactory를 확장하여 그 기능을 포함하면서 여러 부가 기능 제공간만에 스프링 공부하니까 개ㅐ어지럽다.
다양한 어노테이션과 개념들이 연달아 쏟아지듯 등장하면서 뇌가 지끈거렸는데
각각 따로 보면 헷갈리지만
결국 모두 스프링이 객체를 생성하고 관리하면서 필요한 객체끼리 연결하는 과정과 관련된 개념이다.
@SpringBootApplication
↓
@ComponentScan
↓
@Component 계열 클래스 탐색
↓
Bean 생성 및 등록
↓
ApplicationContext가 Bean 관리
↓
생성자 주입 / @Autowired
↓
필요한 Bean을 다른 Bean에 주입
@Component가 붙은 클래스를 발견하면 객체를 생성하고 스프링 Container에 Bean으로 등록한다.@Controller
@Service
@Repository
@Component 계열 어노테이션이 붙은 클래스를 찾아 Bean으로 등록한다.@SpringBootApplication안에 @ComponentScan이 포함되어 있으니까 !!!@SpringBootApplication이 있는 현재 패키지+하위 패키지 스캔
@SpringBootApplication
├─ @SpringBootConfiguration
│ └─ @Configuration
├─ @EnableAutoConfiguration
└─ @ComponentScan
@SpringBootConfiguration : 클래스가 Spring Boot의 설정 클래스임을 나타냄@Configuration : 클래스가 Spring의 설정 클래스임을 나타냄@EnableAutoConfiguration : 클래스 패스와 설정값을 바탕으로 필요한 설정을 자동 구성@ComponentScan : 현재 패키지와 하위 패키지의 @Component 계열 클래스를 탐색해 Bean 등록둘 다 Bean을 등록하는 방법이지만 누가 Bean 등록을 결정하느냐가 다름
| 구분 | @Component | @Configuration + @Bean |
|---|---|---|
| 붙이는 위치 | 클래스 | 설정 클래스 + 메서드 |
| 등록 대상 | 해당 클래스 자체 | @Bean 메서드가 반환한 객체 |
| 등록 방식 | Component Scan으로 자동 발견 | 개발자가 직접 Bean 생성 방법 정의 |
| 주로 사용 | 내가 만든 클래스 | 외부 라이브러리 객체, 생성 과정 커스터마이징 필요 시 |
@Component
public class PaymentService {
}
@Configuration
public class AppConfig {
@Bean
public PaymentService paymentService() {
return new PaymentService();
}
}
여러 어노테이션을 통해 Bean을 등록한 다음에는
Bean끼리 연결을 해야하는데 이때 사용하는 것이 의존성 주입(DI)이다.
@Autowired는 스프링 컨테이너에서 필요한 타입의 Bean을 찾아 자동으로 주입하도록 요청한다.예제 코드
@RestController
public class UserController {
@Autowired
private UserService userService;
}
UserService타입의 Bean을 찾아 userService 필드에 넣어준다.final 필드 사용 가능@Autowired 생략 가능@RestController
public class MemoController {
private final MemoService memoService;
@Autowired
public MemoController(MemoService memoService) {
this.memoService = memoService;
}
}
@RequiredArgsConstructor는 final 필드와 @NonNull 필드를 매개변수로 가지는 생성자를 자동으로 만들어준다.@RestController
@RequiredArgsConstrucutor
public class MemoController {
private final MemoService memoService;
}
@Autowired를 붙여 주입받는 방식final 필드에 일반적인 필드 주입을 적용 불가final과 충돌null@RestController
public class MemoController {
@Autowired
private MemoService memoService;
}
MemoController controller = new MemoController(); // 이때 memoService는 null
Setter 메서드를 통해 의존성을 전달받는 방식set..()를 호출해서 주입final 사용 불가@RestController
public class MemoController {
private MemoService memoService;
@Autowired
public void setMemoService(MemoService memoService) {
this.memoService = memoService;
}
}
필수 의존성 없이 객체를 생성하는 것을 방지할 수 있음
final 필드는 한 번 초기화되면 다른 객체로 재할당이 불가해,
의존성이 실수로 변경되는 것을 방지 할 수 있음 - Setter 주입은 변경이 가능
@SpringBootApplication
│
└── @ComponentScan
│
↓
Component Scan 수행
│
↓
@Component / @Controller / @RestController
@Service / @Repository 클래스 발견
│
↓
Bean 생성
│
↓
ApplicationContext
┌─────────────────┐
│ Bean 관리 │
│ Bean 조회 │
│ 의존성 관리 │
└─────────────────┘
│
↓
생성자 주입 / @Autowired
│
↓
Bean 간 의존성 연결