Spring Framework는 DI를 어떻게 처리할까 ?
📌 명시적 DI를 위해서는 @Configuration과 @Bean 이라는 annotation이 사용된다.
@Configuration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@Bean
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
@AliasFor("name")
String[] value() default {};
}
@Configuration // 이것은 설정 파일 입니다.
public class PhoneConfig {
@Bean // 빈 생성 선언
public LPhone lPhone() { //LPhone 타입의 Bean 생성, Bean 이름은 lPhone
return new LPhone(); // 실제로 사용될 Bean 객체 반환
}
@Bean(name = "mysPhone") // 빈 객체 선언 : 빈의 이름은 mysPhone
public Sphone sphone() {
return new Sphone();
}
@Bean
public PhoneUser phoneUser() {
PhoneUser user = new PhoneUser(lPhone()); // 생성자를 통해 의존성인 phone을 주입
return user;
}
}
@SpringBootApplication
Bean 객체 관리
@Test
@DisplayName("spring은 bean을 singleton을 관리하는지 테스트")
public void singleTonTest() {
// given
//when
PhoneUser user = ctx.getBean(PhoneUser.class);
LPhone phone = ctx.getBean(LPhone.class);
//then
Assertions.assertSame(user.getPhone(), phone);
}
Type 기반의 Bean 관리
@Test
@DisplayName("Spring container는 기본적으로 타입 기반으로 빈 관리")
public void getPhoneTestByType() {
Assertions.assertThrows(NoUniqueBeanDefinitionException.class, () -> ctx.getBean(SmartPhone.class));
SmartPhone phone = ctx.getBean(SmartPhone.class);
}
@Test
@DisplayName("Spring container는 기본적으로 타입 기반으로 빈 관리")
public void getPhoneTestByType() {
Assertions.assertThrows(NoUniqueBeanDefinitionException.class, () -> ctx.getBean(SmartPhone.class));
SmartPhone phone = ctx.getBean("lPhone", SmartPhone.class);
Assertions.assertEquals(phone.getClass().getName(), LPhone.class.getName());
}