스프링 컨테이너 (애노테이션 기반 자바 코드 설정)
// 스프링 컨테이너 생성
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
ApplicationContext
를 스프링 컨테이너라고 한다.
이때, ApplicationContext 는 인터페이스이며, AnnotationConfigApplicationContext 는 인터페이스의 구현체이다.
스프링 컨테이너는 생성자가 클래스 정보를 받으면, 해당 클래스가 스프링 빈으로 자동 등록된다.
스프링 컨테이너는 두 가지 방식으로 설정할 수 있다.
1. XML 기반
(거의 사용 X)
2. 애노테이션 기반의 자바 설정 클래스
(거의 대부분)
스프링 컨테이너 생성 과정
1. @Configuration 이 붙은 AppConfig를 설정 정보로 사용하여
new AnnotationConfigApplicationContext(AppConfig.class)
를 통해 스프링 컨테이너를 생성한다.
2. @Bean 으로 등록된 메서드를 모두 호출하여 스프링 빈으로 등록한다.
2. 등록된 빈들을 스프링 빈 저장소에 스프링 빈 이름
, 빈 객체
짝지어 저장하여 싱글톤
으로 관리한다.
이때, 스프링 빈 이름은 @Bean 이 붙은 메서드 명으로 사용한다.
( @Bean(name="aa") 로 이름을 직접 부여할 수도 있다.)
3. 스프링 컨테이너가 생성되면 스프링 빈들 간의 의존관계를 자동으로 주입(DI)한다.
>참고<
- 빈 이름은 항상 달라야 한다. (다른 빈 무시 or 기존 빈 덮어버림 등 오류 발생)
public class MemberApp {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
Member member = new Member(1L, "memberA", Grade.VIP);
memberService.join(member);
Member findMember = memberService.findMember(1L);
System.out.println("new member = " + member.getName());
System.out.println("find Member = " + findMember.getName());
}
}
}
싱글톤 컨테이너
스프링 컨테이너로 스프링 빈을 등록하면, 싱글톤으로 관리한다.
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
}
@Configuration이 붙은 AppConfig 로 스프링 컨테이너를 생성할 때,
실제 클래스가 아닌 프록시 객체를 생성하여 스프링 빈으로 등록한다.
따라서 임의의 다른 클래스를 통해
@Bean 이 붙은 메서드마다 이미 스프링 컨테이너에 등록되어 있으면 존재하는 빈을 반환하고,
스프링 컨테이너에 등록되어 있지 않으면 생성하여 스프링 빈으로 등록하고 반환하는 코드가 실행된다.
// AppConfig@CGLIB 예상 코드
@Bean
public MemberRepository memberRepository() {
if (memoryMemberRepository가 이미 스프링 컨테이너에 등록되어 있으면?) {
return 스프링 컨테이너에서 찾아서 반환;
} else { //스프링 컨테이너에 없으면
기존 로직을 호출해서 MemoryMemberRepository를 생성하고 스프링 컨테이너에 등록
return 반환
}
}
이러한 프록시 객체 덕분에 싱글톤이 보장된다.
>참고<
- @Configuration 없이 @Bean만 사용해도 스프링 빈으로 등록되지만, 싱글톤을 보장하지 않는다
스프링 컨테이너(XML 설정)
컴파일 없이 빈 설정 정보를 변경할 수 있다.
GenericXmlApplicationContext
를 사용하여 XML
설정 파일을 넘기면 된다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="memberService" class="hello.core.member.MemberServiceImpl">
<constructor-arg name="memberRepository" ref="memberRepository" />
</bean>
<bean id="memberRepository" class="hello.core.member.MemoryMemberRepository" />
<bean id="orderService" class="hello.core.order.OrderServiceImpl">
<constructor-arg name="memberRepository" ref="memberRepository" />
<constructor-arg name="discountPolicy" ref="discountPolicy" />
</bean>
<bean id="discountPolicy" class="hello.core.discount.RateDiscountPolicy" />
</beans>
// 아래와 동일한 설정이다.
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
}
위와 같은 xml 설정 파일을 resources 디렉토리에 생성하여 사용해 준다.
@Test
void xmlAppContext() {
ApplicationContext ac = newGenericXmlApplicationContext("appConfig.xml");
MemberService memberService = ac.getBean("memberService", MemberService.class);
assertThat(memberService).isInstanceOf(MemberService.class);
}
BeanFactory 와 ApplicationContext
BeanFactory 나 ApplicationContext 를 스프링 컨테이너라고 한다.
보통 부가기능이 포함된 ApplicationContext 를 사용한다.
BeanFactory
스프링 컨테이너의 최상위 인터페이스이다.
스프링 빈을 관리, 조회하는 역할을 담당한다.
getBean( ) 및 대부분의 기능을 제공한다.
ApplicationContext
BeanFactory 기능을 모두 상속받아 제공한다.
빈을 관리, 조회하는 역할 외의 아래와 같은 부가기능을 제공한다.
메시지 소스를 활용한 국제화 기능
: 한국에서 들어오면 한국어로, 영어권에서 들어오면 영어로 출력
환경변수
: 로컬, 개발, 운영 등 구분해서 처리
애플리케이션 이벤트
: 이벤트를 발행, 구독하는 모델을 편리하게 지원
편리한 리소스 조회
: 파일, 클래스패스, 외부 등에서 리소스를 편리하게 조회
출처 | 스프링 핵심 원리 - 기본편(김영한) - 인프런
'💠프로그래밍 언어 > Java' 카테고리의 다른 글
[Spring] @Autowired 에서 조회되는 빈이 2개 이상이라면 ?? (@Primary, @Qualifier) (0) | 2025.02.26 |
---|---|
[Spring] 롬복 라이브러리의 편리한 기능들 (0) | 2025.02.26 |
[Spring] 스프링 빈 조회하기, 스프링 빈 설정 메타 정보(BeanDefinition) (0) | 2025.02.25 |
[Spring] AOP 는 무엇일까 ?? (0) | 2024.12.30 |
[Spring] 순수 JDBC → JdbcTemplate → JPA → 스프링 데이터 JPA (0) | 2024.12.30 |