基于Spring的AOP切面编程切换数据源

基于Spring的AOP切面编程切换数据源

1、实现Spring提供的获取数据源的抽象类

package com.banksteel.finance.bill.db;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * 
* @description: 动态数据源,动态获取数据源的实现
* @projectName:banksteel-finance-voucher-service
* @author: zhongwen
* @createTime:2017年12月12日 上午10:49:17
 */
public class DynamicDataSource extends AbstractRoutingDataSource
{
   
   
    private static final Logger log = LoggerFactory.getLogger(DynamicDataSource.class);
	/**
	 * 用户返回当且切换到的数据库
	 */
	@Override
	protected Object determineCurrentLookupKey()
	{
   
   
		//DynamicDataSourceHolder有获取和设置当前数据库的方法get & put
	    String dataSource = DynamicDataSourceHolder.getDataSource();
	    log.info("数据库访问获取数据源:{}", dataSource);
		return DynamicDataSourceHolder.getDataSource();
	}

}

2、一个用来存放threadLocal来保存当前线程的数据源的工具类

package com.banksteel.finance.bill.db;

/**
 * 
* @description: 动态数据源holder
* @projectName:banksteel-finance-voucher-service
* @author: zhongwen
* @createTime:2017年12月12日 上午10:47:38
 */
public class DynamicDataSourceHolder
{
   
   
	public static final ThreadLocal<String> HOLDER = new ThreadLocal<String>();

	public static void putDataSource(String name)
	{
   
   
		HOLDER.set(name);
	}

	public static String getDataSource()
	{
   
   
		return HOLDER.get();
	}
	
	public static void clearCustomerType() {
   
   
		HOLDER.remove();
    }
}

3、定义一个切面AOP实现类
@Pointcut用于来描述切点
@Before扫描切面执行被切方法之前的操作【切换到注解指定的数据源】
@After被切方法执行完毕后需要将其使用的数据源清空

package com.banksteel.finance.bill.db;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @description 数据库切面
 * @className DataSourceAspect
 * @projectName banksteel-finance-payable-base-service-provider
 * @author fangsy
 * @createTime 2018年9月5日上午10:53:55
 * @version 1.0.0
 */
@Aspect
@Component
public class DataSourceAspect
{
   
   
	private static final Logger logger = LoggerFactory.getLogger(DataSourceAspect.class);
	
	@Pointcut("execution(* com.banksteel.finance.bill.dao.*.*(..))")  
    private void aspectPoint(){
   
   
		//定义一个切入点  
	}

	/**
	 * 
	 *
	 * @param joinPoint
	 *            切点
	 */
	@Before("aspectPoint()")
	public void doBefore(JoinPoint point)
	{
   
   
		Object target = point.getTarget();
		String method = point.getSignature().getName();
		Class<?>[] classz = target.getClass().getInterfaces();
		Class<?
Spring AOP中,可以使用切面编程来实现动态数据源切换。下面是一个简单的示例: 首先,创建一个注解类`DataSource`,用于标识需要切换数据源的方法: ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DataSource { String value() default "default"; } ``` 然后,创建一个切面类`DataSourceAspect`,在该类中定义切点和切面逻辑: ```java @Aspect @Component public class DataSourceAspect { @Around("@annotation(dataSource)") public Object switchDataSource(ProceedingJoinPoint joinPoint, DataSource dataSource) throws Throwable { try { // 获取切换数据源名称 String dataSourceName = dataSource.value(); // 根据数据源名称切换数据源 switchDataSource(dataSourceName); // 执行目标方法 return joinPoint.proceed(); } finally { // 切换回默认数据源 switchDataSource("default"); } } // 实际切换数据源的逻辑 private void switchDataSource(String dataSourceName) { // 根据传入的数据源名称进行数据源切换逻辑的实现 // ... } } ``` 在上述代码中,`@Around("@annotation(dataSource)")`表示拦截带有`@DataSource`注解的方法,并执行切面逻辑。在切面逻辑中,首先获取切换数据源名称,然后根据该名称进行数据源切换操作。在目标方法执行完毕后,切面逻辑会将数据源切换回默认的数据源。 最后,使用`@DataSource`注解标识需要切换数据源的方法: ```java @Service public class UserService { @DataSource("db1") public void addUser(User user) { // 执行添加用户的逻辑 } @DataSource("db2") public void updateUser(User user) { // 执行更新用户的逻辑 } } ``` 在上述示例中,`addUser`方法使用名为"db1"的数据源,`updateUser`方法使用名为"db2"的数据源。 通过以上步骤,就可以使用Spring AOP实现动态数据源切换。当调用带有`@DataSource`注解的方法时,切面会根据注解中指定的数据源名称进行数据源切换,从而实现动态切换数据源的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值