Spring動態注入Bean


動態注冊bean的兩種api

Spring中的bean定義都保存在 BeanDefinitionRegistry 接口中,單例的bean的實例都保存在 SingletonBeanRegistry 接口中。

因此動態注冊bean也分為了兩種方式:

  1. 使用BeanDefinitionRegistry接口的void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException方法

  2. 使用SingletonBeanRegistry接口的void registerSingleton(String beanName, Object singletonObject)方法

兩者區別在於使用前者時,Spring容器會根據BeanDefinition實例化bean實例,而使用后者時,bean實例就是傳遞給registerSingleton方法的對象。

這里DefaultListableBeanFactory接口同時實現了這兩個接口,在實踐中通常會使用這個接口。

注意

我們可以在任何獲得了BeanDefinitionRegistry或者SingletonBeanRegistry實例的地方進行動態注冊。

但是如果bean不是在BeanFactoryPostProcessor中被注冊,那么該bean則無法被BeanPostProcessor處理,即無法對其應用aop、Bean Validation等功能(因為IOC中綁定AOP發生在BeanPostProcessor的Spring生命周期方法里)。

BeanFactoryPostProcessor中進行動態注冊
public class PersonBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        DefaultListableBeanFactory defaultListableBeanFactory
                = (DefaultListableBeanFactory) beanFactory;

        //注冊Bean定義,容器根據定義返回bean
        log.info("register personManager1>>>>>>>>>>>>>>>>");
        BeanDefinitionBuilder beanDefinitionBuilder =
                BeanDefinitionBuilder.genericBeanDefinition(PersonManager.class);
        beanDefinitionBuilder.addPropertyReference("personDao", "personDao");
        BeanDefinition personManagerBeanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
        defaultListableBeanFactory.registerBeanDefinition("personManager1", personManagerBeanDefinition);

        //注冊bean實例
        log.info("register personManager2>>>>>>>>>>>>>>>>");
        PersonDao personDao = beanFactory.getBean(PersonDao.class);
        PersonManager personManager = new PersonManager();
        personManager.setPersonDao(personDao);
        beanFactory.registerSingleton("personManager2", personManager);

    }
}

在普通bean中注冊

@RestController
@Slf4j
public class PersonManagerRegisterController {

    /**
     * The Application context.
     */
    @Autowired
    GenericApplicationContext applicationContext;

    /**
     * The Bean factory.
     */
    @Autowired
    ConfigurableBeanFactory beanFactory;

    /**
     * 動態注冊bean,此處注冊的bean沒有AOP的支持
     */
    @GetMapping("/registerPersonManager")
    public void registerPersonManager() {
        PersonDao personDao = applicationContext.getBean(PersonDao.class);
        PersonManager personManager = new PersonManager();
        personManager.setPersonDao(personDao);
        beanFactory.registerSingleton("personManager3", personManager);
    }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM