Spring) @Autowired

DONG HEON·2021년 10월 26일

Spring

목록 보기
3/7

@Autowired

기존에는 setter와 생성자를 통해서 Inversion of Control로 의존성을 주입하는데 Autowired 어노테이션을 이용해서 의존성을 주입할 수 있다.

Autowired 란?

필요한 의존 객체의 "타입"에 해당하는 빈을 찾아 주입한다.

  1. 생성자
  2. setter
  3. 필드

3가지의 경우에 Autowired를 사용할 수 있다. 그리고 Autowired는 기본값이 true이기 때문에 의존성 주입을 할 대상을 찾지 못한다면 애플리케이션 구동에 실패한다. 다음과 같이 Autowired를 사용할 때의 경우의 수가 존재한다.

사용 방식

Constructor Dependency Injection

생성자 주입은 생성자에 의존성 주입을 받고자 하는 field를 나영하는 방법으로, 권고되는 방법의 하나이다.

  • 장점
    • 필수적으로 사용해야하는 레퍼런스 업이는 인스턴스를 만들지 못하도록 강제한다.
    • Spring 4.3 이상부터는 생성자가 하나인 경우 @Autowired를 사용하지 않아도 된다.
    • 순환 참조 의존성을 알 수 있다.
    • 생성자에 점차 많은 의존성이 추가될 경우 리팩토링 시점을 감지할 수 있다.
    • 테스트 코드 작성 시 생성자를 통해 의존성 주입이 용이하다.
  • 단점
    • 어쩔 수 없는 순환 참조는 생성자 주입으로 해결하기 어려움
      -> 이러한 경우에는 나머지 주입 방법 중에 하나를 사용
      -> 가급적이면 순환 참조가 발생하지 않도록 하는 것이 중요

Field Dependecy Injection

member field에 @Autowired 어노테이션을 선언하여 주입받는 방법이다.

  • 장점
    • 간단한 선언 방식
  • 단점
    • 의존 관계가 눈에 잘 보이지않아 추상적이고, 이로 인해 의존성 관계가 과도하게 복잡해질 수 있다.
      -> 반대로 Constructor Injection과 Setter Injection은 의존성을 명확하게 커뮤니케이션 해야한다.
    • SRP / 단일 책임 원칙에 반하는 안티 패턴
    • DI Container와 강한 결합을 가져 외부 사용이 용이하지 않음
      -> 단위 테스트시 의존성 주입이 용이하지 않다.
    • 의존성 주입 대상 필드가 final 선언 불가하다.

Setter Dependency Injection

setter 메소드에 @Autowired 어노테이션을 선언하여 주입받는 방법이다.

  • 장점
    • 의존성이 선택적으로 필요한 경우에 사용된다.
    • 생성자에 모든 의존성을 기술하면 과도하게 복잡해질 수 있는 것을 선택적으로 나눠 주입할 수 있게 부담을 덜어준다.
    • 생성자 주입 방법과 Setter 주입 방법을 적절하게 상황에 맞게 분배하여 사용한다.
  • 단점
    • 의존성 주입 대상 필드가 final 선언 불가하다.

@Autowired의 편리함

@Autowired 사용 전

@Service
public class BookService {
	
    private final BookRepository bookRepository;
    
    public BookService(BookRepository bookRepository) {
    	this.bookRepository = bookRepository;
    }
    
}

BookService는 생성자로 BookRepository를 전달받고 인스턴스 변수를 할당한다.

<bean id="bookRepository" class="~.BookRepository"/>

<bean id="bookService" class="~.BookService">
	<constructor-arg name="bookRepository" ref="bookRepository"/>
</bean>

기존에는 xml 파일에 Bean을 설정해주어야 했다.

@Configuration
public class ApplicationConfig {
	@Bean
    public BookRepository bookRepository() {
    	return new BookRepository();
    }
    
    @Bean
    public BookService bookService() {
    	return new BookService(bookRepository());
    }
}

또는 위처럼 xml 설정 파일을 대신하는 java class에서 Bean 설정을 만들어주어 해결할 수도 있다.

@Autowired 사용

@Service
public class BookService {
	private BookRepository bookRepository;
    
    @Autowired
    public BookService(BookRepository bookRepository) {
    	this.bookRepository = bookRepository;
    }
}

하지만 @Autowired 어노테이션을 사용하는 경우 위와 같이 객체의 의존성을 가지는 부분에 간단히 @Autowired 어노테이션을 사용하면 쉽게 의존성을 주입을 받을 수 있게된다.

@Repository
public class BookRepository { ... }

의존성 주입 타겟이 되는 Class 역시 당연히 Bean으로 등록이 되기위한 @Repository 어노테이션이 부여되어 있다.

profile
같이 일하고 싶은 사람이 되자😁

0개의 댓글