Spring Bean


Spring Bean μ΄λž€ IoC Container 내뢀에 λ“€μ–΄μžˆλŠ” 객체둜 ν•„μš”ν•  λ•Œ κΊΌλ‚΄μ„œ μ‚¬μš©ν•  수 μžˆλ‹€. @Bean μ΄λ‚˜ xml 섀정을 톡해 일반 객체λ₯Ό Bean 으둜 등둝할 수 μžˆλ‹€. μŠ€ν”„λ§μ€ μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆμ— μŠ€ν”„λ§ λΉˆμ„ 등둝할 λ•Œ, 기본으둜 μ‹±κΈ€ν†€μœΌλ‘œ λ“±λ‘ν•œλ‹€. λ”°λΌμ„œ 같은 μŠ€ν”„λ§ 빈이면 λͺ¨λ‘ 같은 μΈμŠ€ν„΄μŠ€λ‹€.

Spring Bean 생성 κ³Όμ •


Spring Bean 의 생λͺ…μ£ΌκΈ°

  1. 객체 생성
  2. 의쑴 μ„€μ •
  3. μ΄ˆκΈ°ν™”
  4. μ‚¬μš©
  5. μ†Œλ©Έ

Bean 은 IoC Container 에 μ˜ν•΄ 생λͺ…μ£ΌκΈ°λ₯Ό κ΄€λ¦¬ν•˜λ©° μ΄ˆκΈ°ν™” 방법은 @PostConstruct λ₯Ό Bean μ†Œλ©Έμ—μ„œλŠ” @PreDestroy λ₯Ό μ‚¬μš©ν•œλ‹€. μƒμ„±ν•œ Bean 을 등둝할 λ•ŒλŠ” @ComponentScan 을 μ΄μš©ν•˜κ±°λ‚˜ @Configuration 의 @Bean 을 μ‚¬μš©ν•˜μ—¬ Bean μ„€μ • νŒŒμΌμ— 직접 Bean 을 등둝할 수 μžˆλ‹€.

Bean 등둝 방법


@Component

@Controller
public class MemberController {
 
    private final MemberService memberService;
 
    @Autowired
    public MemberController(MemberService memberService) {
 
         this.memberService = memberService;
    }
}

Bean 으둜 λ“±λ‘ν•˜κ³ μž ν•˜λŠ” 클래슀 μ„ μ–ΈλΆ€ 상단에 @Component μ• λ„ˆν…Œμ΄μ…˜μ„ μΆ”κ°€ν•˜μ—¬ Bean 으둜 등둝할 수 μžˆλ‹€. 자주 μ‚¬μš©λ˜λŠ” @Controller @Service @Repository μ• λ„ˆν…Œμ΄μ…˜μ€ λͺ¨λ‘ @Component μ• λ„ˆν…Œμ΄μ…˜μ΄ ν¬ν•¨λ˜μ–΄ μžˆλ‹€. μŠ€ν”„λ§μ€ @ComponentScan 을 톡해 @Component μ• λ„ˆν…Œμ΄μ…˜μ΄ μ„ μ–Έλœ λͺ¨λ“  클래슀λ₯Ό μžλ™μœΌλ‘œ μŠ€μΊ”ν•œ λ’€ Singleton Bean 으둜 λ“±λ‘ν•œλ‹€.

@Bean

@Configuration
public class SpringConfig {
 
    @Bean
    public MemberService memberService() {
        return new MemberService(memberRepository());
    }
 
    @Bean
    public MemberRepository memberRepository() {
      return new MemoryMemberRepository();
    }
}

