1. IoC와 프레임워크, 라이브러리
IoC란?
Inversion of Control의 약자로 제어에 관해 역전이 일어났다는 것을 의미한다. 그러면 여기서 Control은 무엇을 제어하는 것을 의미할까?
우리는 개발자니까, 프로그래밍적으로 생각해보면 당연히 코드, 프로그램에 관한 제어이다. 개발자는 자신이 작성한 코드에 대해 자신이 원하는대로 흘러가길 바란다. 이렇게 작성해서 이러한 흐름으로 코드가, 프로그램이 진행되어야지~ 하는 개발자의 흐름대로 코드가 작성되고 흘러가는 것이 일반적이고 이러한 경우를 프로그래머가 제어권을 가지고 있다고 한다. 이러한 제어의 흐름을 조금 더 세분화해서, 객체지향 프로그래밍에서 '제어'란, 객체들간의 의존성을 연결하고 객체의 생성을 담당하는 것을 의미한다. 즉, 지금까지 의존성 주입과 객체의 생성은 개발자의 영역이었다.
그렇다면, 제어권이 역전된 IoC는 무슨 말인가? 프로그래머말고 코드흐름의 제어권을 가질 다른 존재가 있다는 말이다. 누가 그 제어권을 가져갔는가?하면 이어서 설명할 프레임워크의 IoC 컨테이너가 코드, 프로그램의 흐름을 제어 즉, 객체를 생성하고, 객체간의 의존성을 주입하는 것을 IoC라고 한다.
프레임워크란?
프레임워크란, 공통적으로 사용될 수 있는 특정기능을 모듈화한 것을 의미한다. 이에 그치지 않고 이를 폴더,파일명과 같은 부분에 관한 규칙이 존재하고 프레임워크 자체적인 Life Cycle이 존재한다. 또한, 프로그램 흐름의 제어를 개발자가 아닌 프레임워크가 갖는다.
예를 들자면, Java의 테스트 프레임워크 JUnit5를 보자. Test class의 여러 테스트를 실행할때, 각 테스트 코드의 실행 순서는 위에서부터 실행되지 않고 프레임워크 자체적인 제어에 통해 실행된다.
라이브러리란?
라이브러리란, 역시 공통적으로 사용될 수 있는 특정한 기능들을 모듈화한 것을 의미한다. 그러나, 프레임워크와 다르게 규칙이 존재하지 않고 흐름 제어권한 역시 프로그래머가 갖는다. 단지, 자주쓰고 공통적으로 쓰이는 코드들을 미리 작성해 놓은 것을 불러다 쓰는 것이다.
2. 생성자를 통한 의존성 주입과 @Autowired 비교
앞서, @Autowired 어노테이션을 사용한 의존관계 주입방법으로 3가지가 있음을 이야기하였다. 생성자 주입, 수정자 주입, 필드 주입을 언급했고 이 중 생성자 주입을 사용하는 방법이 권고된다고 언급했다.
여기서, @Autowired를 사용하지 않고 즉, 스프링을 사용하지 않고 생성자를 통해 의존관계를 주입하는 방법이 있다.
생성자를 통한 의존성 주입
생성자를 통한 의존성 주입은 클래스를 객체로 생성할때, 생성자 코드를 한줄한줄 작동하며, 필요한 타 객체가 존재하면 해당 객체를 다시 생성하는 방식으로 의존성을 주입하는 것을 의미한다.
Car 객체를 생성할때 필요한 부품인 타이어가 존재할 것이다. 따라서 Car를 생성하기 위해선 Tire를 정해줘야한다. 다음과 같이 말이다.
Car car = new Car(KoreaTire);
이렇게 Car 객체를 생성할때 필요한 객체를 찾아 의존관계를 주입하는 방법이 있었다.
@Autowired를 사용하는 의존성 주입
스프링에선, @Autowired라는 어노테이션을 사용해 의존성 주입을 받는데, 이는 말 그대로 '자동'으로 의존관계를 주입하는 것을 의미한다. 스프링에 등록된 Bean중에서 해당 빈을 찾고, 두 객체 사이의 의존성을 주입한다.
3. AOP
AOP란?
Aspect Oriented Programming의 약자로 관점지향형 프로그래밍을 의미한다. 우리가 프로그램을 작성할때 필요한 로직이 있는데 이 로직은 핵심적인 로직과 부가적인 로직으로 구분된다. 핵심적인 로직이란 우리가 작성하려하는 핵심 비즈니스 로직을 의미한다. 가령, 상품을 주문하는 서비스를 만들고 싶으면 핵심로직은 상품주문에 관한 부분이다. 반대로, 부가적인 로직은 핵심적인 로직 외적의 것들을 의미한다. DB연결, 파일 입출력, 로깅등이 이 예이다.
부가적인 로직에 집중해 핵심적인 로직이 영향을 받으면 안되기에 이렇게 흩어진 관점을 핵심으로부터 분리하여 재사용하는 것이 AOP이다.