Spring Boot動態注入刪除bean
概述
- 因為如果采用配置文件或者注解,我們要加入對象的話,還要重啟服務,如果我們想要避免這一情況就得采用動態處理bean,包括:動態注入,動態刪除。
動態注入bean思路
-
在具體進行代碼實現的時候,我們要知道,Spring管理bean的對象是BeanFactory,具體的是DefaultListableBeanFactory,在這個類當中有一個注入bean的方法:registerBeanDefinition,在調用registerBeanDefinition方法時,需要BeanDefinition參數,那么這個參數怎么獲取呢?Spring提供了BeanDefinitionBuilder可以構建一個BeanDefinition,那么我們的問題就是如何獲取BeanFactory了,這個就很簡單了,只要獲取到ApplicationContext對象即可獲取到BeanFacory了
-
流程
<1>. 獲取ApplicationContext;
<2>. 通過ApplicationContext獲取到BeanFacotory;
<3>. 通過BeanDefinitionBuilder構建BeanDefiniton;
<4>. 調用beanFactory的registerBeanDefinition注入beanDefinition;
<5>. 使用ApplicationContext.getBean獲取bean進行測試;
動態注入實現代碼
// 測試類
package com.kfit.demo.service;
public class TestService {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void print(){
System.out.println("動態載入bean,name="+name);
}
}
// 獲取context
ApplicationContext ctx = (ApplicationContext) SpringApplication.run(App.class, args);
//獲取BeanFactory
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) ctx.getAutowireCapableBeanFactory();
//創建bean信息.
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(TestService.class);
beanDefinitionBuilder.addPropertyValue("name","張三");
//動態注冊bean.
defaultListableBeanFactory.registerBeanDefinition("testService", beanDefinitionBuilder.getBeanDefinition());
//獲取動態注冊的bean.
TestService testService =ctx.getBean(TestService.class);、testService.print();
// 動態刪除
defaultListableBeanFactory.removeBeanDefinition("testService");
多次注入同一個bean的情況
- 多次注入同一個bean的,如果beanName不一樣的話,那么會產生兩個Bean;如果beanName一樣的話,后面注入的會覆蓋前面的。
- 第二種情況的時候,用beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(TestService.class); 獲取bean會報錯,因為在getBean的時候,找到了兩個bean,這時候就不知道要獲取哪個了,可以用TestService testService=ctx.getBean("testService") 來獲取