μ„€μ • 클래슀둜 μ‚¬μš©ν•  클래슀λ₯Ό μƒμ„±ν•˜κ³  μ„ μ–ΈλΆ€ 상단에 @Configuration μ• λ„ˆν…Œμ΄μ…˜μ„ μΆ”κ°€ν•˜μ—¬ Bean 섀정을 μœ„ν•œ ν΄λž˜μŠ€μž„μ„ λͺ…μ‹œν•œλ‹€. Bean 으둜 등둝할 클래슀λ₯Ό λ°˜ν™˜ν•˜λŠ” λ©”μ„œλ“œλ₯Ό λ§Œλ“€κ³  ν•΄λ‹Ή λ©”μ„œλ“œ 상단에 @Bean μ• λ„ˆν…Œμ΄μ…˜μ„ μΆ”κ°€ν•˜μ—¬ Singleton Bean 을 등둝할 수 μžˆλ‹€. 이 λ•Œ μƒμ„±λ˜λŠ” Bean 의 이름은 기본적으둜 λ©”μ„œλ“œλͺ…μœΌλ‘œ μ§€μ •λ˜λ©°, @Bean(name = "name") 을 톡해 직접 이름을 지정해쀄 수 도 μžˆλ‹€.

Bean Scope


Bean Scope λŠ” Bean 이 μ‘΄μž¬ν•  수 μžˆλŠ” λ²”μœ„λ₯Ό λœ»ν•˜λ©° Singleton Prototype Request Session Application 등이 μ‘΄μž¬ν•œλ‹€.

Singleton

  • Singleton 은 κΈ°λ³Έ Scope 둜 IoC μ»¨ν…Œμ΄λ„ˆμ˜ μ‹œμž‘κ³Ό μ’…λ£ŒκΉŒμ§€ μœ μ§€λ˜λŠ” κ°€μž₯ 넓은 λ²”μœ„μ˜ Scope λ‹€.

Prototype

  • Prototype 은 Bean 의 생성과 μ˜μ‘΄κ΄€κ³„ μ£Όμž…κΉŒμ§€λ§Œ κ΄€μ—¬ν•˜κ³  λ”λŠ” κ΄€λ¦¬ν•˜μ§€ μ•ŠλŠ” 맀우 짧은 λ²”μœ„μ˜ Scope λ‹€.

Request

  • Request λŠ” μ›Ή μš”μ²­μ΄ λ“€μ–΄μ˜€κ³  λ‚˜κ°ˆλ•Œ κΉŒμ§€ μœ μ§€ν•˜λŠ” Scope λ‹€.

Session

  • Session 은 μ›Ή μ„Έμ…˜ 생성뢀터 μ’…λ£ŒκΉŒμ§€ μœ μ§€ν•˜λŠ” Scope λ‹€.

Application

  • Application 은 WebServletContext 와 같은 λ²”μœ„λ‘œ μœ μ§€ν•˜λŠ” Scope λ‹€.

IoC


Inversion of Control, IoC λŠ” μ œμ–΄μ˜ μ—­μ „μœΌλ‘œ ν”„λ‘œκ·Έλž¨μ˜ 흐름을 직접 μ œμ–΄ν•˜λŠ” 것이 μ•„λ‹Œ μ™ΈλΆ€μ—μ„œ κ΄€λ¦¬ν•˜λŠ” 것이닀. 즉, μ½”λ“œμ˜ μ΅œμ’… ν˜ΈμΆœμ€ κ°œλ°œμžκ°€ μ œμ–΄ν•˜λŠ” 것이 μ•„λ‹Œ ν”„λ ˆμž„μ›Œν¬ λ‚΄λΆ€μ—μ„œ κ²°μ •λœ λŒ€λ‘œ μ΄λ£¨μ–΄μ§€λŠ” 것을 μ˜λ―Έν•œλ‹€. 객체의 μ˜μ‘΄μ„±μ„ μ—­μ „μ‹œν‚€λ©΄ 객체 κ°„μ˜ 결합도λ₯Ό 쀄이고 μœ μ—°ν•œ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆμ–΄ 가독성 및 μœ μ§€ λ³΄μˆ˜κ°€ νŽΈν•΄μ§„λ‹€λŠ” μž₯점이 μžˆλ‹€. μŠ€ν”„λ§μ€ λͺ¨λ“  객체λ₯Ό μŠ€ν”„λ§μ΄ 싀행될 λ•Œ λ§Œλ“€μ–΄λ†“κ³  ν•„μš”ν•œ 곳에 μ£Όμž…μ‹œμΌœ νŠΉμ • 객체λ₯Ό μ˜μ‘΄ν•˜λŠ” κ°μ²΄μ—μ„œ 의쑴 객체λ₯Ό μ‚¬μš©ν•  수 μžˆλ„λ‘ ν•œλ‹€.

