
BeanDefinition 이라는 개념은 Bean을 정의한 것.
즉, 우리가 앞서 grooby, java, xml로 SpringContainer를 만들 수 있었는데 이는 BeanDefinition이라는 추상화가 있기에 가능했던 것이다.
그래서 우리는 BeanDefinition을 빈 설정 메타 정보라고 한다.
이말은 @Bean 혹은 <bean>에 각각 하나씩 메타 정보가 생성된다는 것이다.


AnnotationConfigApplicationContext는 AnnotatedBeanDefinitionReader를 사용해서 AppConfig.class를 읽고 BeanDefinition을 생성한다.
GenericXmlApplicationContext는 XmlBeanDefinitionReader를 사용해서 appConfig.xml 설정 정보를 읽고 BeanDefinition을 생성한다.
새로운 형식의 설정 정보가 추가되면, XxxBeanDefinitionReader를 만들어서 BeanDefinition을 생성하면 된다.
이는 BeanDefinition을 직접 생성해서 스프링 컨테이너에 등록할 수 있다. => 실무에서 거의 X
스프링이 다양한 형태의 설정 정보를 BeanDefinition으로 추상화 해서 사용하는것으로 이해하면 된다.


public class BeanDefinitionExample {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// BeanDefinition 생성
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MyBean.class)
.setScope(BeanDefinition.SCOPE_SINGLETON) // 범위 설정 (singleton)
.setLazyInit(true) // 지연 초기화 설정
.addPropertyValue("name", "Spring Bean") // 프로퍼티 값 설정
.setInitMethodName("init") // 초기화 메서드 설정
.setDestroyMethodName("destroy") // 소멸 메서드 설정
.getBeanDefinition();
// BeanDefinition 등록
context.registerBeanDefinition("myBean", beanDefinition);
// 컨텍스트 초기화
context.refresh();
// Bean 사용
MyBean myBean = context.getBean("myBean", MyBean.class);
System.out.println(myBean.getName());
// 컨텍스트 종료
context.close();
}
public static class MyBean {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
// 초기화 메서드
public void init() {
System.out.println("Bean is being initialized");
}
// 소멸 메서드
public void destroy() {
System.out.println("Bean is being destroyed");
}
}
}