코드스테이츠 BE 37일차 - Spring Framework DI 2

coding infant·2022년 8월 12일

코드스테이츠BE

목록 보기
37/48

[학습 목표]

Spring Container와 Bean의 의미를 이해할 수 있다

Bean Scope의 의미를 이해할 수 있다

Java 기반 Container 설정에 대해 이해할 수 있다

Spring DI(Dependency Injection)의 의미를 이해할 수 있다

Component 스캔에 대해 이해할 수 있다

스프링 컨테이너는 스프링 프레임워크의 핵심 컴포넌트. 내부에 존재하는 애플리케이션 빈의 생명주기를 관리. 인터페이스로 구현 (다형성 적용)

Bean들의 생명 주기 관리

관리하기 위해 IoC 사용

애너테이션 기반 컨테이너 구성

BeanFactory, ApplicationContext 두 개의 컨테이너로 DI가 이루어진 빈들을 제어하고 관리


// Spring Container 생성
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
 [Spring Container 종류]

- BeanFactory : 스프링 설정 파일에 등록된 Bean 객체를 생성하고 관리하는 컨테이너. getBean()으로 빈 인스턴스화. @Bean 메서드명을 사용해 빈 등록

- ApplicationContext : BeanFactory를 상속하여 Bean 객체 관리. 트랜잭션 관리, 메세지 기반의 다국어 처리 등 (부가 기능 : MessageSource, EnvironmentCapable, ApplicationEventPublisher, ResourceLoader 등)

컨테이너 인스턴스화


// Annotation
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
 [new와 생성자 주입 코드 차이점]

// new 사용하여 직접 객체 생성
public class OrderServiceImpl implements OrderService {
    private final UserRepository userRepository = new UserRepositoryImpl();
    private final DiscountInfo discountInfo = new RateDiscountInfo();

@Override
public Order createOrder(Long userId, String itemName, int itemPrice) {
    User user = userRepository.findByUserId(userId);
    int discountPrice = discountInfo.discount(user, itemPrice);
    return new Order(userId, itemName, itemPrice, discountPrice);
    }
}


// 생성자 주입
public class OrderServiceImpl implements OrderService {
    private final UserRepository userRepository;
    private final DiscountInfo discountInfo;
    public OrderServiceImpl(UserRepository userRepository, DiscountInfo discountInfo) {
        this.userRepository = userRepository;
        this. discountInfo = discountInfo;
    }
    @Override
    public Order createOrder(Long userId, String itemName, int itemPrice) {
        User user = userRepository.findByUserId(userId);
        int discountPrice = discountInfo.discount(user, itemPrice);
        return new Order(userId, itemName, itemPrice, discountPrice);
    }
}

new 사용 : 직접 객체 생성

생성자 주입 : 의존 객체 주입. 느슨한 의존 관계

Bean : 애플리케이션에서 사용하는 인스턴스화된 객체. 설정 정보와 함께 스프링 컨테이너에 등록, 관리되는 재사용 소프트웨어 컴포넌트. 클래스의 정보, 게터/세터 메서드 포함

Bean 접근 방법


// Create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("service.xml", "daos.xml");

// retrieve configure instance
PetStoreService service = context.getBean("cmarket", cmarketService.class);

// use configure instance
List<String> userList = service.getUsernameList();
 ​

Java Bean vs Spring Bean

Java Bean : 클래스에서 getter/setter만 가지고 있는 클래스

[Bean Definition]

Bean 설정 메타정보

Spring Container은 BeanDefinition 이라는 추상화를 통해 Spring Bean을 생성

BeanClassName : 생성할 빈의 클래스명

factoryBeanName : 팩토리 역할의 빈을 사용할 경우 이름 (ex. appConfig)

factoryMethodName : 빈을 생성할 팩토리 메서드 지정 (ex. userService)

Scope : 싱글톤

lazyInit : 실제 빈을 사용할 때 까지 최대한 빈 생성을 지연 처리하는지 여부

InitMethodName : 빈을 생성하고 의존관계를 적용한 뒤에 호출되는 초기화 메서드 명

DestroyMethodName : 빈의 생명주기가 끝나서 제거하기 전에 호출되는 메서드 명

Constructor arguments, Properties : 의존관계 주입에서 사용.


static AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
/*
AppConfig.class를 파라미터로 ac(ApplicationContext) 생성시 AppConfig.class 바탕으로 BeanDefinition 객체 만듬.
스프링은 이것을 바탕으로 빈을 생성
AnnotiationConfigApplicationContext에 AppConfig.class 넘겨줄 때 
BeanDefinition의 구현체인 AnnotationGenericBeanDefinition 만듬
해당 객체에서 Bean 메타정보 가지고 Spring Contatiner에서 Bean 생성
*/

[애너테이션]

@Configuration

@Bean

@ComponetScan

@Component


@Configuration      // @Bean 애너테이션 메서드에 추가하여 Bean 선언
public class AppConfig {
    @Bean
    public TransferServiceImpl transferService() {
        return new TransferServiceImpl();
    }
}
 public interface BaseConfig {
    @Bean
    default TransferServiceImpl transferService() {
        return new TransferServiceImpl();
    }
}
@Configuration
public class AppConfig implements BaseConfig {
}
// Bean 정의 있는 인터페이스 구현하여 Bean configuration 설정

다양한 의존관계 주입 방법

  • 생성자 주입

  • 수정자 주입(setter 주입)

  • 필드 주입

  • 일반 메서드 주입

[생성자 주입]

생성자 통해 의존관계 주입

생성자 호출 시접에 1번만 호출

불변과 필수 의존 관계에 사용

생성자

이후 수정 예정

0개의 댓글