IoC μ’…λ₯˜


DL

μ €μž₯μ†Œμ— μ €μž₯λ˜μ–΄ μžˆλŠ” Bean 에 μ ‘κ·Όν•˜κΈ° μœ„ν•΄ μ»¨ν…Œμ΄λ„ˆκ°€ μ œκ³΅ν•˜λŠ” API λ₯Ό 톡해 Bean 을 Lookup ν•˜λŠ” 것이닀. DL 은 μ»¨ν…Œμ΄λ„ˆ 쒅속이 μ¦κ°€ν•˜κΈ° λ•Œλ¬Έμ— 주둜 DI λ₯Ό μ‚¬μš©ν•œλ‹€.

DI

빈 μ„€μ • 정보λ₯Ό λ°”νƒ•μœΌλ‘œ 각 ν΄λž˜μŠ€κ°„μ˜ μ˜μ‘΄κ΄€κ³„λ₯Ό μ»¨ν…Œμ΄λ„ˆκ°€ μžλ™μœΌλ‘œ μ—°κ²°ν•΄μ€€λ‹€.

IoC Container


μΈμŠ€ν„΄μŠ€ 생성뢀터 μ†Œλ©ΈκΉŒμ§€ μΈμŠ€ν„΄μŠ€μ˜ 생λͺ…μ£ΌκΈ°λ₯Ό 관리해주기 λ•Œλ¬Έμ— κ°œλ°œμžλŠ” λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ—λ§Œ 집쀑할 수 μžˆλ‹€.

  • 객체의 생성을 μ±…μž„μ§€κ³  μ˜μ‘΄μ„±μ„ 관리
  • POJO 의 생성, μ΄ˆκΈ°ν™”, μ„œλΉ„μŠ€, μ†Œλ©Έμ— λŒ€ν•œ κΆŒλž€μ„ 가짐
  • κ°œλ°œμžλ“€μ΄ 직접 POJO λ₯Ό 생성할 수 μžˆμ§€λ§Œ μ»¨ν…Œμ΄λ„ˆμ—κ²Œ 맑김

IoC Container 의 μ—­ν• 

ApplicationContext λŠ” IoC Container 이며 Bean 을 μΈμŠ€ν„΄μŠ€ν™”ν•˜κ³  κ΅¬μ„±ν•˜κ³  μ‘°λ¦½ν•˜λŠ” 역할을 ν•œλ‹€. μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹€ν–‰ μ‹œμ μ— Bean 였브젝트λ₯Ό μΈμŠ€ν„΄μŠ€ν™”ν•˜κ³  DI ν•œ λ’€ 졜초둜 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ 가동할 Bean ν•˜λ‚˜λ₯Ό μ œκ³΅ν•œλ‹€.

IoC Container 의 μ’…λ₯˜

ApplicationContext λŠ” BeanFactory 의 μ„œλΈŒ μΈν„°νŽ˜μ΄μŠ€

BeanFactory

  • μ»¨ν…Œμ΄λ„ˆμ—μ„œ Bean 을 μƒμ„±ν•˜κ³  DI ν•˜λŠ” κΈ°λŠ₯을 제곡
  • Bean 등둝, 생성, 쑰회, λ°˜ν™˜μ„ 관리
  • νŒ©ν† λ¦¬ λ””μžμΈ νŒ¨ν„΄μ„ κ΅¬ν˜„ν•œ κ²ƒμœΌλ‘œ λΉˆμ„ μƒμ„±ν•˜κ³  λΆ„λ°°ν•˜λŠ” μ±…μž„μ„ 가짐
  • Bean 을 μ‘°νšŒν•  수 μžˆλŠ” getBean() λ©”μ„œλ“œκ°€ μ •μ˜λ˜μ–΄ 있음

