복붙노트

[SPRING] Spring WebApplicationContext에서 런타임시 빈 인스턴스를 추가하는 방법은?

SPRING

Spring WebApplicationContext에서 런타임시 빈 인스턴스를 추가하는 방법은?

제목은 매우 간단합니다. 나는 봄에 의해 제공되는 BeanDefinitionRegistryPostProcessor 인터페이스를 구현하는 동적 클래스 인 DynamicBeanHandler를 가지고있다. 이 클래스에서는 bean 클래스가 MyDynamicBean으로 설정된 여러 SCOPE_SINGLETON 빈을 다음과 같이 추가합니다.

GenericBeanDefinition myBeanDefinition = new GenericBeanDefinition();
myBeanDefinition.setBeanClass(MyDynamicBean.class);
myBeanDefinition.setScope(SCOPE_SINGLETON);
myBeanDefinition.setPropertyValues(getMutableProperties(dynamicPropertyPrefix));
registry.registerBeanDefinition(dynamicBeanId, myBeanDefinition);

getMutableProperties () 메소드는 MutablePropertyValues의 오브젝트를 리턴합니다.

나중에 SpringUtil 클래스가 ApplicationContextAware를 구현하는 곳에서 필요한 MyDynamicBean 인스턴스를 가져 오기 위해 SpringUtil.getBean (dynamicBeanId)을 수행합니다. 이 모든 것이 훌륭하게 작동합니다. 문제는 이러한 인스턴스 중 하나를 제거하고 나중에 레지스트리 인스턴스가없는 곳에 새 인스턴스를 추가하려고 할 때 발생합니다. 누구든지이 일을 할 수있는 방법을 찾도록 도와 줄 수 있습니까?

다음은 SpringUtil 클래스의 코드입니다.

public class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringUtil.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static Object getBean(String beanId) {
        return applicationContext.getBean(beanId);
    }

    public static <T> T getBean(String beanId, Class<T> beanClass) {
        return applicationContext.getBean(beanId, beanClass);
    }
}

해결법

  1. ==============================

    1.빈을 동적으로 제거하거나 등록하려면 BeanDefinitionRegistry (여기 API 참조)를 사용할 수 있습니다.

    빈을 동적으로 제거하거나 등록하려면 BeanDefinitionRegistry (여기 API 참조)를 사용할 수 있습니다.

    따라서 SpringUtil 클래스에서 removeBeanDefinition ()을 사용하여 기존 bean 정의를 제거하고 registerBeanDefinition ()을 사용하여 새 bean 정의를 추가하려면 아래 메소드를 추가 할 수 있습니다.

    public void removeExistingAndAddNewBean(String beanId) {
    
       AutowireCapableBeanFactory factory = 
                       applicationContext.getAutowireCapableBeanFactory();
       BeanDefinitionRegistry registry = (BeanDefinitionRegistry) factory;
       registry.removeBeanDefinition(beanId);
    
        //create newBeanObj through GenericBeanDefinition
    
        registry.registerBeanDefinition(beanId, newBeanObj);
    }
    
  2. from https://stackoverflow.com/questions/43051394/how-to-add-bean-instance-at-runtime-in-spring-webapplicationcontext by cc-by-sa and MIT license