先来看一张类图:

有一个业务接口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.FooA
String beanName = ctx.getBeanNamesForType(IFoo.class)[0];
System.out.println(beanName);//fooA
System.out.println(ctx.isSingleton(beanName));//true //销毁FooA实例
removeBean(ctx, beanName);
System.out.println(ctx.containsBean(beanName));//false
System.out.println("------------"); //注入新Bean
beanName = "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);//fooB
System.out.println(ctx.isSingleton(beanName));//true System.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>

输出:
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. js如何实现动态在表格中添加标题和去掉标题?

    js如何实现动态在表格中添加标题和去掉标题? 一.总结 1.通过table标签的createCaption(),deleteCaption()方法实现. document.getElementById ...

  3. sencha动态向容器里添加控件出现重叠问题

    sencha动态向容器里添加控件出现重叠问题原因是由于动态生成控件的id有重复导致的.(js取时间到毫秒来做id,放在for里面会出现几个控件id是相同的情况.).解决掉重复id的问题就好了. 版权声 ...

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

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

  5. spring源码 — 二、从容器中获取Bean

    getBean 上一节中说明了容器的初始化,也就是把Bean的定义GenericBeanDefinition放到了容器中,但是并没有初始化这些Bean.那么Bean什么时候会初始化呢? 在程序第一个主 ...

  6. Spring注解驱动开发04(给容器中注册组件的方式)

    给容器中注册组件的方式 1. 组件注解标注 + 包扫描(适用于自己写的类) //控制层组件 @Controller public class PersonController { } //业务逻辑层组 ...

  7. vector容器中添加和删除元素

    添加元素: 方法一: insert() 插入元素到Vector中 iterator insert( iterator loc, const TYPE &val ); //在指定位置loc前插入 ...

  8. jQuery中添加/改变/移除改变CSS样式例子

    在jquery中对于div样式操作我们会使用到CSS() removeClass() addClass()方法来操作了,下面我们就整理了几个例子大家一起来看看吧.     CSS()方法改变CSS样式 ...

  9. 2.spring源码-BeanPostProcessor后置处理之ApplicationContextAwareProcessor,实现spring容器中某一个类的bean对象在初始化时需要得到Spring容器内容。

    需求:我们的需求是,在spring初始化完毕时,使我们自定义一个类Bird类可以得到spring容器内容. 实现步骤: 1.首先我们来看一下ApplicationContextAwareProcess ...

随机推荐

  1. Web端即时通讯技术原理详解

    前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...

  2. git之一

    1.Git是什么Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常大的项目版本管理.Git 是 ...

  3. mysql 去重,跨表更新,跨表删除

    一.去重 1.查询出重复的记录 CREATE TABLE push_log_full_2013_10_30_tmp SELECT * FROM `push_log_full` WHERE time B ...

  4. const,readonly 这些你真的懂吗? 也许会被面试到哦。。。

    首先不可否认,这些在面试上会经常被面试官问起,但是你回答的让面试官满意吗?当然如果你知道了这些原理,或许你就不 怕了.既然说到了原理,我们还是从MSDN说起. 一:值得推敲的几个地方 1.先来看看ms ...

  5. SQL Server:统计数据库中每张表的大小

    1. 统计数据库中每张表的大小 1.1 首先执行下面的命令 exec sp_MSforeachtable @command1="sp_spaceused '?'"; 1.2 检测当 ...

  6. 在JavaScript和C#中获得referer

    1. JavaScript /** * 获取HTTP请求的Referer * @ishost 布尔类型 Referer为空时是否返回Host(网站首页地址) */ function get_http_ ...

  7. 烂泥:php5.6源码安装与apache集成

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. apache对php的支持是通过apache的mod_php5模块来支持的,这点与nginx不同.nginx是通过第三方的fastcgi处理器才可以对p ...

  8. setTimeout()与setInterval()——走马灯效果

    JavaScript中的setTimeout()与setInterval()都是指延时执行某一操作. 但setInterval()指每隔指定时间执行某操作,会循环不断地执行该操作:setTimeout ...

  9. C++ 笔记(一) —— 尽量以 const、enum、inline 替换 #define

    ilocker:关注 Android 安全(新手) QQ: 2597294287 #define ASPECT_RATIO 1.653 记号 ASPECT_RATIO 不会进入 symbol tabl ...

  10. Linux 下从头再走 GTK+-3.0 (四)

    实际的应用中,往往有很多个控件, 同样GTK提供了很多种布局方案,Box, Fixed , Table , Grid 等. 接下来试试网格布局 Grid. 我们创建 example4.c ,内容如下: ...