Spring - DI

김도형·2022년 10월 21일
0

DI의 흐름(중요)

  1. 자동 객체 등록하기 - Component Scannig
  2. 객체 자동 연결

자동 객체 연결

DI란?

  • 사용할 객체를 외부에서 주입 받는 것
  • 변경에 유리한 코드(다형성 : 변경 포인트가 줄어드는 것)

[다형성 미적용]
변경 포인트 2개

  • SportCar car -> Truck car
  • new SportsCar(); -> new Truck();
// 변경 전 
SportCar car = new SportsCar(); 

// 변경 후(변경 포인트가 2개)
Truck car = new Truck();

[다형성 적용]
변경 포인트 1개

  • new SportsCar(); -> new Truck();
Class car {}
Class SportsCar extends Car {}
Class Truck extends Car {}

// 변경 전 
Car car = new SportsCar(); 

// 변경 후(변경 포인트가 1개)
Car car = new Truck();

자동 객체 등록하기 - Component Scannig

Component Scanning 에 대해서 세부적으로 알고 싶다면 아래 링크 참고
링크

클래스의 상속관계에 대한 자동 객체 등록

클래스의 객체는 조상 객체거나 자손 객체 모두 적용가능하다.

  1. root-context.xml에 <component-scan> Bean 추가
    검색 범위는 서브패키지까지 검색 가능
    guava 라이브러리 적용해야 component-scan 사용 가능
<context:component-scan base-package="com.devcamp.eztour"/>
  1. 패키지 내의 모든 클래스를 읽어서 set에 저장
  2. 패키지 내의 @Component(@Controller, @Service, @Repository의 메타 애너테이션) 애너테이션 적용된 모든 클래스를 찾은 후 Map 저장


[위 표는 여행사 프로젝트의 후기 게시판 component bean 등록된 Map 테이블]

component-scan 의 빈 등록의 장점

  • 코드를 줄여줄 수 있다.
  • 쉽게 추론 가능
  • 모듈간의 결합을 줄이고, 코드의 재활용성 높임.

@Component

bean id 이름 설정

  • 이름 설정은 생략가능
  • 생략 시, 참조 타입의 이름을 소문자 첫글자로만 변경해서 bean id 저장
@Component("superEngine") // 이름 설정

// 위, 아래 결과 똑같음

@Component // 이름 생략
class SurperEngine extends Engine {} 
  • <component-scan>로 @Component가 클래스를 자동 검색해서 빈으로 등록!
  • @Component는 @Controller, @Service, @Repository, @ControllerAdvice의 메타 애너테이션

    메타 애너테이션

    애너테이션을 위한 애너테이션
    @Controller, @Service, @Repository, @ControllerAdvice 애너테이션들은 메타 애너테이션인 @Component 적용되어 있음

객체 자동 연결하기(byType) - @Autowired

@Autowired 특징

  • byTpye 으로 타입 먼저 검색 후 자동 객체 연결
  • 동일한 타입이라면 이름 검색 후 자동 객체 연결
  • 생성자의 @Autowired는 생략 가능
  • 단, 기본 생성자 선언 + 다른 생성자 선언에 @Autowired 생략하여 실행하면, null 값을 반환
  • 그래서 되도록이면 @Autowired 생략하지 않는 게 좋다.
  • 주입 대상이 변수일 때, 검색된 빈이 1개 아니면 예외 발생
  • 단, @Autowired(required=false)일 때, 주입할 빈을 못 찾아도 예외 발생 x, 대신 null로 반환됨.
  • 주입 대상이 배열 일 때, 검색된 빈이 n개라도 예외 발생 x

검색 후 연결

  • component bean 의 Map에 저장된 객체 중 @Autowired 가 적용 객체 검색
  • 검색 후 타입이 맞다면 자동 연결

@Autowired 자동 연결 예제

RvwController(후기 게시판 Controller)

@Controller
public class RvwController {

    @Autowired RvwService rvwService;
    @Autowired RvwLkAdmService rvwLkAdmService;
    
	}

객체 자동 연결하기(byName) - @Resource

@Resource 특징

  • 이름으로 빈을 검색
  • 이름 생략 시, 변수 이름으로 지정
  • 일치하는 이름 없으면, 예외발생

@Autowired vs @Resource

아래 그림과 같이 동일한 결과를 보여주지만, Spring 방식은 @Autowired 이다.

@Autowired + @Qualifier 자주 사용하는 이유?

  • 변수의 이름은 변경 되는 경우 많이 발생
  • 그래서 타입 자주 변경되지 않아 @Autowired + @Qualifier 사용

타입이 중복될 경우, @Resource 사용

그림에서 보는 거와 같이 0x200(Engine), Ox400(Engine) 타입이 동일하지만 map에서의 key(Bean) 이름이 달라 @Resource 를 사용하여 자동 연결할 수 있다.

Class Car {
	@Resource(name="engine2") Engine engine; 
    @Resource Door door;
}

Bean

Spring Contanier가 관리하는 자바 객체

Srping container

  • Bean 저장소
  • Bean 저장, 관리(생성, 소멸, 연결)
profile
3년간 웹/앱, 자동제어 QA 🔜 개발자로 전향하여 현재 교육 회사에서 백엔드 개발자로 근무 중입니다.(LinkedIn : https://www.linkedin.com/in/dohyoung-kim-5ab09214b)

0개의 댓글