springboot利用aop切面实现数据源自动切换,为何无法保证切面顺序先于事务顺序?

事务使用aspectj代理方式的事务
代理顺序order=2

@EnableDubboConfiguration
@EnableAspectJAutoProxy
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableTransactionManagement(order = 2, mode = AdviceMode.ASPECTJ)

对应pom配置:

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.11</version>
                <configuration>
                    <complianceLevel>1.8</complianceLevel>
                    <encoding>UTF-8</encoding>
                    <showWeaveInfo>true</showWeaveInfo>
                    <forceAjcCompile>true</forceAjcCompile>
                    <sources/>
                    <weaveDirectories>
                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
                    </weaveDirectories>
                    <source>1.8</source>
                    <target>1.8</target>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                </configuration>
                <executions>
                    <execution>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>1.8.9</version>
                    </dependency>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjrt</artifactId>
                        <version>1.8.9</version>
                    </dependency>
                </dependencies>
            </plugin>

定义的aop切面
order=1

@Aspect
@Order(1)
@Component
public class BocDynamicDSAspect {

    @Before("@annotation(bocDS)")
    public void beforeSwitchDS(JoinPoint point, BocDS bocDS) {
        //获得当前访问的class
        Class<?> className = point.getTarget().getClass();

        //获得访问的方法名
        String methodName = point.getSignature().getName();
        //得到方法的参数的类型
        Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
        String dataSource = BocDSHolder.DEFAULT_DS;
        try {
            Method method = className.getMethod(methodName, argClass);

            if (method.isAnnotationPresent(BocDS.class)) {
                BocDS annotation = method.getAnnotation(BocDS.class);
                // 取出注解中的数据源名
                dataSource = annotation.value();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 切换数据源
        BocDSHolder.switchDB(dataSource);
    }

切换数据源的实现:

public class BocDynamicDS extends AbstractRoutingDataSource {

    public static final Logger logger = LoggerFactory.getLogger(BocDynamicDS.class);

    @Override
    protected Object determineCurrentLookupKey() {
        return BocDSHolder.getDBKey();
    }

}

预期设想是:
先执行aop切面,获得对应数据库信息
然后事务初始化开始,获取aop切面中拿到的注解中定义的数据源信息
现在的情况是:
事务总是先于aop切面初始化,用于数据源切换的aop切面后执行,整个数据源切换失效

aspectj代理的事务和切面如何保证顺序?求解答

阅读 5.3k
3 个回答
新手上路,请多包涵

因为spring事务优先从缓存中获取连接 而不是从DataSource, 即使AOP中切换了数据源的key也不会影响连接

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题