📌Autowired 확실히 알고 사용하기
Spring으로 개발을 하면서 수도 없이 작성하는 어노테이션 중 하나인 @Autowired이 있다. 사실 정확한 동작 원리를 알고 쓴다기보단 습관처럼 선언하고 사용했기에 이번 포스팅을 통해 정확히 정리하고 넘어가려고 한다. 우선 Spring Framework의 큰 특징인 DI(Dependency Injection)에 대해 간단하게 알아보자.
📌DI(Dependency Injection)
DI(Dependency Injection)은 다른 Framework에서는 볼 수 없는 Spring에서 제공하는 의존 관계 주입 기능을 말한다. 즉, 필요할 때마다 객체를 생성해서 사용하는 것이 아닌 미리 생성 후 필요한 부분에 주입하여 사용할 수 있다. 이러한 기능을 사용하면 결과적으로 객체 간의 결합을 낮추고, 유지보수의 용이함을 가져온다. 이제 이러한 개념을 바탕으로 @Autowired를 자세히 알아보자.
📌@Autowired
@Autowired
private TestDAO testDAO;
Spring Framework를 기반으로 생성된 프로젝트를 보면 위와 같은 형식으로 @Autowired가 사용된다. 도대체 @Autowired 어노테이션은 무슨 용도로 사용하는 것일까? 이 질문에 대한 답을 DI(Dependency Injection)과 연관 지어 생각해 보자.
Spring Framework에서의 DI(Dependency Injection)은 객체 내에서 또 다른 객체가 필요로 할 때 사용을 해야 되고 직접 Bean을 등록하는 등 직접 주입을 해주어야 했습니다. 이러한 방법을 간결하게 해 주기 위해 @Autowired 어노테이션이 등장하였습니다. 즉, @Autowired는 Spring Container에 등록된 Bean 중 타입이 일치하는 객체를 어노테이션 한 번으로 주입시켜 주는 어노테이션이다. 이러한 주입은 세 가지의 방법으로 사용할 수 있다.
💉필드 주입 - (Field Injection)
@Autowired를 필드 내에 직접 주입
public class TestController {
@Autowired
private TestService testService;
}
하지만, 이 방식은 실제 개발에서 몇 가지 이유로 권장되지 않는 방법이다. 그 이유는 다음과 같다. 첫 번째로 필드 주입을 하게 되면 외부에서 접근이 불가능하다. 따라서 테스트 시 객체의 수정이 불가능하기 때문에 사용을 지양한다. 두 번째로 순환 참조를 하게 되는 문제가 발생한다. 코드를 예로 들자
//A클래스 - B클래스 주입
public class A {
@Autowiredd
private B b;
public void Amethod() {
B.Bmethod();
}
}
//B클래스 - A클래스 주입
public class B {
@Autowiredd
private A a;
public void Bmethod() {
A.Amethod();
}
}
//테스트
public class test {
@Autowired
private A a;
@Autowired
private B b;
public void tetsMethod() {
A.Amethod();
B.Bmethod();
}
}
위의 코드에서 클래스 A와 클래스 B는 서로를 주입받았다. 이러한 상황에서 Test 클래스의 testMethod()가 실행을 하게 되면 서로를 계속 참조하여 서버가 다운되는 상황이 발생합니다. 이러한 이유로 필드 주입을 지양하게 되었습니다.
💉수정자 주입 - (Setter Injection)
수정자를 통해 의존성을 주입 - 수정 가능성이 있는 의존관계에 사용
private TestDAO testDAO;
@Autowired
public void setTestDao(TestDAO testDAO) {
this.testDAO = testDAO;
}
사실 이 수정자 주입 방식도 문제가 있다. Setter 자체가 public 메서드이기 때문에 주입받는 객체의 변경이 될 수 있기 때문이다. 따라서 Spring에서는 이다음에 나올 생성자 주입(Constructor Injection)의 사용을 강력하게 권장한다.
💉생성자 주입 - (Constructor Injection)
생성자 주입의 특징은 필수적인 의존관계에 사용된다.
@RestController
public class TestController {
private TestService testService;
@Autowired
public TestController(TestService testService) {
this.testService = testService;
}
}
생성자 주입 외에 필드 주입이나 수정자 주입에서는 여러 가지 문제가 생겼습니다. 또한 인텔리제이와 같은 특정 툴에서는 필드 주입 시 경고 메시지를 띄워줍니다. 생성자 주입(Constructor Injection)을 하게 되면 다른 주입방식의 단점들을 보완할 수 있고 final 키워드를 사용함으로써 잘못 주입되는 경우도 예방 가능합니다. 무엇보다 테스트 코드를 작성하는데 용이합니다. 따라서 이러한 이유들로 인해 생성자 주입 방식은 Spring에서 가장 권장하는 방식입니다.
'WEB > Spring' 카테고리의 다른 글
[Spring]Getter 그리고 Setter 생성하고 사용하기 (2) | 2023.05.16 |
---|---|
[Spring]스프링 배치(Batch)란? (8) | 2023.02.20 |
[Spring]DTO와 VO의 모호한 사용, 확실하게 사용하기 (7) | 2023.01.30 |
[Spring]@Controller VS @RestController (4) | 2023.01.30 |
[Spring]@RequestBody와 @RequestParam 비교하여 이해하기 (7) | 2023.01.27 |