先來看一張類圖:

有一個業務接口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()
