어노테이션은 스프링이 제공하는 최고의 편의성 중 하나이다. @~ArgsConstructer 로 간단한 생성자의 구현과 의존성 주입, 또 @Entitiy, @Controller 등 여러 어노테이션들을 편하게 사용해왔다. 오늘 쓸 글은 이 어노테이션을 쓰면서 헷갈렸던 부분, 혹은 앞으로 까먹거나 헷갈릴 듯한 친구들을 한번에 정리해봤다.
구성 영역과 사용 영역을 나누기 위함. 즉 추상화를 위해 사용하며, IoC를 위해 사용한다.
👉 IoC(Inversion of Control : 제어의 역전)
- 애플리케이션의 전체 동작 방식을 구성하기 위해 구현 객체를 생성, 연결하는 별도의 설정 클래스인
AppConfig
가 있다고 하자.
- 위 그림과 같이
OrderServiceImpl
은 필요한 인터페이스(DiscountPolicy
)들을AppConfig
로 부터 호출하지만 어떻게 생성 될지는 알 수 없다.
메소드가 실행 됬을때 제어흐름도AppConfig
가 들고 있던걸 실행하는것이기 때문에 프로그램의 제어 흐름에 대한 모든 권한도AppConfig
가 가지고 있다.
다쓰면 객체도 반납한다.- 이 처럼 프로그램의 제어 흐름을
OrderServiceImpl
이 직접 제어하는 것이 아닌AppConfig
와 같이 외부에서 관리하는 것을 IoC(제어의 역전)이라고 한다.
✋잠깐! 용어정리! 그래서 🗃️ 컨테이너 가 뭐야?
Appconfig
와 같이 객체를 생성하고 관리하면서 의존 관계를 연결해 주는 것을 IoC 컨테이너 또는 DI 컨테이너라 한다.🙂 일반적인 제어흐름: 사용자가 자신이 필요한 객체를 생성해서 사용
🙃 역전된 제어흐름 : 사용자가 자신이 필요한 객체(또는 사용할 객체)에 @
으로 표시하면 컨테이너에서 꺼내서 넣어주니까 바로 사용하면됨
(사실 알아야 되긴 하지만, 사용할 객체의 수정내용을 일일이 반영하는 리소스를 아낄 수 있다는 의미)
// 기존 객체 생성
private Object object = new Object();
// 객체 주입 받기 (아래 방법 말고도 많음)
@Autowired
private Object object;
@RequiredArgsConstructor
…@Autowired
…스프링은 자주 쓰는 객체를 Bean으로 만들어 관리한다. 이 Bean을 한번 생성하고 나면, 다시 DB에서 Bean 생성, 조회등을 할 필요가 없기 때문에 메모리의 효율적 사용이 가능하기 때문이다.
그런데, Bean과 Component는 둘 다 Bean으로 만들겠다는 어노테이션이다. 이 둘은 어떤 차이가 있을까?
@Bean은 외부 라이브러리들을 Bean으로 등록하기 위해서 사용하는 어노테이션이다. 이 객체들은 라이브러리로써 이미 설정되어 있기 때문에, Setter 나 Builder를 사용해서 프로퍼티를 변경한 후 그 모양에 맞게 Bean으로써 사용된다.
@Component는 사용자가 직접 만든 클래스를 Bean으로 만들어 사용하는 것을 의미한다.
@**Override
)****@Target
)****@Test
)**Bean은 외부 라이브러리를 Bean으로 만들어 관리할 때, Component는 개발자가 직접 작성하는 코드를 Bean으로 만들어 사용할 때 사용한다.
클래스, 메서드, 변수가 포함된 프로그램 코드 자체에는 아무런 영향을 미치지 않으면서 중복코드를 줄이고 싶을 때 어노테이션을 사용한다.
더하여, IoC, DI를 사용하는 이유와 비슷하다. 이미 built-in 된 기능에 대해서 우리가 손 댈 필요 없이 기능만 사용한다.(추상화)