본문 바로가기

Java/Spring

의존성 주입 - 스프링 IoC컨테이너

의존성 주입을 사용하기 위해서는 객체 생성이 우선 되어야 한다.

이때, 스프링 프레임워크는 필요한 객체를 생성하여 관리하는 역할을 대신 해준다. 

 

빈 (Bean): 스프링이 관리하는 객체

스프링 IoC 컨테이너: '빈'을 모아둔 통

 

'빈' 등록 방법

이전 글(https://move22.tistory.com/148)에서 쓴 Water와 Cup을 예시로 쓰자면 다음과 같다.

 

1.@Component

@Component
public class Water {}

스프링 서버가 실행될 때 스프링 IoC 에 '빈'을 저장해 준다.

 

1-1. 스프링이 @Component 객체에 대해서 하는 일

// 1. Water 객체 생성
Water water = new Water();

// 2. 스프링 IoC 컨테이너에 빈 (water) 저장
// water -> 스프링 IoC 컨테이너

pubic class Water -> water

 

1-2.@Component 적용 조건

@ComponentScan 에 설정해 준 packages 위치와 하위 packages 들

@Configuration
@ComponentScan(basePackages = "com.example.spring")
class BeanConfig { ... }

@SpringBootApplication 에 의해 default 설정이 되어 있다.

 

2.@Bean

직접 객체를 생성하여 빈으로 등록 요청한다.

package com.example.spring.config;

import com.example.spring.object.Water;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BeanConfiguration {
    @Bean
    public Water water() {
        String division = "??";
        return new Water(division);
    }
}

스프링 서버가 실행될 때 스프링 IoC 에 '빈' 저장

// 1. @Bean 설정된 함수 호출
Water water = beanConfiguration.water();

// 2. 스프링 IoC 컨테이너에 빈 (productRepository) 저장
// water -> 스프링 IoC 컨테이너

 

'빈' 사용 방법

1. @Autowired

멤버변수 선언 위에 @Autowired → 스프링에 의해 DI (의존성 주입) 됨

@Component
public class Cup {
    @Autowired
    private final Water water;
}

'빈' 을 사용할 함수 위에 @Autowired → 스프링에 의해 DI 됨

@Component
public class Cup {
    private final Water water;
    @Autowired
    public Cup(Water water) {
        this.water = water;
    }
}
  • @Autowired 적용 조건
    • 스프링 IoC 컨테이너에 의해 관리되는 클래스에서만 가능

Spring 4.3 버젼 부터 생성자 선언이 1개일때 생략이 @Autowired  가능하다. 

public class A {
    @Autowired // 생략 불가
    public A(B b) { ... }

    @Autowired // 생략 불가
    public A(B b, C c) { ... }
}

Lombok 의 @RequiredArgsConstructor 를 사용하면 다음과 같이 코딩 가능하다.

@RestController
@RequiredArgsConstructor // final로 선언된 멤버 변수를 자동으로 생성한다.
public class ProductController {

private final ProductService productService;

// 생략 가능
// @Autowired
// public ProductController(ProductService productService) {
//     this.productService = productService;
// }
}

 

2.Aplication Context

스프링 IoC 컨테이너에서 빈을 수동으로 가져오는 방법

@Component
public class Cup {

private final Water water;

@Autowired
public Cup(ApplicationContext context) {
    // 1.'빈' 이름으로 가져오기
    Water water = (Water) context.getBean("water");
    // 2.'빈' 클래스 형식으로 가져오기
    // Class class = context.getBean(ProductRepository.class);
    this.water = water;
}

// ...
}

 

3.스프링 3계층 Annotation 적용하기

  • 스프링 3계층 Annotation 은 모두 @Component
    1. @Controller, @RestController
    2. @Service
    3. @Repository

 

 

'Java > Spring' 카테고리의 다른 글

Transaction  (0) 2022.12.28
JWT  (0) 2022.12.15
인증과 인가  (0) 2022.12.14
의존성 주입 - 강한결합  (0) 2022.12.13
영속성 컨텍스트  (0) 2022.12.12