[Spring] @Autowired과 의존관계 주입

김재연·2023년 4월 30일

수숙관

목록 보기
13/17
post-thumbnail

스프링 프로젝트를 하고 있는 중에도 아직도 뭔지 잘 모르겠고 썼다가 안썼다가 내맘대로 막 쓰고 있는 @Autowired라는 놈에 대해 파헤쳐보려고 한다.

IoC 컨테이너

  • IoC (Inversion of Control, 제어 반전) : 객체의 생성, 생명주기의 관리 등 모든 객체에 대한 제어권이 바뀌었다는 뜻
  • IoC 컨테이너 = 스프링 컨테이너
  • 스프링 프레임워크에서는 인스턴스 생성부터 소멸까지의 생명주기 관리를 개발자가 아닌 컨테이너가 대신 해준다.
  • 스프링 컨테이너 안에서 관리하는 자바 객체를 빈(Bean)이라고 한다.
    - 빈(Bean)은 @Component나 @Bean 어노테이션을 붙여서 등록할 수 있다.

DI (Dependency Injection, 의존관계주입)

클래스 사이의 의존관계를 빈 설정 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것을 말한다.

💡여기서 잠깐!
객체 A가 객체 B의 변화에 영향을 받으면 A는 B에 의존한다고 말한다.
A와 B가 상호작용을 하면 A와 B는 의존관계에 있다고 말하는데, 이때 사용할 객체에 대한 레퍼런스를 외부에서 제공해줘야 한다.
이것을 바로 '의존성주입', 즉 DI라고 한다.

>> 의존성을 주입할 때는 @Autowired라는 어노테이션을 사용한다.

@Autowired

  • 스프링 컨테이너에 등록한 빈에 의존관계 주입이 필요할때, DI를 도와주는 어노테이션
    >> 의존성을 주입하려는 클래스와 주입의 타겟이 되는 클래스 모두 빈으로 등록되어 있어야 한다.
  • 의존성을 가지는 부분에 @Autowired를 붙이면 의존성 주입이 완료된다.
  • @Autowired는 생성자, 수정자, 필드에 붙여서 사용할 수 있다.


1. Constructor Injection : 생성자 주입 (⭐)

  • 생성자를 통해 의존관계를 주입한다.
  • 의존관계에 있는 객체들을 final로 선언할 수 있다.
  • 생성자가 하나일 경우 @Autowired를 생략할 수 있다.
  • 의존해야하는 객체를 private final로 선언하고, 생성자를 통해 해당 객체들을 주입받고, 생성자 위에 @Autowired를 붙인다.
  • 대부분의 의존관계는 어플리케이션 종료때까지 불변하기 때문에 가장 권장되는 방법이다.
@Component
public class MyService {
	private final MyRepository myRepository;
	private final ExampleBean exampleBean;
    
	@Autowired
	public MyService(MyRepository myRepository, ExampleBean exampleBean) {
            this.memberRepository = memberRepository;
            this.exampleBean = exampleBean;
	}
}

2. Setter Injection : 수정자 주입 (❔)

  • 수정자를 통해 의존관계를 주입한다.
  • 의존해야하는 객체를 private으로 선언한다.
  • 해당 변수에 대한 setter 메소드를 생성하고, 해당 setter에 @Autowired를 붙인다.
  • 스프링 빈을 모두 등록한 후에 @Autowired가 붙은 수정자를 모두 찾아서 의존관계를 주입한다.
@Component
public class MyService {
	private MyRepository myRepository;
	private ExampleBean exampleBean;
    
	@Autowired
	public void setMyRepository(MyRepository myRepository) {
	    this.myRepository = myRepository;
	}
    
	@Autowired
	public void setExampleBean(ExampleBean exampleBean) {
	    this.exampleBean = exampleBean;
	}
}

3. Field Injection : 필드 주입 (❌)

  • 의존해야 하는 객체를 가리키는 변수에 @Autowired를 붙인다.
  • 가장 간단하지만 가장 비추천되는 방법이다.
@Component
public class MyService {
	@Autowired
	private MyRepository myRepository;
    
	@Autowired
	private ExampleBean exampleBean;
}

그동안 싸지른 코드들,, 💩

1) 생성자 어노테이션 1개 + Autowired 생략

2) 생성자 1개 직접 작성 + Autowired 생략

3) 생성자 없이 필드 주입


Reference

[Spring] IoC 컨테이너 (Inversion of Control) 란?
[Spring] @Autowired를 통한 의존 관계 주입

profile
일기장같은 공부기록📝

0개의 댓글