ApplicationContext

  • BeanFactory 의 κΈ°λŠ₯에 더해 μŠ€ν”„λ§μ˜ 각쒅 λΆ€κ°€ κΈ°λŠ₯을 μΆ”κ°€λ‘œ 제곡
  • κ΅­μ œν™”κ°€ μ§€μ›λ˜λŠ” ν…μŠ€νŠΈ λ©”μ‹œμ§€λ₯Ό 관리
  • 이미지같은 파일 μžμ›μ„ λ‘œλ“œν•  수 μžˆλŠ” 포괄적인 방법 제곡
  • λ¦¬μŠ€λ„ˆλ‘œ λ“±λ‘λœ λΉˆμ—κ²Œ 이벀트 λ°œμƒμ„ μ•Œλ €μ€Œ

μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆ 생성


ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
  • ApplicationContext λ₯Ό μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆλΌκ³  ν•œλ‹€.
  • ApplicationContext λŠ” μΈν„°νŽ˜μ΄μŠ€μ΄λ‹€.
  • μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆλŠ” XML 기반으둜 λ§Œλ“€ 수 있고, μ–΄λ…Έν…Œμ΄μ…˜ 기반의 Java μ„€μ • 클래슀둜 λ§Œλ“€ 수 μžˆλ‹€.
  • AppConfig λ₯Ό μ‚¬μš©ν•œ 방식이 μ–΄λ…Έν…Œμ΄μ…˜ 기반의 Java μ„€μ • 클래슀둜 μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆλ₯Ό λ§Œλ“  것이닀.

μ»¨ν…Œμ΄λ„ˆμ— λ“±λ‘λœ λͺ¨λ“  빈 쑰회


@Test
@DisplayName("λͺ¨λ“  빈 좜λ ₯")
void findAllBean() {
    String[] beanDefinitionNames = ac.getBeanDefinitionNames();
    for (String beanDefinitionName : beanDefinitionNames) {
        Object bean = ac.getBean(beanDefinitionName);
        System.out.println("name = " + beanDefinitionName + " object = " + bean);
    }
}
@Test
@DisplayName("μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 빈 좜λ ₯")
void findApplicationBean() {
    String[] beanDefinitionNames = ac.getBeanDefinitionNames();
    for (String beanDefinitionName : beanDefinitionNames) {
        BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);
        // Role ROLE_APPLICATION: 직접 λ“±λ‘ν•œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 빈
        // Role ROLE_INFRASTRUCTURE: μŠ€ν”„λ§μ΄ λ‚΄λΆ€μ—μ„œ μ‚¬μš©ν•˜λŠ” 빈
        if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
            Object bean = ac.getBean(beanDefinitionName);
            System.out.println("name = " + beanDefinitionName + " object = " + bean);
        }
    }
}

μŠ€ν”„λ§ 빈 쑰회 - κΈ°λ³Έ


  • Spring Container μ—μ„œ Spring Bean 을 μ°ΎλŠ” κ°€μž₯ 기본적인 쑰회 방법
    • ac.getBean(λΉˆμ΄λ¦„, νƒ€μž…);
    • ac.getBean(νƒ€μž…);
  • 쑰회 λŒ€μƒμΈ Spring Bean 이 μ—†μœΌλ©΄ NoSuchBeanDefinitionException λ°œμƒ
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
@Test
@DisplayName("빈 μ΄λ¦„μœΌλ‘œ 쑰회")
void findBeanByName() {
    MemberService memberService = ac.getBean("memberService", MemberService.class);
    assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}
@Test
@DisplayName("빈 νƒ€μž…μœΌλ‘œ 쑰회")
void findBeanByType() {
    MemberService memberService = ac.getBean(MemberService.class);
    assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}
@Test
@DisplayName("ꡬ체 νƒ€μž…μœΌλ‘œ 쑰회")
void findBeanByExactType() {
    MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class);
    assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}
