DataSourceAspect.java 1.82 KB
package com.zhongzhi.common.configure;

import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
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.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Order(-10) // 保证该 AOP 在 @Transactional 之前执行
@Component
public class DataSourceAspect {

    @Before("@annotation(com.zhongzhi.common.configure.DataSourceSwitch) || @within(com.zhongzhi.common.configure.DataSourceSwitch)")
    public void before(JoinPoint point) {
        Class<?> targetClass = point.getTarget().getClass();
        DataSourceSwitch classDataSource = targetClass.getAnnotation(DataSourceSwitch.class);
        
        // 默认使用类上的数据源配置
        String dsName = "master";
        if (classDataSource != null) {
            dsName = classDataSource.value();
        }
        
        // 方法上的数据源配置会覆盖类上的配置
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        DataSourceSwitch methodDataSource = method.getAnnotation(DataSourceSwitch.class);
        if (methodDataSource != null) {
            dsName = methodDataSource.value();
        }
        
        // 切换数据源
        DynamicDataSourceContextHolder.push(dsName);
    }

    @After("@annotation(com.zhongzhi.common.configure.DataSourceSwitch) || @within(com.zhongzhi.common.configure.DataSourceSwitch)")
    public void after(JoinPoint point) {
        // 清除数据源,避免线程复用导致的问题
        DynamicDataSourceContextHolder.poll();
    }
}