应用于运行过程中动态加载bean,比如数据源的动态加载、定时任务的动态加载等。
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&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毫秒。