만약 클라이언트 코드가 스프링 컨테이너에 의해 관리되지 않는 오브젝트를 등록해야 한다면 BeanDefinition을 사용해야 한다.
스프링은 BeanDefinitionRegistry의 메서드를 사용함으로써 BeanDefinition을 등록한다.
BeanDefinitionRegistry (Spring Framework 5.2.4.RELEASE API)
Interface for registries that hold bean definitions, for example RootBeanDefinition and ChildBeanDefinition instances. Typically implemented by BeanFactories that internally work with the AbstractBeanDefinition hierarchy. This is the only interface in Spri
docs.spring.io
BeanDefinition
BeanDefinition은 빈의 인스턴스에 대한 정보를 담고 있다.
해당 인터페이스는 setter 메서드를 가지고 있다. scope을 지정하는 setter를 예로 들 수 있다.
void setScope(@Nullable String scope);
GenericBeanDefinition
GenericBeanDefinition은 일반적으로 사용되는 BeanDefinition의 구현체이다.
Bean 클래스, Bean의 특징 생성자의 인자 값 및 property 값을 지정할 수 있다.
GenericBeanDefinition의 사용
public class GenericBeanDefinitionExample {
public static void main(String[] args) {
DefaultListableBeanFactory context = new DefaultListableBeanFactory();
GenericBeanDefinition gbd = new GenericBeanDefinition();
gbd.setBeanClass(MyBean.class);
MutablePropertyValues mpv = new MutablePropertyValues();
mpv.add("date", new Date());
gbd.setPropertyValues(mpv);
context.registerBeanDefinition("myBeanName", gbd);
MyBean bean = context.getBean(MyBean.class);
bean.doSomething();
}
}
다른 Bean을 참조로 주입
public class MyBean {
private OtherBean otherBean;
public void setOtherBean(OtherBean otherBean) {
this.otherBean = otherBean;
}
public void doSomething() {
otherBean.doSomething();
}
}
public class InjectionOtherBean {
public static void main(String[] args) {
DefaultListableBeanFactory context = new DefaultListableBeanFactory();
/*************************OtherBean Class*************************/
GenericBeanDefinition gbd = new GenericBeanDefinition();
gbd.setBeanClass(OtherBean.class);
context.registerBeanDefinition("other", gbd);
/*************************OtherBean Class*************************/
/*************************MyBean Class*************************/
GenericBeanDefinition gbd2 = new GenericBeanDefinition();
gbd2.setBeanClass(MyBean.class);
MutablePropertyValues mpv = new MutablePropertyValues();
mpv.addPropertyValue("otherBean", context.getBean("other"));
gbd2.setPropertyValues(mpv);
context.registerBeanDefinition("myBean", gbd2);
/*************************MyBean Class*************************/
MyBean bean = context.getBean(MyBean.class);
bean.doSomething();
}
}
BeanFactoryPostProcessor의 사용
BeanFactoryPostProcessor는 클라이언트 코드가 bean definition을 커스터마이징 하게끔 할 수 있도록 도와준다.
BeanFactoryPostProcessor의 postProcessBeanFactory 메서드는 모든 definition들이 로드된 이후에 스프링의 startup 프로세스에 의해 호출된다.
하지만 어떠한 빈도 아직 초기화되지는 않은 상태이다.
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
예시코드
public class MyConfigBean implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
GenericBeanDefinition gbd = new GenericBeanDefinition();
gbd.setBeanClass(MyBean.class);
gbd.getPropertyValues().add("strProp", "my string property");
((DefaultListableBeanFactory)beanFactory).registerBeanDefinition("myBeanName", gbd);
}
}
@Configuration
public class MyConfig {
@Bean
MyConfigBean myConfigBean() {
return new MyConfigBean();
}
}
public class MyConfigBean implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
GenericBeanDefinition gbd = new GenericBeanDefinition();
gbd.setBeanClass(MyBean.class);
gbd.getPropertyValues().add("strProp", "my string property");
((DefaultListableBeanFactory)beanFactory).registerBeanDefinition("myBeanName", gbd);
}
}
Code Link
https://github.com/mike6321/Spring/tree/master/SpringBoot/demoapplicationcontextexercise
mike6321/Spring
Contribute to mike6321/Spring development by creating an account on GitHub.
github.com
'Spring > Spring' 카테고리의 다른 글
(SPRING) cglib에 대해서 (with Enhancer) (0) | 2020.04.04 |
---|---|
(SPRING) getBean()에 대해서 (0) | 2020.03.23 |
(SPRING) 빈의 스코프 (0) | 2020.03.22 |
(SPRING) Spring ApplicationContext의 내부 (2) (0) | 2020.03.01 |
(SPRING) Spring ApplicationContext의 내부 (1) (1) | 2020.03.01 |