先来看一张类图:

有一个业务接口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 ?相关推荐

  1. 六、spring之通过FactoryBean为ioc容器中添加组件

    前面我们已经介绍了几种为容器中添加组件的方法,今天一起学习通过FactoryBean添加组件的方法. 首先我们准备一个类,也就是我们需要注册进spring的ioc容器中的类 类Color: // 不必 ...

  2. Spring中将BeanDefinition注册到IOC容器中

    Spring中将BeanDefinition注册到IOC容器中 XML配置元信息 <bean name="-" - /> 注解: @Bean,@Component,@I ...

  3. java servlet 部署到tomcat_如何把spring boot项目部署到tomcat容器中

    把spring-boot项目按照平常的web项目一样发布到tomcat容器下 一.修改打包形式 在pom.xml里设置 war 二.移除嵌入式tomcat插件 在pom.xml里找到spring-bo ...

  4. spring——手动往spring容器中添加对象

        有时候,我们希望可以手动动态的往spring容器中添加对象,而不是必须要项目启动时就决定容器中有哪些对象,对于这种情况,spring提供了一种方式,DefaultListableBeanFac ...

  5. 头条一面:Spring IOC容器中只存放单例Bean吗?

    最近,很多小伙伴出去面试,感觉自己面的不是很理想,回来后,不少小伙伴把面试题做了记录发给我,让我给大家解析下,然后发出来.当我看到这些面试题时,快速在脑海中构建起了整个知识体系,从基础到框架.从分布式 ...

  6. java se 动态添加视图组件_博为峰Java技术题 ——JavaSE Java Swing在顶层容器中添加菜单栏Ⅰ...

    下面将讲述如何在顶层容器中添加菜单栏.下面将通过编写一段Swing程序代码来讲解如何在顶层容器中添加菜单栏.其代码如下: publicclassBWFSwingMenu { staticintwidt ...

  7. ajax异步获取数据后动态向表格中添加数据的页面

    因为某些原因,项目中突然需要做自己做个ajax异步获取数据后动态向表格中添加数据的页面,网上找了半天都没有 看到现成的,决定自己写个例子 1.HTML页面 [html] view plaincopyp ...

  8. ajax异步获取数据后动态向表格中添加数据(行)

    因为某些原因,项目中突然需要做自己做个ajax异步获取数据后动态向表格中添加数据的页面,网上找了半天都没有 看到现成的,决定自己写个例子 1.HTML页面 [html] view plaincopyp ...

  9. 如何:在 Visual Studio 中添加或移除引用(转载)

    http://msdn2.microsoft.com/zh-cn/library/wkze6zky(VS.80).aspx Visual Studio 如何:在 Visual Studio 中添加或移 ...

最新文章

  1. ABP官方文档翻译 9.2 Entity Framework Core
  2. 几种在shell命令行中过滤adb logcat输出的方法
  3. 常见的排序算法二——希尔排序
  4. 前端开发 做一个新闻列表
  5. Solaris11 磁盘分区
  6. 原价19万的美系插混,2年后落地只要11万~15万,微蓝6 PHEV为啥这么惨
  7. spring源码解析(一)---占位符解析替换
  8. PlaySound error
  9. 英语流利说 level4 unti2 part1-extinction events 1
  10. Bean Validation
  11. 关于timestamp时间范围
  12. 领导说“辛苦啦”,下属怎么回答?这三种话术,给你职场加分
  13. 《回眸2022·圆满收官||展望2023·砥砺奋发》
  14. android高德地图marker图标,高德地图自定义Marker显示文字
  15. C++ std::set<>是什么 怎么用 遍历
  16. GIS理论知识(六)之底图数据的来源
  17. 观察者模式——应聘者和应聘公司的关系
  18. openc 图片旋转 ;OpenCvSharp 图片旋转
  19. 微信小游戏云开发数据库
  20. linux官方桌面大图,Ubuntu 19.04官方壁纸揭晓

热门文章

  1. 安卓常用功能——已封装好
  2. C++ 创建一个窗口
  3. Windows核心编程 第六章 线程基础知识 (上)
  4. 【Java 并发编程】线程指令重排序问题 ( 指令重排序规范 | volatile 关键字禁止指令重排序 )
  5. 【鸿蒙 HarmonyOS】UI 组件 ( Text 组件 )
  6. lava.lang.String数据转换为java.sql.Date
  7. python 3.5(socket)
  8. C指针笔试题,蛋疼的多重指针运算,谭浩强的阴影
  9. 【读书笔记】《第一行代码》
  10. 2016-8-18晨型养成第三天