AbstractRoutingDataSource实现数据源切换

来源:互联网 发布:人人商城分销源码下载 编辑:程序博客网 时间:2024/06/05 07:11

1、在spring配置文件中加入以下配置

<!-- 多数据源配置 -->
<bean id="dataSource"
class="com.wangku.wjf.common.datasource.TradingRoutingDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
</map>
</property>
<!-- common里只定义一个默认数据源 -->
<property name="defaultTargetDataSource" ref="default.dataSource"></property>
</bean>

2、TradingRoutingDataSource类如下:

public class TradingRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return TradingDataSourceHolder.getThreadDataSource();
}

@Override
    public void setTargetDataSources(Map<Object, Object> targetDataSources) {  
        super.setTargetDataSources(targetDataSources);  
        afterPropertiesSet();
    }  
}

3、TradingDataSourceHolder定义如下:

public class TradingDataSourceHolder {
protected static final Logger logger = LoggerFactory.getLogger(TradingDataSource.class);


private static final ThreadLocal<String> threadDataSource = new ThreadLocal<String>();


public static String getThreadDataSource() {
String dataSourceName = (String) threadDataSource.get();
if (dataSourceName != null) {
logger.info("DataSource Name:[" + dataSourceName + "]");
}
return threadDataSource.get();
}


public static void setThreadDataSource(String dataSourceName) {
threadDataSource.set(dataSourceName);
}

4、定义BeanPostPrcessorImpl,代码如下:

public class BeanPostPrcessorImpl implements BeanPostProcessor {
@Autowired 
private TradingRoutingDataSource tradingRoutingDataSource;
private static Map<Object,Object> _targetDataSources =new HashMap<Object, Object>();

public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
if(bean instanceof BasicDataSource){
_targetDataSources.put(beanName, bean);
tradingRoutingDataSource.setTargetDataSources(_targetDataSources);
}
return bean;
}
}

5、自定义注解切换数据源:

@Retention(RetentionPolicy.RUNTIME)
public @interface TradingDataSource {
String name();
}

6、AOP解析注解,实现切换:

@Aspect
@Component
public class TradingDataSourceAdvice implements Ordered {


@Pointcut("execution(* com.xxx.*.service..*.*(..))")
private void serviceInvoke(){}

@Around("serviceInvoke()")
public Object interceptor(ProceedingJoinPoint pjp) throws Throwable {
//在类上找
TradingDataSource tradingDataSource = pjp.getTarget().getClass().getAnnotation(TradingDataSource.class);
if (tradingDataSource == null) {
//在方法上找
String methodName = pjp.getSignature().getName();
tradingDataSource = pjp.getTarget().getClass().getMethod(methodName).getAnnotation(TradingDataSource.class);
}
if (tradingDataSource != null) {
//如果检测到需要切换,则进行处理
TradingDataSourceHolder.setThreadDataSource(tradingDataSource.name());
}
Object object = pjp.proceed();
if(tradingDataSource != null) {
//切换后清除
TradingDataSourceHolder.clearThreadDataSource();
}
return object;
}
public int getOrder() {
return 100;
}


}

原创粉丝点击