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.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 ?的更多相关文章
- 六、spring之通过FactoryBean为ioc容器中添加组件
前面我们已经介绍了几种为容器中添加组件的方法,今天一起学习通过FactoryBean添加组件的方法. 首先我们准备一个类,也就是我们需要注册进spring的ioc容器中的类 类Color: // 不必 ...
- js如何实现动态在表格中添加标题和去掉标题?
js如何实现动态在表格中添加标题和去掉标题? 一.总结 1.通过table标签的createCaption(),deleteCaption()方法实现. document.getElementById ...
- sencha动态向容器里添加控件出现重叠问题
sencha动态向容器里添加控件出现重叠问题原因是由于动态生成控件的id有重复导致的.(js取时间到毫秒来做id,放在for里面会出现几个控件id是相同的情况.).解决掉重复id的问题就好了. 版权声 ...
- ajax异步获取数据后动态向表格中添加数据(行)
因为某些原因,项目中突然需要做自己做个ajax异步获取数据后动态向表格中添加数据的页面,网上找了半天都没有 看到现成的,决定自己写个例子 1.HTML页面 <!doctype html> ...
- spring源码 — 二、从容器中获取Bean
getBean 上一节中说明了容器的初始化,也就是把Bean的定义GenericBeanDefinition放到了容器中,但是并没有初始化这些Bean.那么Bean什么时候会初始化呢? 在程序第一个主 ...
- Spring注解驱动开发04(给容器中注册组件的方式)
给容器中注册组件的方式 1. 组件注解标注 + 包扫描(适用于自己写的类) //控制层组件 @Controller public class PersonController { } //业务逻辑层组 ...
- vector容器中添加和删除元素
添加元素: 方法一: insert() 插入元素到Vector中 iterator insert( iterator loc, const TYPE &val ); //在指定位置loc前插入 ...
- jQuery中添加/改变/移除改变CSS样式例子
在jquery中对于div样式操作我们会使用到CSS() removeClass() addClass()方法来操作了,下面我们就整理了几个例子大家一起来看看吧. CSS()方法改变CSS样式 ...
- 2.spring源码-BeanPostProcessor后置处理之ApplicationContextAwareProcessor,实现spring容器中某一个类的bean对象在初始化时需要得到Spring容器内容。
需求:我们的需求是,在spring初始化完毕时,使我们自定义一个类Bird类可以得到spring容器内容. 实现步骤: 1.首先我们来看一下ApplicationContextAwareProcess ...
随机推荐
- 3、Javascript学习 - IT软件人员学习系列文章
接下来,我们开始进入Javascript语言的学习. Javascript语言是一种解释性的语言,不同于ASP.NET.C#语言的这种编译性的语言.它随着HTML网页的发布而发布,就是说嵌入到HTML ...
- python里面出现中文的时候报错 'ascii' codec can't encode characters in position
编码问题,在头部添加 import sys reload(sys) sys.setdefaultencoding( "utf-8" ) http://www.xuebuyuan.c ...
- Linux下防火墙开启相关端口及查看已开启端口
最近利用Apache Mina实现了一个http服务,发布到linux下发现无法访问,通过HttpClient来发送http请求时,报如下错误: Exception in thread "m ...
- javascript 基础教程[温故而知新一]
子曰:“温故而知新,可以为师矣.”孔子说:“温习旧知识从而得知新的理解与体会,凭借这一点就可以成为老师了.“ 尤其是咱们搞程序的人,不管是不是全栈工程师,都是集十八般武艺于一身.不过有时候有些知识如果 ...
- spring多数据源的处理 mybatis实现跨库查询
实现Myibatis动态sql跨数据库的处理 Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性.而这样的方案就会不 同于常见 ...
- asp.net 后台 Http POST请求
时间忙,简单些,直接贴代码上图 百度站长平台为站长提供链接提交通道,您可以提交想被百度收录的链接,百度搜索引擎会按照标准处理 http://zhanzhang.baidu.com/linksubmit ...
- android:context,getApplicationContext()生命周期
getApplicationContext() 返回应用的上下文,生命周期是整个应用,应用摧毁它才摧毁Activity.this的context 返回当前activity的上下文,属于activity ...
- C/C++ sizeof函数解析——解决sizeof求结构体大小的问题
C/C++中不同数据类型所占用的内存大小 32位 64位 char 1 1 int ...
- 仿哔哩哔哩应用客户端Android版源码项目
这是一款高仿哔哩哔哩安卓客户端,跟官方网的差不多吧,界面也几乎是一样的,应用里面也加了一些弹出广告,大家可以参考一下吧,安装测试包在源码文件那里,大家可以多多参考一下. 哔哩哔哩弹幕网是国内知名的弹幕 ...
- hadoop2.6---windows下开发环境搭建
一.准备插件 1.自己编译 1.1 安装Ant 官网下载Ant,apache-ant-1.9.6-bin.zip 配置环境变量,新建ANT_HOME,值是E:\apache-ant-1.9.6:PAT ...