@Test
@DisplayName("μ—†λŠ” 빈 μ΄λ¦„μœΌλ‘œ 쑰회")
void findNotExistingBeanByName() {
    assertThatThrownBy(() -> ac.getBean("xxxx", MemberService.class))
            .isInstanceOf(NoSuchBeanDefinitionException.class);
}

μŠ€ν”„λ§ 빈 쑰회 - λ™μΌν•œ νƒ€μž…μ΄ λ‘˜ 이상


  • νƒ€μž…μœΌλ‘œ 쑰회 μ‹œ 같은 νƒ€μž…μ˜ μŠ€ν”„λ§ 빈이 λ‘˜ 이상이면 였λ₯˜κ°€ λ°œμƒν•œλ‹€. μ΄λ•ŒλŠ” 빈 이름을 지정.
  • ac.getBeansOfType() 을 μ‚¬μš©ν•˜λ©΄ ν•΄λ‹Ή νƒ€μž…μ˜ λͺ¨λ“  λΉˆμ„ μ‘°νšŒν•  수 μžˆλ‹€.
public class ApplicationContextSameBeanFindTest {
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SameBeanConfig.class);
    @Test
    @DisplayName("νƒ€μž…μœΌλ‘œ 쑰회 μ‹œ λ™μΌν•œ νƒ€μž…μ΄ λ‘˜ 이상 있으면 μ˜ˆμ™Έ λ°œμƒ")
    void findBeanByTypeDuplicate() {
        assertThatThrownBy(() -> ac.getBean(MemberRepository.class))
                .isInstanceOf(NoUniqueBeanDefinitionException.class);
    }
    @Test
    @DisplayName("νƒ€μž…μœΌλ‘œ 쑰회 μ‹œ λ™μΌν•œ νƒ€μž…μ΄ λ‘˜ 이상 있으면 빈 이름 지정")
    void findBeanByName() {
        MemberRepository memberRepository = ac.getBean("memberRepository", MemberRepository.class);
        assertThat(memberRepository).isInstanceOf(MemberRepository.class);
    }
    @Test
    @DisplayName("νŠΉμ • νƒ€μž… λͺ¨λ‘ μ‘°νšŒν•˜κΈ°")
    void findAllBeanByType() {
        Map<String, MemberRepository> beansOfType = ac.getBeansOfType(MemberRepository.class);
        for (String key : beansOfType.keySet()) {
            System.out.println("key = " + key + " value = " + beansOfType.get(key));
        }
        System.out.println("beansOfType = " + beansOfType);
        assertThat(beansOfType.size()).isEqualTo(2);
    }
    @Configuration
    static class SameBeanConfig {
        @Bean
        public MemberRepository memberRepository() {
            return new MemoryMemberRepository();
        }
        @Bean
        public MemberRepository memberRepository2() {
            return new MemoryMemberRepository();
        }
    }
}

μŠ€ν”„λ§ 빈 쑰회 - 상속 관계


  • λΆ€λͺ¨ νƒ€μž…μœΌλ‘œ μ‘°νšŒν•˜λ©΄, μžμ‹ νƒ€μž…λ„ ν•¨κ»˜ μ‘°νšŒν•œλ‹€.
  • κ·Έλž˜μ„œ λͺ¨λ“  μžλ°” 객체의 졜고 λΆ€λͺ¨μΈ Object νƒ€μž…μœΌλ‘œ μ‘°νšŒν•˜λ©΄ λͺ¨λ“  μŠ€ν”„λ§ λΉˆμ„ μ‘°νšŒν•œλ‹€.
