준비
본 글의 코드예제룰 수행하기 위해서는 이전 글의 이해와 함께 코드 예제를 수행하여야 합니다.
- [Spring] Spring 간단한 서비스 생성 및 테스트
- [Spring] DI(Dependency Injection)란?
- [Spring] 스프링 컨테이너(Spring Container)
- [Spring] 빈(Bean)
- [Spring] 빈 스코프(Bean Scope)
- [Spring] 싱글톤(Singleton)
- [Spring] 컴포넌트 스캔(Component Scan)
Spring DI 실습
MemberTest.java 수정
package developingman.sample_Project.member;
import developingman.sample_Project.DependencyConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MemeberTest {
public static void main(String[] args){
ApplicationContext ac = new AnnotationConfigApplicationContext(DependencyConfig.class);
MemberService memberService = ac.getBean("memberService", MemberService.class);
Member member = new Member(0L, "leenom@korean.com","LeeNom" , "010-1234-1234");
memberService.createMember(member);
Member currentMember = memberService.getMember(0L);
System.out.println("회원 가입한 유저 : " + member.getName());
System.out.println("현재 첫번째 유저 : " + currentMember.getName());
if(member.getName().equals(currentMember.getName())) {
System.out.println("새롭게 가입한 유저와 현재 유저가 같습니다.");
}
memberService.deleteMember(0L);
if(memberService.getMember(0L) == null){
System.out.println("회원 삭제가 정상적으로 완료 되었습니다.");
}
}
}
- 기존 DependencyConfig를 직접 가져와서 주입해 주는 방식에서 new AnnotationConfigApplicationContext(DependencyConfig.class); 방식을 통해 스프링 컨테이너에 등록된 빈을 가져오는 방식으로 수정하였습니다.
SnackTest.java 수정
package developingman.sample_Project.snack;
import developingman.sample_Project.DependencyConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SnackTest {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(DependencyConfig.class);
SnackService snackService = ac.getBean("snackService", SnackService.class);
Snack snack = new Snack(0L, "인디언밥", "indian meal", 1500);
snackService.createSnack(snack);
if(snackService.getSnack(0L).getKorName().equals(snack.getKorName())){
System.out.println(snack.getKorName() + "가 등록되었습니다.");
}
snackService.editSnack(0L, "인디언 밥", 3000);
if(snackService.getSnack(0L).getPrice() == 3000){
System.out.println(snack.getKorName()+ "의 금액이 정상적으로 변경 되었습니다.");
}
snackService.deleteSnack(0L);
if(snackService.getSnack(0L) == null){
System.out.println("정상적으로 삭제 되었습니다.");
}
}
}
MemberTest 클래스와 같이 수정하였습니다. 수정 후 결과가 올바르게 출력되는지 확인합니다.
스프링 컨테이너
- 코드 예제에서 ApplicationContext가 스프링 컨테이너입니다.
- 기존에 DependencyConfig를 사용해 객체를 생성하고 의존 주입을 했지만, 스프링 컨테이너를 이용한 의존 주입을 사용합니다.
- 스프링 컨테이너는 @Configuration이 붙은 DependencyConfig를 설정 정보로 사용합니다.
- Bean이 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록합니다.
- 직접 자바 코드로 설정 및 등록했던 것을 스프링 컨테이너에 객체만 스프링 빈으로 등록해 주고 스프링 컨테이너에서 찾아서 사용하도록 변경된 것입니다.
컴포넌트 스캔
컴포넌트 스캔을 이용해서 스프링 빈을 등록해 보고 @Autowired를 사용해 보겠습니다.
- 장점
- 스프링 빈을 자동으로 찾아 생성해 줍니다.
- 이전에는 직접 @Bean을 통해 설정 정보를 작성하고 의존 관계도 직접 명시하였습니다.
- 설정 정보 자체가 없기 때문에 의존 관계 주입을 클래스 안에서 해결해 줍니다.
- @Component 애너테이션 붙은 클래스를 찾아서 스프링 빈으로 등록해 주는 방식입니다.
- @Configuration
- 해당 애너테이션에는 @Component가 적용되어 있기 때문에 ComponentScan 할 때 자동으로 스프링 빈 등록이 됩니다.
- 만약 이전 설정 파일 (DependencyConfig 등)에 @Configuration 애너테이션이 붙어 있으면 @Configuration이 설정된 파일 자체를 제거하거나 전체 주석 처리를 해야 합니다.
- 이전 설정 파일(@Configuration이 적용된)을 노두고 싶다면 ComponentScan의 Filter를 사용할 수도 있습니다.
- Autowired
- @ComponentScan & @Component만 사용했을 때 DependencyConfig에 어떤 의존 객체를 주입할지 명시해주지 않기 때문에 의존 주입이 필요한 생성자 부분에 @Autowired를 통해 의존 관계 주입이 필요합니다.
변경 코드
- DependencyConfig.java
package developingman.sample_Project;
import developingman.sample_Project.member.MemberRepository;
import developingman.sample_Project.member.MemberService;
import developingman.sample_Project.snack.SnackRepository;
import developingman.sample_Project.snack.SnackService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class DependencyConfig {
@Bean
public MemberService memberService() {
return new MemberService(new MemberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemberRepository();
}
@Bean
public SnackService snackService(){
return new SnackService(new SnackRepository());
}
@Bean
public SnackRepository snackRepository() {
return new SnackRepository();
}
}
테스트
ComponentScan 방식의 DependencyConfig가 정상적으로 작동되는지 테스트해 봅니다.
sample_project패키지에 ComponentScanTest.java 클래스를 만듭니다.
package developingman.sample_Project;
import developingman.sample_Project.member.MemberService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class ComponentScanTest {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(DependencyConfig.class);
MemberService memberService = ac.getBean(MemberService.class);
System.out.println(MemberService.class.isInstance(memberService));
}
}
위 코드를 실행 시 ture가 출력되는지 확인합니다.
'Spring' 카테고리의 다른 글
[Spring] AOP(Aspect Oriented Programming) 용어 및 개념들 (0) | 2023.04.11 |
---|---|
[Spring] AOP(Aspect Oriented Programming)가 필요한 이유 (0) | 2023.04.11 |
[Spring] 다양한 의존 관계 주입 방법 (0) | 2023.04.09 |
[Spring] 컴포넌트 스캔(Component Scan) (0) | 2023.04.07 |
[Spring] 싱글톤(Singleton) (0) | 2023.04.06 |