
1️⃣ Spring Container (스프링 컨테이너)
Spring 에서 'ApplicationContext' 는 '스프링 컨테이너' 라고 한다.
이는 DI, IoC 와도 관련이 있는데, 스프링 컨테이너를 통해 DI가 자동으로 되기 때문이다.
스프링 컨테이너가 동작하는 원리를 간단하게 설명하면 다음과 같다.
- @Configuration 이 붙은 클래스를 설정 정보로 사용한다.
- 위 클래스에서 작성된 모든 메소드를 모두 호출하여 반환된 객체를 스프링 컨테이너에 등록한다.
- 스프링 컨테이너에 등록된 객체를 '스프링 빈' 이라고 하며, @Bean 이 붙은 메소드명을 이름으로 사용한다.
- 스프링 컨테이너에서 필요한 스프링 빈을 찾아서 사용한다.
@Configuration
public class AppConfig(){
@Bean
public MemberRepository memberRepository(){
return new MemoryMemberRepository();
}
@Bean
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
}
public class BeanTest(){
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberRepository memberRepository = ac.getBean("memberRepository",MemberRepository.class);
}
위 코드를 예시로 들어보자.
1. 스프링 컨테이너 생성
우선 AppConfig 클래스에 @Configuration 어노테이션이 붙음으로써 설정 정보로 사용하겠다는 표시를 한다.
이는 이후 싱글톤 객체를 만드는 것을 보장해주는데, 이후에 자세히 다뤄보겠다.
AppConfig 내부엔 'memberRepository' 와 'memberService' 메소드가 있다.
모두 @Bean 이라는 어노테이션이 달려있는데, 이것이 스프링 빈으로 등록하겠다는 의미이다.
(스프링 빈의 이름은 첫 글자가 소문자인 메소드명으로 설정되나 사용자가 직접 변경할 수 있다.)
아래 BeanTest 클래스를 보자.
ApplicationContext 는 스프링 컨테이너라고 하였다.
사실 이는 인터페이스이며, 구현체로 'AnnotationConfigApplicationContext' 가 있다.
new 연산자를 통해 스프링 컨테이너를 생성하고, 설정 정보로 'AppConfig.class' 를 넣어준다.
(구성 정보를 꼭 지정해주어야 한다.)
2. 스프링 빈 등록
AppConfig.class 에서 넘어온 @Bean 어노테이션을 보고 스프링 빈을 등록한다.
즉, 메소드 명(사용자 지정)인 빈 이름과 return 값으로 받은 빈 객체를 스프링 빈 저장소에 저장한다.
여기서 주의할 점은 스프링 빈 이름은 모두 다른 이름이어야 한다. 그렇지 않으면 오류가 발생할 수 있다.
Spring Container | |
Bean Name | Bean Object |
memberRepository | MemoryMemberRepository@x01 |
memberService | memberServiceImpl@x02 |
3. 의존 관계 설정
AppConfig 에서 설정한 정보를 통해 DI 된다.
@Configuration
public class AppConfig(){
@Bean
public MemberRepository memberRepository(){
return new MemoryMemberRepository();
}
@Bean
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
}
위 코드에선 'memberService' 가 'memberRepository' 를 의존한다는 것을 알려준다.
실제로는 new 연산자를 통해 객체를 생성할 때, 스프링 빈으로 등록됨과 동시에 의존 관계 설정까지 마친다.
이 경우는 생성자 주입을 통해 의존 관계를 설정하는 방법인데, Setter 주입, 필드 주입 등 여러 방법이 있다.
2️⃣ BeanFactory
사실 스프링 컨테이너는 다양한 형식의 설정 정보를 받아들일 수 있게 설계되어있다.
이번에 다룬 내용은 Java 코드를 활용한 것이고, 이외에도 XML 이나 Groovy 등으로도 가능하다.
ApplicationContext 는 스프링 컨테이너를 나타내는 인터페이스라고 하였다.
그러나 이보다 더 상위에 존재하는 인터페이스가 있는데, 바로 'BeanFactory' 이다.
즉, 상속 관계가 (상위←하위) 라면
<Interface>BeanFactory ← <Interface>ApplicationContext ← AnnotationConfigApplicationContext
이다.
BeanFactory 는 스프링 컨테이너의 최상위 인터페이스로, 스프링 빈을 관리하고 조회하는 역할을 담당한다.
ApplicationContext 는 BeanFactory 의 모든 기능을 상속받아 제공한다. 그러나 실제로 개발을 할 때 수많은 부가 기능이 필요하기 때문에, 빈 관리 기능과 편리한 부가 기능을 제공한다. 사실상 ApplicationContext 를 많이 사용한다.
3️⃣ BeanDefinition
스프링은 BeanDefinition 을 통해 Java, XML, Groovy 등의 다양한 설정 형식을 지원한다.
이는 빈 설정 메타 정보이며, @Bean (Java), <Bean> (XML) 당 각각 메타 정보가 생성된다.
즉, 다양한 형식의 설정 정보에서 생성된 메타 정보를 기반으로 스프링 빈을 생성하는 것이다.
실제로 BeanDefinition 을 직접 정의하거나 사용할 일은 거의 없다고 한다.
단지 BeanDefinition 의 추상화를 통해 다양한 형태의 설정 정보를 바탕으로 스프링 빈을 등록한다는 것만 알아두자.
참고 : 김영한-스프링 핵심 원리 (기본편), google

