2007-03-20

spring 多数据源解决方案

关键字: spring 多数据源
对这个贴的补充:动态切换多数据源

引用
2。在有多个数据源的时候,需要为每个数据源生成一个 beanfactory 。这个目前可能无法通过 spring 提供的 servlet 来自动实现,需要自己手工来操作。这些 beanfactory 使用同样的 spring xml 配置文件,但是使用不同的数据库配置文件。

对应每一个数据源,在程序启动的时候生成一个 factory ,然后可以为每个 factory 和数据源标识对应起来保存在 hashmap 之类的列表中,以方便后面使用。

3。如果使用 webwork,web 层的 action 不能再在 spring 的配置文件中出现了。在 web 层的 action 里面都实现一个 BeanFactoryAware 的 Interface 。再写一个 interceptor 来为 action 做 IoC 的操作,这个 BeanFactoryAware 可以根本不需要有任何方法,只是作为一个标识接口就可以了。


interceptor 的代码类似
public class RegistryInterceptor implements Interceptor {
  public String intercept(ActionInvocation invocation) throws Exception {
    if( invocation.getAction() instanceof BeanFactoryAware ) {
      Map session = invocation.getInvocationContext().getSession();

      Registry.getInstance().getContext( session.get( "dsKey" ) )
          .getBeanFactory().autowireBeanProperties( invocation.getAction(),
          AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false );
    }
  }
}


package test;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;

import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;

import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;

public final class Registry {

  static Registry instance = new Registry();

  public static Registry getInstance() {
    return instance;
  }

  private Map contextMap;

  private Registry() {
    contextMap = new HashMap();
  }     

  public Object getBean( final String dsKey, final String beanName ) {
    AbstractApplicationContext context =
      (AbstractApplicationContext)contextMap.get( dsKey );
    if( null != context ) { 
      return context.getBean( beanName );
    } else {    
      return null;      
    }           
  }     

  public AbstractApplicationContext getContext( final String dsKey ) {
    return (AbstractApplicationContext)contextMap.get( dsKey );
  }     

  public void init( Map dsPropertiesMap, String [] contextFiles ) throws Exception {
    Iterator iter = dsPropertiesMap.keySet().iterator();

    while( iter.hasNext() ) {
      String dsKey = (String)iter.next();

      String [] propertiesFiles = (String[])dsPropertiesMap.get( dsKey );

      Properties allProps = new Properties();
      for( int i = 0; i < propertiesFiles.length; i++ ) {
        Properties props = new Properties();
        props.load( new FileInputStream( propertiesFiles[i] ) );

        allProps.putAll( props );
      }

      PropertyPlaceholderConfigurer configurer = 
            new  PropertyPlaceholderConfigurer();
      configurer.setProperties(  allProps );

      ClassPathXmlApplicationContext context = 
            new ClassPathXmlApplicationContext( contextFiles, false );
      context.addBeanFactoryPostProcessor( configurer );
      context.refresh();

      contextMap.put( dsKey, context );
    }
  }
}



package test;

import org.springframework.beans.factory.config.AutowireCapableBeanFactory;

import java.util.Map;
import java.util.HashMap;

import test.Registry;

class UserService {
  UserService(){}

  // omit other useful methods
}

class UserAction {
  UserService userService;

  UserAction() {}

  void setUserService( UserService userService ) {
    userService = userService;
  }     

  // omit other useful methods
}

public class TestRegistry {

  static public void main( String [] args ) throws Exception {
    Map propertiesMap = new HashMap();

    propertiesMap.put( "ds1", 
      new String[] { "database1.properties", "common.properties" } );
    propertiesMap.put( "ds2", 
      new String[] { "database2.properties", "common.properties" } );

    Registry.getInstance().init( propertiesMap,
        new String[] { "ApplicationContext.xml", "DataAccessContext.xml" } );

    UserAction action = new UserAction();
    Registry.getInstance().getContext( "ds1" ).getBeanFactory()
      .autowireBeanProperties( action,
      AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);

    UserService service = 
      (UserService)Registry.getInstance().getBean( "ds2", "UserService" );
  }     
}
评论
stephen
搜索本博客
最近加入圈子
存档
最新评论
  • [zz]桥牌基本概念
    确定定约的一方称定约方,其宗旨是要完成定约;同意的一方称防守方,其目标是击垮敌方 ...
    -- by stephen
  • [zz]桥牌基本概念
    5、定约所谓定约,是指经过叫牌最后由一方确定经另一方同意的一个叫牌级数协定。确定 ...
    -- by stephen
评论排行榜