博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring:如何用代码动态向容器中添加或移除Bean ?
阅读量:6359 次
发布时间:2019-06-23

本文共 5320 字,大约阅读时间需要 17 分钟。

先来看一张类图:

有一个业务接口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配置文件:

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

转载地址:http://ebdma.baihongyu.com/

你可能感兴趣的文章
seajs在jquery多个版本下引用jquery的插件的方案
查看>>
关于网络上java,php和.net的“口角之争“的一点想法 !
查看>>
python 第二周(第十三天) 我的python成长记 一个月搞定python数据挖掘!(21) -正则表达式re...
查看>>
[POI2011]SEJ-Strongbox
查看>>
20文件
查看>>
Android开发Intent应用概述
查看>>
【Go】并发编程
查看>>
VMware虚拟化NSX-Manager命令行更改admin用户密码
查看>>
python字符串函数
查看>>
ORM框架Hibernate (四)MyEclipse Hibernate Tool 逆向生成实体类
查看>>
去掉iphone连接电脑时会出现的弹出窗口
查看>>
【python】-- web开发之HTML
查看>>
vs2015 去除 git 源代码 绑定
查看>>
解决firefox的button按钮文字不能垂直居中
查看>>
网络协议端口号详解
查看>>
大话数据结构读后感——第一章
查看>>
各种排序
查看>>
Optional
查看>>
sed 命令编辑文本
查看>>
Activity调用isDestroyed()方法报出,java.lang.NoSuchMethodError
查看>>