public class ApplicationContextExtendsFindTest {
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
    @Test
    @DisplayName("λΆ€λͺ¨ νƒ€μž…μœΌλ‘œ 쑰회 μ‹œ μžμ‹μ΄ λ‘˜ 이상 있으면 μ˜ˆμ™Έ λ°œμƒ")
    void findBeanByParentTypeDuplicate() {
        assertThatThrownBy(() -> ac.getBean(DiscountPolicy.class))
                .isInstanceOf(NoUniqueBeanDefinitionException.class);
    }
    @Test
    @DisplayName("λΆ€λͺ¨ νƒ€μž…μœΌλ‘œ 쑰회 μ‹œ μžμ‹μ΄ λ‘˜ 이상 있으면 빈 이름 지정")
    void findBeanByParentTypeBeanName() {
        DiscountPolicy rateDiscountPolicy = ac.getBean("rateDiscountPolicy", DiscountPolicy.class);
        assertThat(rateDiscountPolicy).isInstanceOf(RateDiscountPolicy.class);
    }
    @Test
    @DisplayName("νŠΉμ • ν•˜μœ„ νƒ€μž…μœΌλ‘œ 쑰회")
    void findBeanBySubType() {
        DiscountPolicy rateDiscountPolicy = ac.getBean(RateDiscountPolicy.class);
        assertThat(rateDiscountPolicy).isInstanceOf(RateDiscountPolicy.class);
    }
    @Test
    @DisplayName("λΆ€λͺ¨ νƒ€μž…μœΌλ‘œ λͺ¨λ‘ 쑰회")
    void findAllByParentType() {
        Map<String, DiscountPolicy> beansOfType = ac.getBeansOfType(DiscountPolicy.class);
        assertThat(beansOfType.size()).isEqualTo(2);
    }
    @Test
    @DisplayName("λΆ€λͺ¨ νƒ€μž…μœΌλ‘œ λͺ¨λ‘ 쑰회 - Object")
    void findAllByObjectType() {
        Map<String, Object> beansOfType = ac.getBeansOfType(Object.class);
    }
    @Configuration
    static class TestConfig {
        @Bean
        public DiscountPolicy rateDiscountPolicy() {
            return new RateDiscountPolicy();
        }
        @Bean
        public DiscountPolicy fixDiscountPolicy() {
            return new FixDiscountPolicy();
        }
    }
}

BeanFactory 와 ApplicationContext


BeanFactory

  • μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆμ˜ μ΅œμƒμœ„ μΈν„°νŽ˜μ΄μŠ€
  • μŠ€ν”„λ§ λΉˆμ„ κ΄€λ¦¬ν•˜κ³  μ‘°νšŒν•˜λŠ” 역할을 λ‹΄λ‹Ή
  • getBean() 을 제곡

ApplicationContext

  • BeanFactory 의 κΈ°λŠ₯을 λͺ¨λ‘ μƒμ†λ°›μ•„μ„œ 제곡
  • μ• ν”Œλ¦¬μΌ€μ΄μ…˜ κ°œλ°œν•  λ•ŒλŠ” BeanFactory μ—μ„œ μ œκ³΅ν•˜λŠ” κΈ°λŠ₯ 외에도 λ§Žμ€ λΆ€κ°€κΈ°λŠ₯이 ν•„μš”

ApplicationContext κ°€ μ œκ³΅ν•˜λŠ” λΆ€κ°€κΈ°λŠ₯

  • λ©”μ‹œμ§€μ†ŒμŠ€λ₯Ό ν™œμš©ν•œ κ΅­μ œν™” κΈ°λŠ₯
    • ν•œκ΅­μ—μ„œ λ“€μ–΄μ˜€λ©΄ ν•œκ΅­μ–΄, μ˜μ–΄κΆŒμ—μ„œ λ“€μ–΄μ˜€λ©΄ μ˜μ–΄λ‘œ 좜λ ₯
  • ν™˜κ²½λ³€μˆ˜
    • 둜컬, 개발, μš΄μ˜λ“±μ„ κ΅¬λΆ„ν•΄μ„œ 처리
  • μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 이벀트
    • 이벀트λ₯Ό λ°œν–‰ν•˜κ³  κ΅¬λ…ν•˜λŠ” λͺ¨λΈμ„ νŽΈλ¦¬ν•˜κ²Œ 지원
  • νŽΈλ¦¬ν•œ λ¦¬μ†ŒμŠ€ 쑰회
    • 파일, 클래슀패슀, μ™ΈλΆ€ λ“±μ—μ„œ λ¦¬μ†ŒμŠ€λ₯Ό νŽΈλ¦¬ν•˜κ²Œ 쑰회

