π΅π»βοΈ κΆκΈμ¦μ κ°κ² λ κ³κΈ°
νμ΅ κ³Όμ μμ λ€μκ³Ό κ°μ μμ μ½λλ₯Ό λ§μ£Όνκ² λλ€.
@Test
void test3() {
StaticApplicationContext context = new StaticApplicationContext();
context.registerBeanDefinition("printer", new RootBeanDefinition(Printer.class));
BeanDefinition helloDef = new RootBeanDefinition(Hello.class);
helloDef.getPropertyValues().addPropertyValue("name", "Spring");
helloDef.getPropertyValues().addPropertyValue("printer", new RuntimeBeanReference("printer"));
context.registerBeanDefinition("hello", helloDef);
Hello hello = context.getBean("hello", Hello.class);
hello.print();
}
μμ μ½λλ₯Ό λ³΄κ³ , μ #registerbeanDefinition μ μ¬μ©νμκΉ νλ μλ¬Έμ΄ λ€μλ€. κ·Έλ₯ registerBean μ νλ©΄ λλ κ² μλκ°? μ΄λ¬ν λ¨μν κΆκΈμ¦κ³Ό μΌμ’ μ λ°λ°μ¬μ μ°Ύμ보기 μμνλ€.
β BeanDefinition μ΄λ?
A BeanDefinition describes a bean instance, which has property values, constructor argument values, and further information supplied by concrete implementations.
곡μ λ¬Έμμμλ BeanDefinition μ μμ κ°μ΄ μ μνκ³ μλ€. ν΄μνμλ©΄ BeanDefinition μ λΉ μΈμ€ν΄μ€λ₯Ό μ€λͺ νλ μν μ νλ€. λν μμ± κ°κ³Ό μμ±μμ μΈμ κ°, κ·Έλ¦¬κ³ κ΅¬μ²΄μ μΈ κ΅¬ν체λ€μ μν΄ μ 곡λλ μ 보λ€μ κ°λλ€λ κ²μ΄λ€.
BeanDefinition μ μμ± κ°
μ μμμ μ΄μΌκΈ°νλBeanDefinition μ μμ± κ°μ΄λ 무μμΌκΉ? μ΄λ λ¨μν κ°μ²΄μ νλκ°μ΄λΌκ³ μκ°νλ©΄ λλ€.
Student λΌλ κ°μ²΄κ° μμ λ name μ΄λΌλ νλμ κ°λ μμ± κ°μ΄κ³ , Service κ° Repository λ₯Ό μμ‘΄νλ€λ©΄ μ΄ μμλ μμ± κ°μ΄λ€. BeanDefinition μμλ μ΄λ₯Ό μ§μ μ€μ ν΄μ€ μ μλ€.
BeanDefinition helloDef = new RootBeanDefinition(Hello.class);
helloDef.getPropertyValues().addPropertyValue("name", "Spring");
helloDef.getPropertyValues().addPropertyValue("printer", new RuntimeBeanReference("printer"));
μμ μ μν μμ μ½λμμλ μ΄μ κ°μ λ΄μ©μ νμΈν μ μλ€.
BeanDefinition μ μμ± κ°λ€μ #getPropertyValues λ₯Ό ν΅ν΄ λͺ¨λ κ°μ Έμ€κ³ , key μ value λ₯Ό μ μν΄ #addPropertyValue λ₯Ό ν΅ν΄ μμ±μ μΆκ°νλ€.
μμ± κ°μ΄ μΈν λλ μ리
λ¬Έλ μ΄ μμ± κ°μ μ΄λ»κ² μΈν λλμ§ κΆκΈνλ€. key μ value ννμ΄λ νλλͺ μΌκΉ? μλλ©΄ setter μ μ΄λ¦μΌκΉ?
μ°μ μ λ΅μ setter μ΄λ€.
helloDef.getPropertyValues().addPropertyValue("name", "Spring");
public class Hello {
private final String name;
public void setName(String name){
}
}
helloDef.getPropertyValues().addPropertyValue("naaame", "Spring");
public class Hello {
private final String name;
public void setNaaame(String name){
}
}
μμ λ μ½λλ λͺ¨λ μ μ μλνλ€. μ¦, setXXX λ₯Ό ν΅ν΄ μμ±μ΄ μΈν λλ κ²μ΄λ€.
RuntimeBeanReference
BeanDefinition helloDef = new RootBeanDefinition(Hello.class);
helloDef.getPropertyValues().addPropertyValue("name", "Spring");
helloDef.getPropertyValues().addPropertyValue("printer", new RuntimeBeanReference("printer"));
μμ μμ μ½λμλ λνλ μλ―, RuntimeBeanReference λ₯Ό μμ±ν΄ λ΄λΆμ "printer" λ₯Ό λ¨μν λ¬Έμμ΄λ‘ λ£κ³ μλ€.
κ·ΈλΌμλ μ΄λ»κ² Helllo λΌλ ν΄λμ€μ νλμ μ μμ μΌλ‘ Printer ν΄λμ€μ λν μμ‘΄μ± μ£Όμ μ΄ μ΄λ€μ§λ κ²μΌκΉ?
μ°μ RuntimeBeanReference λ λΉ μ€μ μ 보 μ€ λ€λ₯Έ λΉμ μ°Έμ‘°ν νμκ° μλ κ²½μ° μ¬μ©νλ ν΄λμ€μ΄λ€. μ¦, ‘λμ€μ λ μ΄ κ° νμνλκΉ λ°νμμ μ°Ύμμ μ£Όμ ν΄μ€~’ νλ μꡬμ¬νμΈ κ²μ΄λ€.
λν λ¬Έμμ΄λ‘λ§ μ μνλλΌλ ν΄λΉ Printer μ μΈμ€ν΄μ€λ₯Ό μ μμ μΌλ‘ μ°Ύμ μ£Όμ ν μ μλ μ΄μ λ, ApplicationContext μμ printer λΌλ μ΄λ¦μ κ°μ§ λΉμ μ°Ύμ μ£Όμ ν΄μ£ΌκΈ° λλ¬Έμ΄λ€.
β μ Bean μ λ±λ‘νμ§ μκ³ BeanDefinition μ λ±λ‘ν κΉ?
μ€νλ§ λΆνΈμ λ³Έμ§μ Bean μ΄λΌλ μκ°μ νλ€. κ·Έλ κΈ°μ μμ μ΄μΌκΈ°νλ κ²μ²λΌ μ κ΅³μ΄ #registerBean μ μ¬μ©νμ§ μκ³ , #registerBeanDefinition μ μ¬μ©νλμ§μ λν μλ¬Έμ΄ λ€μλ€.
κ·Έλ¬λ μ€μ λ‘ κ³΅λΆλ₯Ό νλ€ λ³΄λ, μ»΄ν¬λνΈ μ€μΊμ΄ μ΄λ€μ§ λ μ¬μ€μ λ±λ‘λλ κ²μ Bean μ΄ μλλΌ BeanDefinition μ΄λΌλ κ²μ μκ² λλ€.
π λ΄κ° μκ°νλ μ€νλ§λΆνΈμ μ»΄ν¬λνΈ μ€μΊ κ³Όμ
- @Bean μ΄ λΆμ ν΄λμ€λ€μ λͺ¨λ μ€μΊ
- ν΄λΉ ν΄λμ€μ μΈμ€ν΄μ€λ€μ λͺ¨λ μμ±ν΄μ ApplicationContext μ λ±λ‘
βοΈ μ€μ μ»΄ν¬λνΈ μ€μΊ κ³Όμ
- μ»΄ν¬λνΈ μ€μΊ μμ
- @Component κ΄λ ¨ μ΄λ Έν μ΄μ μ΄ λΆμ ν΄λμ€λ€μ λν BeanDefinition μ λ§λ€μ΄μ BeanDefinitionRegistry μ λ±λ‘
- 컨ν μ΄λκ° μ΄κΈ°ν λ λ μ μ ν μμ μ λ°λΌ λΉμ μμ±νλ€
κ·Έλ κΈ°μ ApplicationContext μ registerBeanDefinition μ νλ κ²μ μ€νλ € λ λ§λ μμμΈ κ²μ΄λ€.
β μ μ μλ₯Ό λ±λ‘νκ³ λ°λ‘ μμ±μ νμ§ μλ κ²μΌκΉ?
μ€νλ§μμ λ€λ£¨λ λΉμ μ°λ¦¬κ° POJO μμ μμ±νλ κ°μ²΄μ μΈμ€ν΄μ€μλ λ€λ₯΄λ€. μ€νλ§μμμ λΉμ λ§μ λΆκ°μ κΈ°λ₯μ μνν΄μΌ νλ€. λν μ΄λ₯Ό μν΄μλ μ€νλ§ μ»¨ν μ΄λκ° κ°μ²΄μ μμ± μμ μ΄λ κ³Όμ μ μ μ΄ν΄μΌ νλ€.
1. μ§μ° μμ±μ ν΅ν΄ λ©λͺ¨λ¦¬μ 리μμ€λ₯Ό μ μ½νλ€.
λ°λ‘ λΉμΌλ‘ λͺ¨λ λ§λ€κ² λλ©΄ λ©λͺ¨λ¦¬μ 리μμ€κ° λλΉλ μλ μλ€. μ€νλ§ λΆνΈμλ 'μ§μ° μμ±'μ΄ μ‘΄μ¬νλ€.
μ΄λ₯Ό ν΅ν΄ ν΄λΉ λΉμ μ€μ λ‘ νΈμΆν λκΉμ§ μΈμ€ν΄μ€ννλ μμ μ λ―Έλ£° μ μλ€. λ°λΌμ μ€νλ§μμλ μ μλ§ λ±λ‘ν΄λκ³ μμ± μμ μ λ°λ‘ κ΄λ¦¬νλλ‘ νλ κ²μ΄λ€.
2. μμ‘΄μ± κ·Έλνλ₯Ό κ΄λ¦¬νκΈ° μν΄
μ€νλ§μμλ μν μ°Έμ‘°λ₯Ό λ°©μ§ν μ μκ² ν΄μ€λ€. μ΄κ° κ°λ₯ν μ΄μ λ, λΉμ μ μλ₯Ό λ¨Όμ μ νμνλ©° μ€νλ§ μ»¨ν μ΄λκ° μμ‘΄μ±μ νμ ν΄ μν μ°Έμ‘°κ° μ‘΄μ¬νλμ§ νμΈν΄μ£ΌκΈ° λλ¬Έμ΄λ€.
λͺ¨λ μ μλ₯Ό ν보ν λ€μμΌ μΈμ€ν΄μ€ μμ±μ νκΈ° λλ¬Έμ μμ± μμ μ λν λ¬Έμ λ₯Ό λ°©μ§ν μ μλ€.
3. νλ‘μ ꡬ쑰λ₯Ό μν΄
μ€νλ§μμλ νλ‘μ ꡬ쑰λ₯Ό μ¬μ©νλ€. μλ₯Ό λ€μ΄, @Configuration μ΄ λΆμ ν΄λμ€μ κ²½μ° Bean μ λ±λ‘ν μ μλ€. μ΄ λ, λ¨μν POJO λ‘λ§ ν΄λΉ ν΄λμ€λ₯Ό κ΄λ¦¬νκ² λλ©΄ Bean μΌλ‘ λ±λ‘λλ νΉμ ν΄λμ€μ μΈμ€ν΄μ€κ° μ¬λ¬κ°κ° λ μλ μλ€.
κ·Έλ¬λ ν΄λΉ @Configuration μ΄ λΆμ ν΄λμ€λ₯Ό νλ‘μλ‘ κ΄λ¦¬ν¨μΌλ‘μ λͺ¨λ μΈμ€ν΄μ€λ€μ μ±κΈν΄μΌλ‘ κ΄λ¦¬ν μ μκ² λλ€.
μΈμ€ν΄μ€λ₯Ό μμ±νλ κ³Όμ μμ λΉμ λ³νν΄ μ‘°μν μ μμ΄μΌ νκΈ°μ, μ¦ κ°μ²΄μ μΈμ€ν΄μ€νλ₯Ό ν κΆλ¦¬κ° μ¨μ ν μ€νλ§ μ»¨ν μ΄λμκ² μμ΄μΌ νκΈ°μ μ μλ₯Ό λ¨Όμ λ±λ‘νκ² λλ κ²μ΄λ€.
β #registerBean λ©μλλ μ μ‘΄μ¬νλκ±ΈκΉ?
κ·Έλ λ€λ©΄ ApplicationContext μ registerBean λ©μλκ° μ μ‘΄μ¬νλμ§μ λν μλ¬Έμ΄ λ€ κ²μ΄λ€.
κ·Έλ¬λ μ¬μ€ registerBean λ©μλλ₯Ό μ€μ λ‘ νμΈν΄λ³΄λ©΄, λ΄λΆμ μΌλ‘λ BeanDefinitionμ λ±λ‘νκ³ μλ€λ κ²μ νμΈν μ μλ€.
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//.. μλ΅
// BeanDefinition μ λ±λ‘
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
μ¦ μ΄λ λ¨μν Bean μΌλ‘ μΈμνκ³ μλ κ°λ°μμκ² νΈμμ±μ μ 곡νκΈ° μν λ©μλμ μ§λμ§ μλ κ²μ΄λ€.
β μ°λ¦¬λ BeanDefinition μ μΈμ μ¬μ©ν κΉ?
μ€μ λ‘ μ€νλ§λΆνΈ κ°λ°μ νλ©΄μ BeanDefinition μ μ§μ μ μΌλ‘ λ€λ£° μΌμ κ±°μ μμλ€. μλνλ©΄ μ΄μ κΉμ§ λͺ¨λ λΉλ€μ λλΆλΆ μ»΄ν¬λνΈ μ€μΊμ μν΄ μ²λ¦¬ν μ μμκΈ°μ λ΄λΆμ μΌλ‘λ BeanDefinition μ λ€λ£¨κ³ μμμ§ λͺ°λΌλ, μ§μ μ¬μ©ν μΌμ μμκΈ° λλ¬Έμ΄λ€.
κ·Έλ¬λ μ΄λ λΉ κ΅¬μ±κ³Ό μ£Όμ λμμ΄ μ¬μ μ κ³ μ λμ΄ μλ κ²½μ°μλ§ ν΄λΉλλ€. μΈλΆ 쑰건μ μν΄ λ°νμμ λ§μ½ μ΄λ€ λΉμ μ£Όμ ν μ§ λͺ¨λ₯Έλ€λ©΄ μ΄λ»κ² ν΄μΌ ν κΉ?
μλ₯Ό λ€μ΄, json νμΌμ μ½κ³ κ²½μ°μ λ°λΌ νΉμ λΉμ μ£Όμ ν΄μΌ νλ€κ³ κ°μ ν΄λ³΄μ.
{
"usePaymentService": true,
"useNotificationService": false
}
if (config.isUsePaymentService()) {
RootBeanDefinition bd = new RootBeanDefinition(PaymentService.class);
registry.registerBeanDefinition("paymentService", bd);
}
if (config.isUseNotificationService()) {
RootBeanDefinition bd = new RootBeanDefinition(NotificationService.class);
registry.registerBeanDefinition("notificationService", bd);
}
λ§μ½ μμ κ°μ΄ μ£Όμ ν΄μΌ νλ λΉμ΄ κ³ μ λμ΄ μμ§ μκ³ , μΈλΆ 쑰건μ λ°λΌ μ£Όμ ν΄μΌ νλ λΉμ λ°νμμλ§ μΈμν μ μλ€λ©΄ κ°λ°μκ° μ§μ BeanDefinition μ μ μν΄ λ±λ‘ν΄μ€μΌ νλ€.
β BeanDefinition μ μΈμ Bean μ΄ λ κΉ?
μ μλ‘λ§ λ¨μμμλλ°, μΈμ μΈμ€ν΄μ€νκ° λμ΄ μ€μ λΉμ΄ λλ κ±ΈκΉ? μ΄λ ν¬κ² λ κ°μ§κ° μ‘΄μ¬νλ€.
1. ApplicationContext κ° refresh λλ κ²½μ°
ApplicationContext κ° refresh λλ κ²½μ°μλ μμ‘΄μ± μ£Όμ κ³Ό μΈμ€ν΄μ€νκ° μΌμ΄λλ€. μ»΄ν¬λνΈ μ€μΊμ΄ μ΄λ€μ§κ³ λλ©΄ λ΄λΆμ μΌλ‘ λ°λ‘ refresh κ° λκΈ° λλ¬Έμ μ°λ¦¬λ Bean μ΄ μΈμ€ν΄μ€ν λμ΄ μλ μ±λ‘ λ§μ£Όνκ² λλ€.
2. μ€μ λΉμ΄ νΈμΆλλ κ²½μ° (#getBean)
Beanμ΄ μ§μ° μ΄κΈ°ν λμμΈ κ²½μ°, λλ λ°νμμ μ΄λ€ λΉμ΄ μ£Όμ λ μ§κ° κ²°μ λλ κ²½μ°μλ refresh() μ΄νμ BeanDefinitionμ΄ λ±λ‘λκΈ°λ νλ€. μ΄λ° κ²½μ°, λͺ μμ μΌλ‘ refresh()λ₯Ό νΈμΆνκ±°λ, μ€μ λ‘ λΉμ μμ²νλ μμ μμμΌ μΈμ€ν΄μ€νκ° μ΄λ£¨μ΄μ§λ€.