spring:如何用代码动态向容器中添加或移除Bean ?
先来看一张类图:
有一个业务接口IFoo,提供了二个实现类:FooA及FooB,默认情况下,FooA使用@Component由Spring自动装配,如果出于某种原因,在运行时需要将IFoo的实现,则FooA换成FooB,可以用代码动态先将FooA的实例从容器中删除,然后再向容器中注入FooB的实例,代码如下:
1、IFoo接口:
package yjmyzz;import org.springframework.beans.factory.DisposableBean;public interface IFoo extends DisposableBean {public void foo();
}
2、 FooA实现
package yjmyzz;import org.springframework.stereotype.Component;//注:这里的名称fooA,仅仅只是为了后面演示时看得更清楚,非必需
@Component("fooA")
public class FooA implements IFoo {public FooA() {System.out.println("FooA is created!");}public void foo() {System.out.println("FooA.foo()");}public void destroy() throws Exception {System.out.println("FooA.destroy()");}
}
3、FooB实现
package yjmyzz;public class FooB implements IFoo {public FooB() {System.out.println("FooB is created!");}public void foo() {System.out.println("FooB.foo()");}public void destroy() throws Exception {System.out.println("FooB.destroy()");}
}
4、测试程序AppDemo
package yjmyzz;import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.support.AbstractRefreshableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** 演示在运行时,动态向容器中添加、移除Bean* author:菩提树下的杨过 http://yjmyzz.cnblogs.cm/*/
public class AppDemo {public static void main(String[] args) {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");//从context中取出FooA实例IFoo f = ctx.getBean(IFoo.class);f.foo();//FooA.foo()//输出IFoo的Bean基本信息System.out.println(f.getClass());//class yjmyzz.FooAString beanName = ctx.getBeanNamesForType(IFoo.class)[0];System.out.println(beanName);//fooASystem.out.println(ctx.isSingleton(beanName));//true//销毁FooA实例removeBean(ctx, beanName);System.out.println(ctx.containsBean(beanName));//falseSystem.out.println("------------");//注入新BeanbeanName = "fooB";addBean(ctx, beanName, FooB.class);//取出新实例f = ctx.getBean(beanName, IFoo.class);f.foo();//输出IFoo的Bean基本信息System.out.println(f.getClass());beanName = ctx.getBeanNamesForType(IFoo.class)[0];System.out.println(beanName);//fooBSystem.out.println(ctx.isSingleton(beanName));//trueSystem.out.println("------------");showAllBeans(ctx);ctx.close();}/*** 向容器中动态添加Bean** @param ctx* @param beanName* @param beanClass*/static void addBean(AbstractRefreshableApplicationContext ctx, String beanName, Class beanClass) {BeanDefinitionRegistry beanDefReg = (DefaultListableBeanFactory) ctx.getBeanFactory();BeanDefinitionBuilder beanDefBuilder = BeanDefinitionBuilder.genericBeanDefinition(beanClass);BeanDefinition beanDef = beanDefBuilder.getBeanDefinition();if (!beanDefReg.containsBeanDefinition(beanName)) {beanDefReg.registerBeanDefinition(beanName, beanDef);}}/*** 从容器中移除Bean** @param ctx* @param beanName*/static void removeBean(AbstractRefreshableApplicationContext ctx, String beanName) {BeanDefinitionRegistry beanDefReg = (DefaultListableBeanFactory) ctx.getBeanFactory();beanDefReg.getBeanDefinition(beanName);beanDefReg.removeBeanDefinition(beanName);}/*** 遍历输出所有Bean的信息*/static void showAllBeans(AbstractRefreshableApplicationContext ctx) {//遍历for (String name : ctx.getBeanDefinitionNames()) {System.out.println("name:" + name + ",class:" + ctx.getBean(name).getClass());}}
}
beans.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="yjmyzz" /></beans>
View Code
输出:
FooA is created!
FooA.foo()
class yjmyzz.FooA
fooA
true
FooA.destroy()
false
------------
FooB is created!
FooB.foo()
class yjmyzz.FooB
fooB
true
------------
name:org.springframework.context.annotation.internalConfigurationAnnotationProcessor,class:class org.springframework.context.annotation.ConfigurationClassPostProcessor
name:org.springframework.context.annotation.internalAutowiredAnnotationProcessor,class:class org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
name:org.springframework.context.annotation.internalRequiredAnnotationProcessor,class:class org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor
name:org.springframework.context.annotation.internalCommonAnnotationProcessor,class:class org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
name:org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,class:class org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor
name:org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor,class:class org.springframework.context.annotation.ConfigurationClassPostProcessor$EnhancedConfigurationBeanPostProcessor
name:fooB,class:class yjmyzz.FooB
FooB.destroy()
spring:如何用代码动态向容器中添加或移除Bean ?相关推荐
- 六、spring之通过FactoryBean为ioc容器中添加组件
前面我们已经介绍了几种为容器中添加组件的方法,今天一起学习通过FactoryBean添加组件的方法. 首先我们准备一个类,也就是我们需要注册进spring的ioc容器中的类 类Color: // 不必 ...
- Spring中将BeanDefinition注册到IOC容器中
Spring中将BeanDefinition注册到IOC容器中 XML配置元信息 <bean name="-" - /> 注解: @Bean,@Component,@I ...
- java servlet 部署到tomcat_如何把spring boot项目部署到tomcat容器中
把spring-boot项目按照平常的web项目一样发布到tomcat容器下 一.修改打包形式 在pom.xml里设置 war 二.移除嵌入式tomcat插件 在pom.xml里找到spring-bo ...
- spring——手动往spring容器中添加对象
有时候,我们希望可以手动动态的往spring容器中添加对象,而不是必须要项目启动时就决定容器中有哪些对象,对于这种情况,spring提供了一种方式,DefaultListableBeanFac ...
- 头条一面:Spring IOC容器中只存放单例Bean吗?
最近,很多小伙伴出去面试,感觉自己面的不是很理想,回来后,不少小伙伴把面试题做了记录发给我,让我给大家解析下,然后发出来.当我看到这些面试题时,快速在脑海中构建起了整个知识体系,从基础到框架.从分布式 ...
- java se 动态添加视图组件_博为峰Java技术题 ——JavaSE Java Swing在顶层容器中添加菜单栏Ⅰ...
下面将讲述如何在顶层容器中添加菜单栏.下面将通过编写一段Swing程序代码来讲解如何在顶层容器中添加菜单栏.其代码如下: publicclassBWFSwingMenu { staticintwidt ...
- ajax异步获取数据后动态向表格中添加数据的页面
因为某些原因,项目中突然需要做自己做个ajax异步获取数据后动态向表格中添加数据的页面,网上找了半天都没有 看到现成的,决定自己写个例子 1.HTML页面 [html] view plaincopyp ...
- ajax异步获取数据后动态向表格中添加数据(行)
因为某些原因,项目中突然需要做自己做个ajax异步获取数据后动态向表格中添加数据的页面,网上找了半天都没有 看到现成的,决定自己写个例子 1.HTML页面 [html] view plaincopyp ...
- 如何:在 Visual Studio 中添加或移除引用(转载)
http://msdn2.microsoft.com/zh-cn/library/wkze6zky(VS.80).aspx Visual Studio 如何:在 Visual Studio 中添加或移 ...
最新文章
- ABP官方文档翻译 9.2 Entity Framework Core
- 几种在shell命令行中过滤adb logcat输出的方法
- 常见的排序算法二——希尔排序
- 前端开发 做一个新闻列表
- Solaris11 磁盘分区
- 原价19万的美系插混,2年后落地只要11万~15万,微蓝6 PHEV为啥这么惨
- spring源码解析(一)---占位符解析替换
- PlaySound error
- 英语流利说 level4 unti2 part1-extinction events 1
- Bean Validation
- 关于timestamp时间范围
- 领导说“辛苦啦”,下属怎么回答?这三种话术,给你职场加分
- 《回眸2022·圆满收官||展望2023·砥砺奋发》
- android高德地图marker图标,高德地图自定义Marker显示文字
- C++ std::set<>是什么 怎么用 遍历
- GIS理论知识(六)之底图数据的来源
- 观察者模式——应聘者和应聘公司的关系
- openc 图片旋转 ;OpenCvSharp 图片旋转
- 微信小游戏云开发数据库
- linux官方桌面大图,Ubuntu 19.04官方壁纸揭晓
热门文章
- 安卓常用功能——已封装好
- C++ 创建一个窗口
- Windows核心编程 第六章 线程基础知识 (上)
- 【Java 并发编程】线程指令重排序问题 ( 指令重排序规范 | volatile 关键字禁止指令重排序 )
- 【鸿蒙 HarmonyOS】UI 组件 ( Text 组件 )
- lava.lang.String数据转换为java.sql.Date
- python 3.5(socket)
- C指针笔试题,蛋疼的多重指针运算,谭浩强的阴影
- 【读书笔记】《第一行代码》
- 2016-8-18晨型养成第三天