1. 程式人生 > >Spring運行時動態註冊bean

Spring運行時動態註冊bean

factory context 創建 contex ner 註入 ref 刪除 定義

在spring運行時,動態的添加bean,dapeng框架在解析xml的字段時,使用到了動態註冊,註冊了一個實現了FactoryBean類!


定義一個沒有被Spring管理的Controller
public class UserController implements InitializingBean{

    private UserService userService;

    public UserService getUserService() {
        return userService;
    }

    public void setUserService
(UserService userService) { this.userService = userService; } @Override public void afterPropertiesSet() throws Exception { System.out.println("我是動態註冊的你,不是容器啟動的時候註冊的你"); } public String toAction(String content){ return "-->" + userService.doService
(content); } }
需要註意的是,如果要註入UserService,需要提供它的getter和setter方法
現在啟動springboot工程,顯而易見這個類是不會被Spring管理的,接下來我們定義一個獲取Spring上下文的工具類,如下
工具類
public class SpringContextUtil {
    private static ApplicationContext applicationContext;
    //獲取上下文
    public static ApplicationContext getApplicationContext() {
        return
applicationContext; } //設置上下文 public static void setApplicationContext(ApplicationContext applicationContext) { SpringContextUtil.applicationContext = applicationContext; } //通過名字獲取上下文中的bean public static Object getBean(String name){ return applicationContext.getBean(name); } //通過類型獲取上下文中的bean public static Object getBean(Class<?> requiredType){ return applicationContext.getBean(requiredType); } }
我們在Springboot的啟動類中,保存當前Spring上下文,代碼如下:
@SpringBootApplication
public class HelloApplication {

    public static void main(String[] args) {
        ApplicationContext app = SpringApplication.run(HelloApplication.class, args);
        SpringContextUtil.setApplicationContext(app);
    }
    
}
然後我們在另一個被Spring管理的容器中,寫如下方法,進行bean的動態註冊
@GetMapping("/bean")
public String registerBean() {
    //將applicationContext轉換為ConfigurableApplicationContext
    ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) SpringContextUtil.getApplicationContext();

    // 獲取bean工廠並轉換為DefaultListableBeanFactory
    DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory();

    // 通過BeanDefinitionBuilder創建bean定義
    BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UserController.class);
        
    // 設置屬性userService,此屬性引用已經定義的bean:userService,這裏userService已經被spring容器管理了.
    beanDefinitionBuilder.addPropertyReference("userService", "userService");

    // 註冊bean
    defaultListableBeanFactory.registerBeanDefinition("userController", beanDefinitionBuilder.getRawBeanDefinition());


    UserController userController = (UserController) SpringContextUtil.getBean("userController");

    return userController.toAction("動態註冊生成調用");

     //刪除bean.
    //defaultListableBeanFactory.removeBeanDefinition("testService");

}
    
如上,就能動態的註冊bean

Spring運行時動態註冊bean