首页 > 编程语言 > 详细

Spring配置多数据源过程

时间:2016-06-26 02:15:32      阅读:237      评论:0      收藏:0      [点我收藏+]

这里使用AOP拦截注解来切换数据源。
1.??? 在数据源配置文件context.xml中增加新的数据源信息,使存在多个数据库服务可以访问。注意区别开jndi名称。
2.??? 在spring配置文件(一般是spring.xml)中增加新数据源的连接配置。
3.??? 新建多数据源类(比如MultipleDataSource.java),需要继承自org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
a)??? 增加静态属性用来保存数据源信息。因为线程间不需要访问对方的数据源,这里使用ThreadLocal保存各线程的数据源信息

private static final ThreadLocal<String> dataSourceKey

?b)?? ?重写determineCurrentLookupKey()方法。该方法是spring jdbc用来从targetDataSources中查找数据源的,如果返回为null, 则使用defaultTargetDataSource指定的默认数据源(这些属性在第4步配置)

	@Override
	protected Object determineCurrentLookupKey() {
		return dataSourceKey.get();
	}

?c)?? ?增加静态设置方法,用于给当前线程设置数据源

	public static void setDataSourceKey(String dataSource) {
		dataSourceKey.set(dataSource);
	}

?d)?? ?增加静态清除方法,用于给无注解方法使用默认数据源

	public static void toDefault(){
		dataSourceKey.remove();
	}

?4.?? ?在spring.xml增加多数据源类的bean

	<bean id="multipleDataSource"	class="MultipleDataSource">
		<property name="defaultTargetDataSource" ref="{0}" />
		<property name="targetDataSources">
			<map>
				<entry key="key1" value-ref="{1}" />
				<entry key="key2" value-ref="{2}" />
			</map>
		</property>
	</bean>

?a)?? ?配置属性defaultTargetDataSource,ref值为几个数据库连接中的某一个。当没有指定数据源时,默认使用该连接。
b)?? ?配置属性targetDataSources,map的条目key自由定义,用来识别不同的数据源,value-ref指向对应的数据库连接。
6.??? 新增注解类,需要包含一个字符串属性,由于结合AOP所以要指定反射期可用,同时该注解作用于方法上:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface BiDSChoicer {
	String dsName();
}

?7.??? 新建一个AOP通知类,我们要在方法执行以前先切换数据源,所以要实现org.springframework.aop.MethodBeforeAdvice接口,重写before(Method method, Object[] args, Object target)方法:

	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		BiDSChoicer annotation = method.getAnnotation(BiDSChoicer.class);
		if (annotation != null)
	FossMultipleDataSource.setDataSourceKey(annotation.dsName());
		else
			FossMultipleDataSource.toDefault();
	}

?8.??? 由于接口实现配置了事务管理,事务的优先级会高于数据源切换。一旦事务开启,再切换数据源是无效的,所以这里需要修改它们的次序
a)??? 通知类要实现org.springframework.core.Ordered接口,并重写getOrder()方法,令其返回1;

	@Override
	public int getOrder() {
		return 1;
	}

?b)??? 事务的配置中增加order为2

<tx:annotation-driven transaction-manager="transactionManager" order="2" />

?这样,Spring会优先执行通知类方法,之后再开启事务。
9.??? 在需要切换数据源的接口方法上(必须是接口里的方法,在实现方法上无效)增加注解@BiDSChoicer(dsName="dsname"),属性值必须是配置的targetDataSources属性的条目key。
10.??? 在spring.xml里面新建通知类的bean,假设id是advice
11.??? 定义切入点,expression属性要根据情况具体修改,指向实现类

	<bean id="dspc"
class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
		<property name="expression"
			value="execution(public * .service..*.*(..))"/>
	</bean>

?12.??? 定义通知者

	<bean id="defaultPointcutAdvisor " class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="advice" ref="advice" />
		<property name="pointcut" ref="dspc" />
	</bean>

?这样配置以后,需要修改数据源的接口方法只要在其上增加注解即可。AOP拦截方法后会先对数据源进行设置,有注解的根据注解属性设置,没有注解的设置为使用默认数据源。对于AOP不拦截的则使用默认数据源。

Spring配置多数据源过程

原文:http://somefuture.iteye.com/blog/2306320

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!