공부하는 스누피
[Spring] Dependency Injection (DI) 본문
1. 의존 주입 Dependency Injection
한 클래스가 다른 클래스의 메소드를 실행할 때 이를 '의존'한다고 표현한다. 의존 관계는 변경에 의해 영향을 받는 관계로, B 클래스가 A 클래스의 메소드를 실행할 때 A 클래스에 변경이 이루어지면 B 클래스에 영향이 가게 된다. 여기서 B 클래스의 메소드를 실행하는 C 클래스가 있다면, 이 변경은 C 클래스까지 전파된다.
의존 관계를 구현하기 가장 쉬운 방법은 B 클래스에서 A 클래스 객체를 직접 생성하는 방법이다. DI(Dependency Injection)는 의존하는 객체를 직접 생성하지 않고 의존 객체를 전달받는 방식을 사용한다.
즉, DI란 의존하는 객체를 전달받아서 사용하는 패턴이다. DI는 의존 객체 변경이 유연하다는 것이 큰 장점인데, 의존 주입 대상이 되는 클래스만 수정하면 의존하는 다른 클래스들은 코드를 수정할 필요가 없다.
2. 이해를 위한 설명
public class A{
public void printA(){
System.out.println("A");
}
}
A에 의존하는 B 클래스의 객체를 생성할 때는 생성자에 A 객체를 전달(주입)해야 한다.
public class B{
private A a;
public B(A a){
this.a = a;
}
}
객체 생성은 다음과 같이 이루어진다.
//객체 생성
A a = new A();
B b = new B(a);
생성자가 아니더라도 Setter 메소드를 활용해 의존 객체를 주입할 수 있다. 위 코드처럼 객체를 생성하면서 의존 관계를 만들어주어야 하는데, 이러한 역할을 하는 조립기(Assembler)가 필요하다. Spring은 DI를 지원하는 조립기 기능을 제공하기 때문에 DI와 조립기는 Spring의 기본 개념으로 꼭 알고 넘어가야 한다.
3. DI 구현을 위한 개념
- 스프링 컨테이너 ApplicationContext
스프링 컨테이너는 객체를 생성하고 의존 객체를 주입한다. 컨테이너를 사용하려면 @Configuration이 붙은 스프링 설정 클래스를 이용해서 컨테이너를 생성해야 한다.
* @Configuration
Configuration 어노테이션은 스프링 설정 클래스를 의미한다.
* @Bean
Bean 어노테이션은 해당 메소드가 생성한 객체를 스프링의 빈(Bean)이라고 설정한다. @Bean이 붙은 메소드마다 한 개의 객체를 생성한다. 이때, 메소드 이름을 빈 객체의 이름으로 사용해야 한다. 스프링 컨테이너가 생성한 Bean은 싱글톤 객체로, 한 메소드당 한 개의 객체만 생성한다.
=> 싱글톤은 스프링이 설정 클래스를 그대로 사용하지 않기 때문에 가능하다.
=> 스프링은 설정 클래스를 그대로 사용하지 않고 런타임에 기존 설정 클래스를 상속받은 새로운 설정 클래스를 만들어서 사용한다.
=> 객체를 Bean으로 설정해 두지 않으면 스프링 컨테이너는 객체를 관리하지 않는다.
- 구현 방식
a. 생성자 방식
: 생성자를 이용해 객체가 생성될 때 의존 객체를 주입.
+ 빈 객체를 생성할 때 모든 의존 객체가 주입됨.
- 생성자 파라미터 수가 많을 경우 주입되는 객체를 알아내기 어려움.
b. 설정 메소드 방식(Setter)
: 객체 property를 정의하는 세터 메소드를 이용해서 객체를 주입.
=> 자바빈 규칙: 메소드 이름이 set으로 시작하며, 파라미터가 1개인 void 타입 메소드여야 함.
+ 메소드 이름을 통해 어떤 의존 객체가 주입되는지 알 수 있다.
- 의존 주입이 되어있지 않은 상태에서도 객체 생성이 되기 때문에 NullPointerException이 발생할 수 있음.
- 자동 주입
@Autowired 어노테이션은 스프링의 자동 주입 기능을 위한 것이다. 스프링 설정 클래스의 필드에 @Autowired를 붙이면 해당 타입의 Bean을 찾아서 필드에 할당한다. 다른 설정 파일에 정의한 빈을 필드에 할당할 수 있게 한다. @Autowired를 의존 주입 대상에 붙이면 자동으로 의존 주입이 되기 때문에 스프링 설정 클래스의 @Bean 메소드에서 의존 주입을 따로 안해줘도 된다.
+ @Import
두 개 이상의 설정 파일을 사용할 때, @Import 어노테이션을 사용해 함께 사용할 설정 클래스를 지정한다. 이렇게 하면 스프링 컨테이너에서 여러 개의 설정 클래스를 지정할 필요가 없다.
ex) @Import({설정1.class, 설정2.class}) => 여러 개의 설정 클래스를 배열을 사용해서 한번에 지정할 수 잇다.
'Web > Spring' 카테고리의 다른 글
[Spring] 메시지 정리 (0) | 2020.08.28 |
---|---|
[Spring] MVC 기본 정리 (0) | 2020.08.19 |
[AWS, Spring] Spring 프로젝트 Beanstalk에 올리기 (0) | 2020.08.11 |
[Spring] AOP 정리 (0) | 2020.08.10 |
[Spring] 자동 의존 주입을 위한 어노테이션들 (0) | 2020.08.07 |