AppConfig.java 수정
@Configuration을 클래스 앞에 붙여서 앱의 구성정보,설정정보 파일임을 명시해준다.
@Bean 어노테이션을 각 메서드에 붙여준다. -> 각 객체들이 스프링컨테이너에 등록된다.
@Configuration
public class AppConfig { //프로젝트의 객체 생성,구성,주입 환경설정을 하는 중요 역할
@Bean
public MemberService memberService() {
return new MemberServiceImpl(MemberRepository());
}
@Bean
public MemberRepository MemberRepository() {
return new MemoryMemberRepository();
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(MemberRepository(), DiscountPolicy());
}
@Bean
public DiscountPolicy DiscountPolicy() {
return new RateDiscountPolicy();
}
}
다음과 같이 수정하였다.
MemberApp.java 수정
ApplicationContext가 스프링 컨테이너라고 보면 된다. ( Bean 객체들을 관리함)
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
이 코드를 추가해준다.
AppConfig에 적은 @Bean 어노테이션이 붙은 객체들을 생성해서 스프링 컨테이너에 등록시켜준다.
public class MemberApp {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = applicationContext.getBean("memberService",
MemberService.class);//객체의 이름은 AppConfig에 적은 메서드이름으로 적어준다. 두번쨰는 타입을 적어준다.
Member memberA = new Member(1L, "memberA", Grade.VIP); //테스트용 멤버생성
memberService.join(memberA); //가입메소드 사용
Member findMember = memberService.findMember(1L); // 정상 가입됬는지 findMember 메소드를 사용해본다.
System.out.println("new member = " + memberA.getName());
System.out.println("find Member = " + findMember.getName());
}
}
스프링빈으로 등록된 멤버서비스를 컨테이너에서 가져올때 Context를 이용해서 getBean으로 가져온다.
가져올 객체이름(AppConfig에 적은 메소드명) 과 타입을 적어서 가져올 수 있다.
MemberApp을 실행해보면
결과위에 로그가 찍힌것을 확인할 수있는데 빨간부분이 AppConfig 파일(@Configuration)과 @Bean 으로 등록해놓은것들이 컨테이너에 들어간것을 확인할 수 있다. 빨간색 윗부분은 스프링이 필요해서 기본적으로 등록시켜놓는 Bean이다.
OrderApp.java 도 수정
public class OrderApp {
public static void main(String[] args) {
// AppConfig appConfig = new AppConfig();
// MemberService memberService = appConfig.memberService();
// OrderService orderService = appConfig.orderService();
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = ac.getBean("memberService", MemberService.class);
OrderService orderService = ac.getBean("orderService", OrderService.class);
Long memberId = 1L;
Member member = new Member(memberId, "memberA", Grade.VIP);
memberService.join(member);
Order order = orderService.createOrder(memberId, "itemA", 10000);
System.out.println("order = " + order);
}
}
Context를 이용해서 컨테이너에 있는 빈을 꺼내오는 형식으로 수정하였다.
ApplicationContext
이전에는 AppConfig 객체를 만들고 AppConfig 안에있는 메소드를 이용하여 객체를 생성하고 그 객체를 주입해주었지만
이제 부터는 스프링컨테이너를 사용하여 필요한 스프링 빈(객체)를 가져온다.
스프링컨테이너는 @Configuration 어노테이션으로 AppConfig를 설정(구성)정보로 사용하고 , AppConfig안에 @Bean 어노테이션이 붙은 메소드들을 호출해서 반환된 객체를 스프링 컨테이너에 등록된다.
스프링컨테이너에 등록된 객체는 스프링빈이라 한다.
스프링빈은 @Bean이 붙은 메소드명을 스프링 빈의 이름으로 사용한다. ( 물론 @Bean(name = "바꾸고싶은이름") 식으로 바꿀 수 있다 , 디폴트값을 사용하는것이 좋긴하다)
기존에는 개발자가 직접 자바코드로 모든것을 했다면 이제부터는 스프링 컨테이너에 객체를 스프링 빈으로 등록하고,
스프링 컨테이너에서 스프링 빈을 찾아서 사용하도록 변경되었다.
스프링 컨테이너와 스프링 빈
스프링 컨테이너 생성
스프링 컨테이너가 생성되는 과정을 알아보자.
ApplicationContext applicationContext =new AnnotationConfigApplicationContext(AppConfig.class);
ApplicationContext를 스프링 컨테이너라고 한다.
ApplicationContext는 인터페이스이고 그걸 구현한 구현체 중 하나가 AnnotationConfigApplicationContext이다.
스프링 컨테이너는 XML 기반으로 만들수도 있고,
어노테이션 기반의 자바 설정 클래스로도 만들 수 있다.
이전에 만든 AppConfig.java에서 사용했던 방식이
어노테이션 기반의 자바 설정 클래스로 스프링 컨테이너를 만든것이다.
@Configuration
public class AppConfig { //프로젝트의 객체 생성,구성,주입 환경설정을 하는 중요 역할
@Bean
public MemberService memberService() {
return new MemberServiceImpl(MemberRepository());
}
@Bean
public MemberRepository MemberRepository() {
return new MemoryMemberRepository();
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(MemberRepository(), DiscountPolicy());
}
@Bean
public DiscountPolicy DiscountPolicy() {
return new RateDiscountPolicy();
}
}
위에 코드가
어노테이션 기반(@Configuration,@Bean)의 자바 설정 클래스(AppConfig.class)이고
ApplicationContext applicationContext =new AnnotationConfigApplicationContext(AppConfig.class);
위의 코드가 어노테이션기반 자바설정 클래스 AppConfig.class를 가지고
스프링컨테이너를 생성하는 코드이다.
스프링 컨테이너의 생성 과정
1. 스프링 컨테이너의 생성
- new AnnotationConfigApplicationContext(AppConfig.class) 라는 코드가 실행되면서 스프링 컨테이너가 생성된다.
- 스프링 컨테이너 안에는 스프링 빈 저장소라는게 있다. 그 안에 key : 빈 이름 value : 빈 객체로 저장이 되는.
- 그리고 그안에 스프링빈을 채우기 위해서 구성정보를 활용해줘야하는데 그때 전달된 AppConfig.class를 이용하는것이다
2. 스프링 빈 등록
@Bean 어노테이션 붙은 메소드들을 전부 호출해서
메소드이름을 빈이름(key)로 가지고 그 메소드의 리턴값은 빈 객체(value)로 가진다.
3. 스프링 빈 의존관계 설정 - 준비
스프링빈간에 의존관계 설정을 해야한다.
4. 스프링 빈 의존관계 설정 - 완료
설정정보(AppConfig.java)를 통해 의존관계를 주입해준다.
memberService() 메소드를 보면 멤버서비스임플 객체를 생성하면서 전달인자로 memberRepository를 전달한다.
그렇다는것은 멤버서비스 객체를 생성하려면 멤버리포지토리가 필요한것이므로
멤버서비스는 멤버리포지토리를 의존한다고 볼 수 있다 ( 멤버서비스가 멤버리포지토리를 가리키는 의존관계)
오더서비스는 멤버리포지토리와 디스카운트폴리시 둘다 의존하므로 오른쪽 그림같이 표현한다.
댓글