1️⃣ Spring Container (스프링 컨테이너)
Spring 에서 'ApplicationContext' 는 '스프링 컨테이너' 라고 한다.
이는 DI, IoC 와도 관련이 있는데, 스프링 컨테이너를 통해 DI가 자동으로 되기 때문이다.
스프링 컨테이너가 동작하는 원리를 간단하게 설명하면 다음과 같다.
- @Configuration 이 붙은 클래스를 설정 정보로 사용한다.
- 위 클래스에서 작성된 모든 메소드를 모두 호출하여 반환된 객체를 스프링 컨테이너에 등록한다.
- 스프링 컨테이너에 등록된 객체를 '스프링 빈' 이라고 하며, @Bean 이 붙은 메소드명을 이름으로 사용한다.
- 스프링 컨테이너에서 필요한 스프링 빈을 찾아서 사용한다.
@Configuration
public class AppConfig(){
@Bean
public MemberRepository memberRepository(){
return new MemoryMemberRepository();
}
@Bean
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
}
public class BeanTest(){
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberRepository memberRepository = ac.getBean("memberRepository",MemberRepository.class);
}
위 코드를 예시로 들어보자.
1. 스프링 컨테이너 생성
우선 AppConfig 클래스에 @Configuration 어노테이션이 붙음으로써 설정 정보로 사용하겠다는 표시를 한다.
이는 이후 싱글톤 객체를 만드는 것을 보장해주는데, 이후에 자세히 다뤄보겠다.
AppConfig 내부엔 'memberRepository' 와 'memberService' 메소드가 있다.
모두 @Bean 이라는 어노테이션이 달려있는데, 이것이 스프링 빈으로 등록하겠다는 의미이다.
(스프링 빈의 이름은 첫 글자가 소문자인 메소드명으로 설정되나 사용자가 직접 변경할 수 있다.)
아래 BeanTest 클래스를 보자.
ApplicationContext 는 스프링 컨테이너라고 하였다.
사실 이는 인터페이스이며, 구현체로 'AnnotationConfigApplicationContext' 가 있다.
new 연산자를 통해 스프링 컨테이너를 생성하고, 설정 정보로 'AppConfig.class' 를 넣어준다.
(구성 정보를 꼭 지정해주어야 한다.)
2. 스프링 빈 등록
AppConfig.class 에서 넘어온 @Bean 어노테이션을 보고 스프링 빈을 등록한다.
즉, 메소드 명(사용자 지정)인 빈 이름과 return 값으로 받은 빈 객체를 스프링 빈 저장소에 저장한다.
여기서 주의할 점은 스프링 빈 이름은 모두 다른 이름이어야 한다. 그렇지 않으면 오류가 발생할 수 있다.
Spring Container | |
Bean Name | Bean Object |
memberRepository | MemoryMemberRepository@x01 |
memberService | memberServiceImpl@x02 |
3. 의존 관계 설정
AppConfig 에서 설정한 정보를 통해 DI 된다.
@Configuration
public class AppConfig(){
@Bean
public MemberRepository memberRepository(){
return new MemoryMemberRepository();
}
@Bean
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
}
위 코드에선 'memberService' 가 'memberRepository' 를 의존한다는 것을 알려준다.
실제로는 new 연산자를 통해 객체를 생성할 때, 스프링 빈으로 등록됨과 동시에 의존 관계 설정까지 마친다.
이 경우는 생성자 주입을 통해 의존 관계를 설정하는 방법인데, Setter 주입, 필드 주입 등 여러 방법이 있다.
2️⃣ BeanFactory
사실 스프링 컨테이너는 다양한 형식의 설정 정보를 받아들일 수 있게 설계되어있다.
이번에 다룬 내용은 Java 코드를 활용한 것이고, 이외에도 XML 이나 Groovy 등으로도 가능하다.
ApplicationContext 는 스프링 컨테이너를 나타내는 인터페이스라고 하였다.
그러나 이보다 더 상위에 존재하는 인터페이스가 있는데, 바로 'BeanFactory' 이다.
즉, 상속 관계가 (상위←하위) 라면
<Interface>BeanFactory ← <Interface>ApplicationContext ← AnnotationConfigApplicationContext
이다.
BeanFactory 는 스프링 컨테이너의 최상위 인터페이스로, 스프링 빈을 관리하고 조회하는 역할을 담당한다.
ApplicationContext 는 BeanFactory 의 모든 기능을 상속받아 제공한다. 그러나 실제로 개발을 할 때 수많은 부가 기능이 필요하기 때문에, 빈 관리 기능과 편리한 부가 기능을 제공한다. 사실상 ApplicationContext 를 많이 사용한다.
3️⃣ BeanDefinition
스프링은 BeanDefinition 을 통해 Java, XML, Groovy 등의 다양한 설정 형식을 지원한다.
이는 빈 설정 메타 정보이며, @Bean (Java), <Bean> (XML) 당 각각 메타 정보가 생성된다.
즉, 다양한 형식의 설정 정보에서 생성된 메타 정보를 기반으로 스프링 빈을 생성하는 것이다.
실제로 BeanDefinition 을 직접 정의하거나 사용할 일은 거의 없다고 한다.
단지 BeanDefinition 의 추상화를 통해 다양한 형태의 설정 정보를 바탕으로 스프링 빈을 등록한다는 것만 알아두자.
참고 : 김영한-스프링 핵심 원리 (기본편), google