하나씩 차근차근
article thumbnail

앞에서 만든 예제 코드에 스프링을 사용해보겠습니다.

 

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 라는 이름으로 등록된 빈을 갖고 오는것을 확인할 수 있습니다.

profile

하나씩 차근차근

@jeehwan_lee

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!