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;
}
}