안녕하세요👋 공부할 내용들이 많아 예상보다 빠르게 글을 포스팅하게 되었습니다. 제가 웹개발을 찍먹하면서 느낀건… 여태까지 했었던 거처럼 무지성 개발을 하면 안된다는 거였습니다.. 이해가 선행되지 않으면 개발은 무슨ㅋ GPT한테 어떻게 물어봐야 할 지도 모르겠더라구요ㅎㅎ!
그래서 개념 위주로 공부하고 개발하면서 마주치는 에러들에 대해 서술해보도록 하겠습니다😉
스프링을 쓰다보면은 ‘의존성’이라던지 ‘IoC’..’AOP’ 라는 단어를 엄청 자주 마주치게 됩니다😧 의존성 주입은 Spring과 떼 놓을 수 없는 관계임으로 한 번 정리해보기로 했습니다.
디자인 패턴 중 하나로, 클래스나 모듈 간의 의존성을 외부에서 주입하도록 하는 것
개념만 봐서는 이해가 어려울 수 있으니 코드로 한 번 보겠습니다.
public class KimbapService{
private final BasicKimbapPersistence kimbap;
public KimbapService(){
this.kimbap = new BasicKimbapPersistence()
}
public void create(...){
...
kimbap.create(...);
}
}
KimbapService 클래스 - 김밥을 레시피 클래스
BasicKimbapPersistence 클래스 - 기본 김밥을 제공하는 클래스
여기서 KimbapService는 BasicKimbapPersistence 없이는 제 기능을 못합니다. 이때! KimbapService가 BasicKimbapPersistence에 ‘의존’한다고 말할 수 있습니다. 추가로 KimbapService가 BasicKimbapPersistence 오브젝트를 생성하고 관리하고 있음을 확인할 수 있습니다.
근데, 여기서 문제가 있습니다.
어느 날 갑자기 본사에게서 메세지가 옵니다. 김밥 레시피의 BasicKimbap을 단종시키고 TunaKimbap으로 바꾸라는 메세지가요😦 근데 성실한 요리연구가인 저는 이미 BasicKimbap 레시피와 어울리는 세트메뉴 조합을 100개나 만든 상태였습니다, 그럼 전 기본 김밥과 조합한 100개의 조합들을 하나하나 다 고치러 다녀야할까요?
네…
벌써 아찔하죠? 그래서 존재하는 것이 ‘의존성 주입(DI, Dependency Injection)’ 입니다. 이 클래스가 의존하는 다른 클래스들을 외부에서 주입시키는거죠. DI의 방법에는 생성자 주입과 Setter 주입 그리고 필드 주입이 있습니다. 저희는 이 중 많이 사용하고 있는 생성자 주입방식과 Setter 주입 방식에 대해서 알아보겠습니다.
public class KimbapService{
private final IBasicKimbapPersistence kimbap; //인터페이스
public KimbapService(IBasicKimbapPersistence kimbap){
this.kimbap = kimbap;
}
public void create(...){
...
kimbap.create(...);
}
}
public static void main(String[] args){
IBasicKimbapPersistence kimbap = new BasicKimbapPersistence();
KimbapService service = new KimbapService(kimbap);
}
이렇게 KimbapService를 생성할 때, 인터페이스인 IBasicKimbapPersistence의 구현부를 넘겨줌으로써 의존성을 주입시키면 훨씬 수정이 빠르겠죠?
그리고 이 생성자 주입방식이 가장 권장되는 주입 방식입니다.
public class KimbapService{
private final IBasicKimbapPersistence kimbap; //인터페이스
public void setIBasicKimbapPersistence(IBasicKimbapPersistence kimbap){
this.kimbap = kimbap;
}
}
public static void main(String[] args){
IBasicKimbapPersistence kimbap = new BasicKimbapPersistence();
KimbapService service = new KimbapService();
service.setIBasicKimbapPersistence(kimbap);
}
이 방식은 오브젝트를 초기화한 후 Setter를 이용해 의존하는 오브젝트를 주입하는 방식입니다.
Spring Application에서 객체(Bean)의 생성, 의존성 관리 등의 작업을 Spring Container가 담당하는 것
IoC를 직독직해하면 ‘제어의 역전’이라는 의미입니다. 저는 맨처음에 듣고 1도 이해하지 못했었죠.
찾아보니 IoC 이전에 일반적으로 코드를 작성할 때 코드의 제어 흐름을 주로 개발자가 결정하고 제어했습니다. 즉, 개발자가 직접 객체 생성부터 의존성 설정, 메서드 호출 등 다 개발자가 명시적으로 제어했었습니다. 벌써 귀찮죠?
이때, 개발자가 다 하던 객체 생성과 관리를 외부 컨테이너(Spring Container)가 하게됨으로써 더 모듈화되고 유연한 코드를 작성하 수 있게 되었습니다.
그래서 DI와 IoC의 관계를 정의하자면,
IoC는 DI를 통해 달성된다
라고 할 수 있겠습니다.
문제를 바라보는 관점을 기준으로 프로그래밍 하는 방법론
프로그램에서는 로깅, 트랜잭션, 보안, 캐싱과 같이 비즈니스 로직과는 개념적으로 분리되어 있으면서 한 애플리케이션의 여러 부분에 걸쳐 있는 기능이 있습니다.(이를 횡단관심사(cross-cutting-concerns)라고 함)
이 기능들을 ‘관심사’라고 부르며, 각 관점을 모듈화하여 코드의 중복을 줄일 수 있습니다.
AOP에서의 관점을 What/When/Where로 나누는데, 이 관점에 따른 용어가 있습니다.
사실은 이번 포스팅에 container와 context에 대해서도 다루려고 했으나, 내용이 너무 많아질 거 같아 이정도만 하겠습니다🥲
부족한 글 읽어주셔서 감사합니다😸
화이팅 입니다