정리

  • ApplicationContext λŠ” BeanFactory 의 κΈ°λŠ₯을 μƒμ†λ°›λŠ”λ‹€.
  • ApplicationContext λŠ” 빈 관리 κΈ°λŠ₯ + νŽΈλ¦¬ν•œ λΆ€κ°€ κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€.
  • BeanFactory λ₯Ό 직접 μ‚¬μš©ν•  일은 거의 μ—†κ³ , ApplicationContext λ₯Ό μ‚¬μš©ν•œλ‹€.
  • BeanFactory λ‚˜ ApplicationContext λ₯Ό λͺ¨λ‘ μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆλΌκ³  ν•œλ‹€.

μŠ€ν”„λ§ 빈 μ„€μ • 메타 정보 - BeanDefinition


  • μŠ€ν”„λ§μ€ μ–΄λ–»κ²Œ 이런 λ‹€μ–‘ν•œ μ„€μ • ν˜•μ‹μ„ μ§€μ›ν•˜λŠ”κ°€?
  • κ·Έ μ€‘μ‹¬μ—λŠ” BeanDefinition μ΄λΌλŠ” 좔상화가 μžˆλ‹€.
    • XML, μžλ°” μ½”λ“œ 등이 BeanDefinition 으둜 λ§Œλ“€μ–΄μ§€λ©΄ μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆλŠ” BeanDefinition 만 μ•Œλ©΄λœλ‹€.
  • BeanDefinition 을 메타정보라 ν•œλ‹€.
    • @Bean <bean> λ‹Ή 각각 ν•˜λ‚˜μ”© 메타 정보가 μƒμ„±λœλ‹€.
  • μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆλŠ” 이 메타정보λ₯Ό 기반으둜 μŠ€ν”„λ§ λΉˆμ„ μƒμ„±ν•œλ‹€.
  • AnnotationConfigApplicationContext λŠ” AnnotatedBeanDefinitionReader λ₯Ό μ‚¬μš©ν•΄μ„œ AppConfig.class λ₯Ό 읽고 BeanDefinition 을 μƒμ„±ν•œλ‹€.

BeanDefinition

  • BeanClassName
  • factoryBeanName
  • factoryMethodName
  • Scope
  • lazyInit
  • InitMethodName
  • DestroyMethodName
  • Constructor arguments, Properties

정리

  • BeanDefinition 을 직접 μƒμ„±ν•΄μ„œ μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆμ— 등둝할 수 도 μžˆλ‹€.
  • ν•˜μ§€λ§Œ μ‹€λ¬΄μ—μ„œ BeanDefinition 을 직접 μ •μ˜ν•˜κ±°λ‚˜ μ‚¬μš©ν•  일은 거의 μ—†λ‹€.
  • BeanDefinition 에 λŒ€ν•΄μ„œ λ„ˆλ¬΄ 깊이있게 μ΄ν•΄ν•˜κΈ° 보단, μŠ€ν”„λ§μ΄ λ‹€μ–‘ν•œ ν˜•νƒœμ˜ μ„€μ • 정보λ₯Ό BeanDefinition 으둜 μΆ”μƒν™”ν•΄μ„œ μ‚¬μš©ν•œλ‹€λŠ” 것 μ •λ„λ§Œ μ΄ν•΄ν•˜λ©΄ λœλ‹€.
  • 가끔 μŠ€ν”„λ§ μ½”λ“œλ‚˜ μŠ€ν”„λ§ κ΄€λ ¨ μ˜€ν”ˆ μ†ŒμŠ€μ˜ μ½”λ“œλ₯Ό λ³Ό λ•Œ, BeanDefinition μ΄λΌλŠ” 것이 보일 λ•Œκ°€ μžˆλŠ”λ°, μ΄λ•Œ 이런 λ©”μ»€λ‹ˆμ¦˜μ„ λ– μ˜¬λ¦¬λ©΄ λœλ‹€.