앞에서 만든 예제 코드에 스프링을 사용해보겠습니다.
1. 시작
먼저 Appconfig 에 @Configuration 과 @Bean 애노테이션을 붙여주겠습니다.
<java />
package hello.core;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import hello.core.member.MemberRepository;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.DiscountPolicy;
import hello.core.order.FixDiscountPolicy;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;
import hello.core.order.RateDiscountPolicy;
@Configuration
public class Appconfig {
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public DiscountPolicy discountPolicy() {
// return new FixDiscountPolicy();
return new RateDiscountPolicy();
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
}
- 스프링 컨테이너는 @Configuration 이 붙은 AppConfig 를 설정 정보로 사용
- @Configuration 이 붙은 Appconfig 에서 @Bean 이 붙은 모든 메서드를 호출해서 반환된 객체를 컨테이너에 등록
- 컨테이너에 등록된 객체를 스프링 빈이라고 하며, 메서드의 이름을 스프링 빈의 이름으로 사용
2. 스프링 컨테이너 생성
스프링 컨테이너는 XML 기반으로 만드는 방법과 위에서 사용한 애노테이션으로 만드는 두가지 방식이 있습니다.
<java />
ApplicationContext applicationContext
= new AnnotationConfigApplicationContext(AppConfig.class);
애노테이션으로 만든 Appconfig 를 스프링 컨테이너 인페이스인 ApplicationContext 통해 컨테이너를 생성합니다.

스프링 컨테이너를 생성할때 구성 정보를 지정해줘야 합니다.
new AnnotationConfigApplicationContext (구성정보)

스프링 컨테이너는 파라미터로 전달받은 구성 정보를 사용해서 @Bean 이 붙은 메서드를 찾아서 스프링 빈을 등록합니다.
빈 이름은 메서드 이름을 사용하며, 직접 부여할 수 있습니다.
<java />
@Bean(name = "newmemberServie")
주의할 점은 빈 이름은 항상 다른 이름을 부여해야 합니다.

다음으로 스프링 컨테이너는 설정 정보를 참고해서 의존관계를 주입합니다.
3. 스프링 빈 조회
위에서 만든 스프링 컨테이너를 통해 스프링 빈을 조회해보겠습니다.
src/test/java 디렉토리에 테스트를 할 수 있는 ApplicationContext 클래스를 만들겠습니다.

3.1. 모든 빈 조회
<java />
package hello.core;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class ApplicationContext {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Appconfig.class);
@Test
void findAllBean() {
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for(String beanDefinitionName : beanDefinitionNames) {
Object bean = ac.getBean(beanDefinitionName);
System.out.println("name = " + beanDefinitionName + " object = " + bean);
}
}
}
위와 같이 Appconfig.class 의 설정 정보를 통해 스프링 컨테이너에서 빈을 읽어서 등록합니다.
<bash />
name = org.springframework.context.annotation.internalConfigurationAnnotationProcessor object = org.springframework.context.annotation.ConfigurationClassPostProcessor@4e70a728
name = org.springframework.context.annotation.internalAutowiredAnnotationProcessor object = org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@b7838a9
name = org.springframework.context.annotation.internalCommonAnnotationProcessor object = org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@696f0212
name = org.springframework.context.event.internalEventListenerProcessor object = org.springframework.context.event.EventListenerMethodProcessor@5733f295
name = org.springframework.context.event.internalEventListenerFactory object = org.springframework.context.event.DefaultEventListenerFactory@1c3146bc
name = appconfig object = hello.core.Appconfig$$SpringCGLIB$$0@56c698e3
name = memberRepository object = hello.core.member.MemoryMemberRepository@47a86fbb
name = discountPolicy object = hello.core.order.RateDiscountPolicy@f478a81
name = orderService object = hello.core.order.OrderServiceImpl@19553973
name = memberService object = hello.core.member.MemberServiceImpl@7bb6ab3a
출력결과를 보면 스프링 자체 빈들과 함께 Appconfig 에 등록한 빈들이 출력됩니다.
Appconfig 또한 빈으로 등록되어 관리됩니다.
3.2. 설정 정보의 빈 조회
설정 정보인 Appconfig 에 등록한 빈을 조회하기 위해서는 아래와 같은 명령어를 사용합니다.
- ac.getBean(빈이름, 타입)
- ac.getBean(타입)
<java />
package hello.core;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import hello.core.member.MemberService;
public class ApplicationContext {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Appconfig.class);
@Test
void findBeanByName() {
MemberService memberSerivce = ac.getBean("memberService", MemberService.class);
System.out.println("memberSerivce = " + memberSerivce);
System.out.println("memverService.getClass() = " + memberSerivce.getClass());
}
}
위와 같이 MemberService.class 타입의 memberSerivce 라는 이름을 같은 빈을 조회하면 다음과 같이 출력됩니다.
<bash />memberSerivce = hello.core.member.MemberServiceImpl@4e70a728 memverService.getClass() = class hello.core.member.MemberServiceImpl
다음과 같이 타입으로 조회해도 결과는 같습니다.
<java />
package hello.core;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import hello.core.member.MemberService;
public class ApplicationContext {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Appconfig.class);
@Test
void findBeanByType() {
MemberService memberSerivce = ac.getBean(MemberService.class);
System.out.println("memberSerivce = " + memberSerivce);
System.out.println("memverService.getClass() = " + memberSerivce.getClass());
}
}
4. xml 기반 사용법
위에서 사용한 Appconfig.class 를 xml 기반으로 만들어보겠습니다.

src/main/resources 에 appConfig.xml 파일을 만들고 아래와 같이 작성합니다.
<html />
<?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>
<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.order.RateDiscountPolicy">
</bean>
</beans>
다음으로 appConfig.xml 을 설정 정보로 사용해보겠습니다.
<java />
ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");
xml 파일을 설정 정보로 사용하기 위해서는 GenericXmlApplicationContext 를 사용합니다.
<java />
package hello.core;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import hello.core.member.MemberService;
public class XmlAppContext {
ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");
@Test
void xmlAppContext() {
MemberService memberSerivce = ac.getBean("memberService", MemberService.class);
System.out.println("memberSerivce = " + memberSerivce);
System.out.println("memverService.getClass() = " + memberSerivce.getClass());
}
}
xml 설정 정보를 사용하는 XmlAppContext 클래스를 생성하고 실행을 합니다.
<bash />memberSerivce = hello.core.member.MemberServiceImpl@736caf7a memverService.getClass() = class hello.core.member.MemberServiceImpl
실행을 하면 memberService 라는 이름으로 등록된 빈을 갖고 오는것을 확인할 수 있습니다.
'Spring > Spring 핵심 원리' 카테고리의 다른 글
의존관계 자동주입 (0) | 2023.01.21 |
---|---|
컴포넌트 스캔 (0) | 2023.01.21 |
예제 만들기 - AppConfig 생성 (0) | 2023.01.20 |
예제 만들기 - 주문과 할인 도메인 설계 (0) | 2023.01.20 |
객체 지향과 스프링 - 좋은 객체 지향 설계의 5가지 원칙 (0) | 2023.01.16 |