Spring DI활용하기

SOLEE_DEV·2023년 4월 10일
0

Spring

목록 보기
6/8

@Autowired

  • 객체 자동 연결하기

isInstance

object.getClass().equals(clazz)

@Autowired vs @Resource

  • @Autowired : byType으로 먼저 찾은 후, 여러개면 이름으로 검색! ( @Qualifier )
  • @Resource : byName으로 찾음
@Resource(name="superEngine")




1. 빈(bean)이란?

JavaBeans

  • 재사용 가능한 컴포넌트, 상태(iv), getter&setter, no-args constructor

Servlet & JSP bean

  • MVC의 Model (Data 전달), EL, scopre, JSP container에 담아서 관리하는 객체!

...

Spring Bean

  • POJO (Plain Old Java Object) <-> (EJB)
  • 단순 독립적
  • Spring Container가 관리!




2. BeanFactory와 Application Context

1) Bean (POJO)

  • Spring Container가 관리하는 객체

2) Spring Container

  • Bean 저장소
  • Bean을 저장, 관리 (생성, 소멸, 연결)
    ※ (생성, 소멸) Bean의 LifeCycle을 관리
    ※ (연결) 객체 간의 관계까지 연결해줌 = Autowiring / @Autowired
  1. BeanFactory (Bean 공장) - Bean을 생성, 연결 등의 기본 기능을 정의해놓은 인터페이스
  2. ApplicationContext - BeanFactory를 확장해서 여러 기능을 추가 정의




3. ApplicationContext의 종류

  • 다양한 종류의 ApplicationContext구현체 제공

AC의 종류

1. XML

1) non-Web : GenericXmlApplcationContext
2) Web : XmlWebApplcationContext

2. Java Config

1) non-Web : AnnotationConfigApplcationContext
2) Web : AnnotationConfigWebApplcationContext

// in xml (텍스트 문서)
<bean id ... />

// in java Config (컴파일러가 관리!)
@Bean




4. Root AC와 Servlet AC

  • 두 개의 xml설정파일, 두 개의 XmlWebApplicationContext()를 만들면서 두 개를 연결해줌!
  • 부모 (공통 bean / root-context) - 자식 (개별 bean / dispatcher-servlet)
  • 부모 : non-web
  • 자식 : 각 모듈에서 쓰는 애들을 씀 web!
new XmlWebApplicationContext();

```xml ...contextConfigLocation... .../WEB-INF/spring root-context.xml... org.springframework.web.context.ContextLoaderListener ... ... /WEB-INF/.../servlet-context.xml ```

5. ApplicationContext의 주요 메서드

bean 얻기

  • getBean() : 빈 얻기 ( == @autowired)

bean 타입 확인

1) isPrototype(String name)
2) isSingleton(String name)
3) isTypeMatch(String name, Class<//T> typeToMatch)

정의된 bean 개수 확인

  • getBeanDefinitionCount()

※ 스프링 deploy 단계

  • 시스템 property값 생성 : key - value 형태
    1) Root Web AC 초기화! (root-context.xml 기반)
    ※ 해당 부분이 안되면 root-context.xml에 문제가 있다고 판단!
    2) DS 초기화 & DS 내부에 XmlWebApplicationContext 생성 (servletAC) !
    (servlet-context.xml 기반)
    3) AutowriedAnnotationBeanPostProcesseor
    4) RequestMappingHandlerMapping
    5) Deploy 끝!




6. IoC와 DI

1) 제어의 역전 IoC : 제어의 흐름을 전통적인 방식과 다르게 뒤바꾸는 것

  • Control : flow control (실행 흐름이 바뀜!)
  • 전통적인 방식 : 다른 사람이 작성한 코드를 호출
  • IoC : 사용자가 제공한 코드를 라이브러리가 호출!
    = 다른 사람이 만든 코드가 우리가 만든 코드를 호출!
  • 분리 1. 관심사 2. 변하는 것, 변하지 않는 것 3. 중복 코드
