-
Spring Framework 6.2 문서 읽고 이해하기 ... IOC Container (1)개발하면서/타인글보면서 2025. 2. 9. 16:00반응형
현재 정산 백엔드 직군으로 일하고 있고 사용하는 기술은 Spring Boot와 Kotlin이다.
(사람마다 깊이에 대한 기준은 다르지만) Spring을 깊은 이해 없이 활용 가능한 정도로 공부한 후
사용하다가 문제 생기면 그때 필요한 부분만 알아가는 식이였다.
IOC Container라는 게 있어서 POJO + Meta정보를 이용해서 Bean을 생성하고 lifecycle도 관리해 주고,
Reflection을 이용해서 DI 해준다 정도... 아는 것도 모르는 것도 아닌 두리뭉실한 느낌이를 반대로 말하면 문제없는 영역은 잘 모른다는 게 문제다.
Spring Boot가 알아서 해주는 게 많아 개발자는 비즈니스 로직에만 집중한다는 장점이 있지만
프로젝트가 커지다 보면 비즈니스 로직만 알아서는 부족함을 느낀다. 개발 속도가 느려진다.지금 상황이 그렇다.
코드를 봐야겠다고 결심하게 된 결정적인 계기는
지금 프로젝트를 리팩토링 하려고 테스트 코드 작성하는데 감으로만 알고 있던 걸로는 진행이 안 됐다.더 이상 구글 검색결과에 나온 방법들로는 해결되지 않았다.
내가 생각한 개발자의 가장 큰 장점은 공개되어 있는 코드들이 많아
시간과 노력을 투자한다면 내부 동작 원리를 알 수 있다는 점이다.
그래서 당장 업무에 도움 될지를 상상하며 내부 동작을 알아보려고 한다.
첫 시작은
Spring framework 6.2!!
나의 지적호기심 채우려고 너무 깊게 알아가는 모습을 항상 경계하자.
Core Technologies / The IoC Container
IOC는 Inversion of Control의 약자로 제어를 내부가 아닌 외부에서 한다는 개념이고
DI는 생성자, property, factory method, setter method 등을 이용하여 의존 관계에 있는 객체를 주입받는 걸 말한다.
IoC 컨테이너는 두 개 패키지가 기본이고 `org.springframeowrk.beans`, `org.springframeowrk.context`
beans 패키지는 BeanFactory interface를, context 패키지는 ApplicationContext interface를 root로 보면 된다.
BeanFactory는 모든 유형의 객체를 관리할 수 있는 메커니즘을 제공하고,
ApplicationContext는 BeanFactory의 하위 interface로 아래와 같은 추가 기능을 제공한다.- Spring AOP 기능과 쉬운 연동
- i18n 관리
- 이벤트 메시지 관리
- 웹에서 사용하기 위한 WebApplicationContext 같은 계층별 Context
BeanFactory는 프레임워크 설정과 기본 기능을 제공하고, ApplicationContext는 추가로 엔터프라이즈 기능을 제공한다.
이후 Spring IoC Container 설명 ApplicationContext으로 진행한다.
※ BeanFactory에 대한 자세한 내용은 The BeanFactory API 읽을 때 알아보겠습니다.Container Overview
Spring IoC Container = ApplicationContext interface 느낌.
bean의 인스턴스화, 설정, 조합등을 책임지는데 메타정보를 읽어 처리한다.
다양한 ApplicationContext interface 구현체가 있는데 그중에
AnnotationConfigApplicationContext, ClassPathXmlApplicationContext 가 단독으로 생성 가능하다.
비즈니스 로직이 있는 객체(POJO)와 메타정보를 가져와서 ApplicationContext에서 즉시 사용가능한 Bean 만들어준다.
Configuration Metadata
메타정보는 다양한 방식으로 정의할 수 있는데 대부분의 개발자들은 주로 Java-based configuration 방식을 사용한다.
- Annotation-based configuration: 애플리케이션 컴포넌트 클래스에 annotation을 사용해서 bean을 정의하는 방식
- Java-based configuration: 애플리케이션과 별개의 클래스에 bean을 정의하는 방식
XML 방식도 있는데 XML에 <beans/>를 적고 하위에 <bean/>을 적어서 bean을 정의한다.
※ <import /> element를 이용해서 다른 xml파일에 정의한 bean 내용을 가져올 수도 있다.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- services --> <bean id="petStore" class="com.tistory.dol9.context.support.PetStore"/> </beans>
ClassPathXmlApplicationContext 생성자 argument로 Java classpath 기준 xml을 넘겨주면 IoC container가 생성된다.
XML 경로는 상대경로 대신 절대경로 사용을 권장한다.
추가로 GenericApplicationContext와 reader delegate를 이용해서 container를 생성할 수도 있다.
// create and configure beans using ClassPathXmlApplicationContext val context: ApplicationContext = ClassPathXmlApplicationContext(SINGLE_CONTEXT) val service: PetStore = context.getBean("petStore", PetStore::class.java) // create and configure beans using GenericApplicationContext val context = GenericApplicationContext() val beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(PetStore::class.java).beanDefinition context.registerBeanDefinition("petStore", beanDefinition) context.refresh() val service: PetStore = context.getBean("petStore", PetStore::class.java) val userList = service.userName // PetStore class PetStore { val userName: List<String> get() = mutableListOf("dol9", "dol10") }
위에 작성한 XML과 코드
https://github.com/kgcrom/learn-something/commit/e95a391445213127ff9eb6e7017b7c9a833d98bc
Spring Framework 6.2 git clone 한 뒤 코드를 봤지만 이해 안 되는 게 참 많았다.
문서 Resource까지 보면서 대강 분위기 익히고 코드를 봐야겠다.
반응형