Today I Learned_220725
Spring Framework
Dependency Injection(의존관계 주입)
- 생성자 주입
- 수정자 주입(setter 주입)
- 필드 주입
- 일반 메서드 주입
생성자 주입
생성자를 통해 의존관계 주입
불변, 필수적인 의존관계에 사용한다.
생성자 호출 시점에 딱 한 번만 호출되는것이 보장된다. -> 그 때 가서 세팅하고 다음에 세팅 못하도록 막을 수 있다.
getter/setter 없이 생성자 주입만 진행한다면 한계점과 제약이 있이 설계할 수 있음.
생성자가 딱 1개만 있으면 @Autowired를 생갹해도 자동 주입이 된다.
생성자가 2개일 경우 @Autowired를 반드시 사용해야 하며, 스프링 빈에만 해당한다. (순수 자바 코드는 해당하지 않음)
빈을 등록하면서 의존관계 주입이 일어남(스프링 코드 때문이 아니라 자바 코드 때문) - 스프링 컨테이너에 빈을 등록하면서 의존관계 주입이 일어남
수정자 주입
setter 메소드를 통해 의존관계 주입
선택, 변경 가능성이 있는 의존관계에 사용한다.
스프링 빈을 컨테이너에 모두 등록한 다음, 의존관계 주입이 일어남
중간에 인스턴스를 바꿀 일이 있을 때 주로 수정자 주입을 사용한다.
자바 빈 프로퍼티 규약 : 클래스의 필드값을 직접 변경하지 않고 setter와 getter 메소드를 통해서 값을 수정하거나 읽는 규칙
의존관계 주입이 이루어지는 순서 (컨테이너 라이프사이클)
필드 주입
필드에 바로 주입
코드가 매우 간결해지나, 필드 주입을 사용하게 되면 외부에서 변경이 불가능해 테스트하기 힘들다.
DI가 없으면 아무것도 못 하므로, 순수한 자바코드를 사용하기 어려워진다.
웬만하면 쓰지 말자. 이거 쓸 바에야 setter 사용하자.
다른 곳에서 가져다 쓸 일이 없는 테스트코드에서 사용하는 정도..?
일반 메서드 주입
일반 메서드를 통해서 주입
일반적으로 생성자 주입/수정자 주입으로 해결하기 때문에 잘 사용하지 않는다.
주의점
의존관계 자동 주입은 스프링 컨테이너가 관리하는 스프링 빈이어야만 동작한다. 일반 클래스에서 @Autowired를 적용해도 안 된다.
바이트코드를 조작하는 기능을 사용하면 일반 객체에서도 @Autowired를 사용할 수 있지만, 일반적으로 의존관계 자동 주입은 스프링 컨테이너가 관리하는 빈만 가능하다고 생각하자.
Autowired 옵션 처리
자동 주입 대상을 옵션으로 처리하는 방법
- @Autowired(required=false) : 자동 주입할 대상이 없으면 수정자 메서드 자체가 호출되지 않음(기본값은 true)
- @Nullable : 파라미터에 사용. 자동 주입할 대상이 없으면 null이 입력됨
- Optional<> : Java 8 이상. 자동 주입 대상이 없으면 Optional.empty가 입력된다.