void turboDrive() {
	engine = new TurboEngine();
    // superEngine으로 바꾸고 싶으면..! 
    // 라이브러리 자체를 뜯어 고쳐야됨~~
    engine.start();
}

2) 의존성 주입 DI : 사용할 객체를 외부에서 주입받는 것

  • 라이브러리 : 단순 기능 제공
  • 프레임워크 : 기능 + 프로그래밍 패턴 / 형식 제공
car.drive(new SuperEngine()); // 수동 주입!
// 자동 주입 : @Autowired

...

void drive(Engine engine) {
	engine.start();
    ...
}

@Autowired (byType)

  • 인스턴스 변수(iv), setter, 참조형 매개변수를 가진 생성자, 메서드에 적용
  • 생성자에는 @ 생략 가능!
    => 단, 매개변수 없는 생성자가 있으면 안됨
// 1. iv
class Car {
	@Autowired Engine engine;
}
...
// 2. setter
@Autowired
public void setEngineAndDoor(Engine engine) {
	this.engine = engine;
}
...
// 3. 참조형 매개변수 생성자, 메서드에 적용
@Autowired
public Car (@Value("red") String color, Engine engine) {
	this.color = color;
    this.engine = engine;
}

=> 1,2는 빼먹을 수도 있으니까 생성자에 한꺼번에 주입하는게 나음!

  • Spring container에서 타입으로 빈 검색 -> 참조 변수에 자동 주입(DI)
  • 검색된 빈이 n개 이면, 그 중에 참조 변수와 이름이 일치하는 것을 주입!
  • 주입 대상이 변수일 때, 검색된 빈이 1개 아니면 예외 발생
    => 반드시 1개여야 함
  • 주입 대상이 배열일 때, 검색된 빈이 n개라도 예외 발생 X
  • @Autowired(required=false)일 때, 주입할 빈을 못찾아도 예외 발생 X

@Resource (byName)

  • Spring container에서 이름으로 빈을 검색해서 참조 변수에 자동 주입(DI)
  • 일치하는 이름의 빈이 없으면, 예외 발생!
class Car {
	@Resource(name="superEngine")
    Engine engine;
}

class Car {
	@Autowired // 1. 타입 검색 후,
    @Qualifier("superEngine") // 2. 어떤거 주입할지 지정!
    Engine engine;
}

class Car {
	@Resource(name="engine")
	@Resource // 이름 생략 가능!
    Engine engine;
}

@Component

  • <component-scan>으로 @Component가 클래스를 자동 검색해서 빈으로 등록
  • @Controller, @Service, @Repository, @ControllerAdvice의 메타 애너테이션
<context:component-scan base-package="com.fastcampus.ch3" />
<!-- 서브 패키지까지 다 검색해서 
     @Component 붙은 클래스들 다 모아서 빈으로 등록해줌 -->
package com.fastcampus.ch3;
import org.springframework.stereotype.*;

// 1. <bean id="superEngine" 
//    class="com.fastcampus.ch3.SuperEngine">

// 2. @Component("superEngine") // 이름 생략 가능

@Component
class SuperEngine extends Engine {}

@Value와 @PropertySource

@Value("#{systemProperties['user.timezone']}")
// 시스템 속성 / 환경 변수 가져올 때!
...
Properties prop = System.getProperties();

@Value("${autosaveDir}")




7. 스프링 애너테이션 vs 표준 애너테이션

1) @Autowired = @Inject
2) @Qualifier = @Resource (annotations-api.jar 가 필요함!)
3) @Scope("singleton") : 표준에서는 prototype이 디폴트
4) @Component
※ annotations-api.jar : @Qualifier, @PreDestroy, @Singleton

8. 빈 초기화 <property>와 setter

  • <property>를 이용한 빈 초기화 (setter 이용)
  • <constructor-arg>를 이용한 빈 초기화 (생성자 이용)
  • <list>, <set>, <map>
profile
Front-End Developer

0개의 댓글