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>

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()

时间: 2024-11-27 13:46:09

spring:如何用代码动态向容器中添加或移除Bean ?的相关文章

android 如何用代码动态添加launcher?

问题描述 android 如何用代码动态添加launcher? 同一个项目包含手机和盒子版两个版本的代码,手机版不需要添加按Home键 出launcher,而盒子版需要按home键时,将应用显示在launcher列表里, (即盒子需要launcher,手机不需要)如果只是在AndroidManifest.xml 添加属性的手机和盒子都会有lanucher,求大神解救--- 解决方案 参考http://blog.csdn.net/t12x3456/article/details/7857835

如何用winhex在MFT表中添加记录被文件系统识别?

问题描述 如何用winhex在MFT表中添加记录被文件系统识别? 5C 如何用winhex在MFT表中添加记录被文件系统识别? 步骤如下: 1 我先在根目录下新建一个很小的TXT文件 例如a.txt 里面有内容123456789 2 用winhex找到啊a.txt在MFT表中的记录 复制十六进制数据 3 将复制的内容在MFT表中新建一个记录 修改其中的文件记录参考号+1 文件名 完成 但是 实际上没有被识别到 而且附加操作 新建一个文件 发现我刚刚粘贴的文件倍覆盖了 我以为是不是ntfs还有别的

Android实现动态向Gallery中添加图片及倒影与3D效果示例_Android

本文实例讲述了Android实现动态向Gallery中添加图片及倒影与3D效果的方法.分享给大家供大家参考,具体如下: 在Android中gallery可以提供一个很好的显示图片的方式,实现上面的效果以及动态添加数据库或者网络上下载下来的图片资源.我们首先实现一个自定义的Gallery类. MyGallery.java: package nate.android.Service; import android.content.Context; import android.graphics.Ca

Android实现动态向Gallery中添加图片及倒影与3D效果示例

本文实例讲述了Android实现动态向Gallery中添加图片及倒影与3D效果的方法.分享给大家供大家参考,具体如下: 在Android中gallery可以提供一个很好的显示图片的方式,实现上面的效果以及动态添加数据库或者网络上下载下来的图片资源.我们首先实现一个自定义的Gallery类. MyGallery.java: package nate.android.Service; import android.content.Context; import android.graphics.Ca

如何用代码动态添加控件

在资源编辑器里我们可以方便地在对话框中加入所需控件,比如文本编辑框.列表控件等.但假如我们需要在运行期间动态生成这些控件该怎么做呢?本文就是讲述用代码动态添加控件的方法,并提供示例工程. 程序运行界面如下 为了方便演示,我们先生成一个基于对话框的MFC工程,起名为My 在CMyDlg.h中做下面几个步骤: public: //加上这个变量 CEdit m_MyEdit; protected: //加上这个函数, 用来响应编辑框改变的事件 afx_msg void OnChangeEdit();

代码控制list.view中添加子项subitem问题

问题描述 例如lvw1.add之后,如何向该项中添加子信息显示在第二列及以后列?? 解决方案 解决方案二:item里的那个.,.,解决方案三:本帖最后由 caozhy 于 2016-02-08 21:56:17 编辑解决方案四:引用2楼caozhy的回复: ListView.Items.Insert(index-1,item) 这样能直接添加子项中的内容并用一个方法去修改么-我现在找到的方法是newlistviewitem(newstring[]{},-1);可是我发现我又不会在后面更改其中某一

javascript动态向网页中添加表格实现代码_javascript技巧

//此段代码在IE9.Firefox.Chorme.safair中测试显示没有问题,给该表格添加了一些简单的样式,基本功能可以实现,还有少量问题有待改进! 效果图如下:  以下是代码: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <

新手问:c# 如何用代码更改FastReprot.net 中1.frx中的文本内容?

问题描述 就是想修改图示中的aaa的文本值 解决方案 本帖最后由 ffwwwyx 于 2015-01-02 23:19:19 编辑解决方案二:靠,自己解决了,搞一天没搞明白,问完了搞明白了.解决方案三:那就找到这个控件,给它赋值呀.

android 动态向Gallery中添加图片及倒影&amp;amp;&amp;amp;3D效果

http://blog.csdn.net/sunboy_2050/article/details/7483169 http://www.cnblogs.com/hellope/archive/2011/08/02/2124573.html android-gallery游览图片点击图片放大  http://dev.10086.cn/cmdn/wiki/index.php?doc-view-7350.html 模仿网易新闻图片点击放大效果 http://www.eoeandroid.com/for