動(dòng)態(tài)注冊(cè)bean的兩種api
Spring中的bean定義都保存在 BeanDefinitionRegistry 接口中车猬,單例的bean的實(shí)例都保存在 SingletonBeanRegistry 接口中讥脐。
因此動(dòng)態(tài)注冊(cè)bean也分為了兩種方式:
使用BeanDefinitionRegistry接口的
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException
方法使用SingletonBeanRegistry接口的
void registerSingleton(String beanName, Object singletonObject)
方法
兩者區(qū)別在于使用前者時(shí),Spring容器會(huì)根據(jù)BeanDefinition實(shí)例化bean實(shí)例透揣,而使用后者時(shí),bean實(shí)例就是傳遞給registerSingleton方法的對(duì)象。
這里DefaultListableBeanFactory接口同時(shí)實(shí)現(xiàn)了這兩個(gè)接口挟裂,在實(shí)踐中通常會(huì)使用這個(gè)接口。
注意
我們可以在任何獲得了BeanDefinitionRegistry或者SingletonBeanRegistry實(shí)例的地方進(jìn)行動(dòng)態(tài)注冊(cè)割岛。
但是如果bean不是在BeanFactoryPostProcessor中被注冊(cè)愉适,那么該bean則無法被BeanPostProcessor處理,即無法對(duì)其應(yīng)用aop癣漆、Bean Validation等功能(因?yàn)镮OC中綁定AOP發(fā)生在BeanPostProcessor的Spring生命周期方法里)维咸。
在BeanFactoryPostProcessor中進(jìn)行動(dòng)態(tài)注冊(cè)
public class PersonBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
DefaultListableBeanFactory defaultListableBeanFactory
= (DefaultListableBeanFactory) beanFactory;
//注冊(cè)Bean定義,容器根據(jù)定義返回bean
log.info("register personManager1>>>>>>>>>>>>>>>>");
BeanDefinitionBuilder beanDefinitionBuilder =
BeanDefinitionBuilder.genericBeanDefinition(PersonManager.class);
beanDefinitionBuilder.addPropertyReference("personDao", "personDao");
BeanDefinition personManagerBeanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
defaultListableBeanFactory.registerBeanDefinition("personManager1", personManagerBeanDefinition);
//注冊(cè)bean實(shí)例
log.info("register personManager2>>>>>>>>>>>>>>>>");
PersonDao personDao = beanFactory.getBean(PersonDao.class);
PersonManager personManager = new PersonManager();
personManager.setPersonDao(personDao);
beanFactory.registerSingleton("personManager2", personManager);
}
}
在普通bean中注冊(cè)
@RestController
@Slf4j
public class PersonManagerRegisterController {
/**
* The Application context.
*/
@Autowired
GenericApplicationContext applicationContext;
/**
* The Bean factory.
*/
@Autowired
ConfigurableBeanFactory beanFactory;
/**
* 動(dòng)態(tài)注冊(cè)bean惠爽,此處注冊(cè)的bean沒有AOP的支持
*/
@GetMapping("/registerPersonManager")
public void registerPersonManager() {
PersonDao personDao = applicationContext.getBean(PersonDao.class);
PersonManager personManager = new PersonManager();
personManager.setPersonDao(personDao);
beanFactory.registerSingleton("personManager3", personManager);
}