`
zhyi_12
  • 浏览: 98910 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

spring中动态加载bean的简单实现

    博客分类:
  • java
阅读更多
  • 场景

应用于运行过程中动态加载bean,比如数据源的动态加载、定时任务的动态加载等。

  • 环境
spring3.0.5
  • 代码

DynamicBeanReader           bean动态加载接口.

DynamicBeanReaderImpl    bean动态加载实现类.

DynamicResource                org.springframework.core.io.Resource的实现类.

DynamicBean                      动态bean描述对象的抽象类.

DataSourceDynamicBean    继承自DynamicBean,一个数据源的简单bean配置描述对象.

 

 

spring配置

 

<bean id="dynamicBeanReader" class="org.youi.common.bean.DynamicBeanReaderImpl" init-method="init">
		
</bean>
 

 

 

动态加载bean接口

 

public interface DynamicBeanReader{
	
    /**
     * 动态加载bean
     * @param dynamicBean
     */
    public void loadBean(DynamicBean dynamicBean);
}

 

 动态加载bean实现类

 

public class DynamicBeanReaderImpl implements DynamicBeanReader,ApplicationContextAware{
	private static final Log logger = LogFactory.getLog(DynamicBeanReaderImpl.class);//日记
	
	private ConfigurableApplicationContext applicationContext = null;  
	
	private XmlBeanDefinitionReader beanDefinitionReader;
	/*初始化方法*/
	public void init(){
		beanDefinitionReader = new XmlBeanDefinitionReader((BeanDefinitionRegistry)
				applicationContext.getBeanFactory());  
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(applicationContext));  
	}
	
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  
        this.applicationContext = (ConfigurableApplicationContext)applicationContext;  
    }
    
    public void loadBean(DynamicBean dynamicBean){ 
    	long startTime = System.currentTimeMillis();
    	String beanName = dynamicBean.getBeanName();
    	if(applicationContext.containsBean(beanName)){
    		logger.warn("bean【"+beanName+"】已经加载!");
    		return;
    	}
        beanDefinitionReader.loadBeanDefinitions(new DynamicResource(dynamicBean));
        logger.info("初始化bean【"+dynamicBean.getBeanName()+"】耗时"+(System.currentTimeMillis()-startTime)+"毫秒。");
    } 
}

 

public class DynamicResource implements Resource {
	private DynamicBean dynamicBean;
	
	public DynamicResource(DynamicBean dynamicBean){
		this.dynamicBean = dynamicBean;
	}
	/* (non-Javadoc)
	 * @see org.springframework.core.io.InputStreamSource#getInputStream()
	 */
	public InputStream getInputStream() throws IOException {
		return new ByteArrayInputStream(dynamicBean.getXml().getBytes("UTF-8"));
	}
//其他实现方法省略
}
 

 

/**
 * 动态bean描述对象
 */
public abstract class DynamicBean {
	protected String beanName;

	public DynamicBean(String beanName) {
		this.beanName = beanName;
	}

	public String getBeanName() {
		return beanName;
	}

	public void setBeanName(String beanName) {
		this.beanName = beanName;
	}
	
	/**
	 * 获取bean 的xml描述
	 * @return
	 */
	protected abstract String getBeanXml();
	
	/**
	 * 生成完整的xml字符串
	 * @return
	 */
	public String getXml(){
		StringBuffer buf = new StringBuffer();
		buf.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
			.append("<beans xmlns=\"http://www.springframework.org/schema/beans\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")
			.append("		xmlns:p=\"http://www.springframework.org/schema/p\" xmlns:aop=\"http://www.springframework.org/schema/aop\"")
			.append("		xmlns:context=\"http://www.springframework.org/schema/context\" xmlns:jee=\"http://www.springframework.org/schema/jee\"")
			.append("		xmlns:tx=\"http://www.springframework.org/schema/tx\"")
			.append("		xsi:schemaLocation=\"")
			.append("			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd")
			.append("			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd")
			.append("			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd")
			.append("			http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd")
			.append("			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd\">")
			.append(getBeanXml())
			.append("</beans>");
		return buf.toString();
	}
}
 

 

 

/**
 * 数据源动态bean描述对象
 */
public class DataSourceDynamicBean extends DynamicBean {
	private String driverClassName;
	
	private String url;
	
	private String username;
	
	private String password;
	
	public DataSourceDynamicBean(String beanName) {
		super(beanName);
	}
	/* (non-Javadoc)
	 * @see org.youi.common.bean.DynamicBean#getBeanXml()
	 */
	@Override
	protected String getBeanXml() {
		StringBuffer xmlBuf = new StringBuffer();
		xmlBuf.append("<bean id=\""+beanName+"\" class=\"org.apache.commons.dbcp.BasicDataSource\" destroy-method=\"close\"")
			.append(" p:driverClassName=\""+driverClassName+"\" ")
			.append(" p:url=\""+url+"\"")
			.append(" p:username=\""+username+"\"")
			.append(" p:password=\""+password+"\"/>");
		return xmlBuf.toString();
	}
	
	public String getDriverClassName() {
		return driverClassName;
	}
	public void setDriverClassName(String driverClassName) {
		this.driverClassName = driverClassName;
	}
	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

}

 

/**
 *junit测试类
 */
@ContextConfiguration(locations={"classpath:applicationContext-test.xml"})
public class DynamicBeanReaderTests extends AbstractJUnit4SpringContextTests{
	@Autowired
	private DynamicBeanReader dynamicBeanReader;
  
    @Test
    public void testLoadBean(){
    	DataSourceDynamicBean dataSourceDynamicBean = new DataSourceDynamicBean("dataSource1");
    	dataSourceDynamicBean.setDriverClassName("org.gjt.mm.mysql.Driver");
    	dataSourceDynamicBean.setUrl("jdbc:mysql://127.0.0.1:3306/youi2?useUnicode=true&amp;characterEncoding=utf-8");
    	dataSourceDynamicBean.setUsername("youi2");
    	dataSourceDynamicBean.setPassword("youi2");
    	
    	dynamicBeanReader.loadBean(dataSourceDynamicBean);//
    	
    	DataSource s = (DataSource)applicationContext.getBean("dataSource1");
    	try {
			PreparedStatement ps = s.getConnection().prepareStatement("select '数据库输出的数据' a from dual");
			ps.execute();
			ResultSet rs = ps.getResultSet();
			while(rs.next()){
				System.out.println(rs.getString("a"));
			}
		} catch (SQLException e) {
			//TODO 
		}
    }
}

执行测试的输出:

 20110310 23:12:44 INFO DynamicBeanReaderImpl.loadBean(60) | 初始化bean【dataSource1】耗时78毫秒。

数据库输出的数据

 

0
9
分享到:
评论
5 楼 Freeman19211105 2016-08-11  
楼主,下次 尽可能分享的时候把包贴出来,要不很容易倒错包的
4 楼 zy463395598 2015-10-16  
您好,请问可以给个动态加载定时任务的例子吗?
我这边按照您的方法,有两个问题
1、可以把bean动态装配进去,但是不能自动执行,即便在xml里面协商init-method也不执行,但是bean确实是已经装配进spring,可以通过getBean获取到。
2、按这种方式装载,装载bean的时候不能注入其他bean,那么在做动态装载定时任务的时候怎么样把Scheduler注入到执行bean里面去?
如果可以到话麻烦回复我下,mail:87565929@qq.com
谢谢!
3 楼 ciwan 2015-07-16  
楼主,能吧DynamicResource的贴全吗
2 楼 hustlxjaw 2011-04-25  
有个工具叫jRebel,可以热加载,对spring支持的也挺好
1 楼 yheye 2011-04-09  
LZ,请问怎么把jar包动态加入进去呢?

相关推荐

Global site tag (gtag.js) - Google Analytics