From 8123b2ebf747ff553a1d566800d224c83407b8a2 Mon Sep 17 00:00:00 2001 From: iAmClever <158091461@qq.com> Date: Fri, 7 Mar 2025 15:27:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=AF=B9seata?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E4=BB=A3=E7=90=86=E6=95=B0=E6=8D=AE=E6=BA=90?= =?UTF-8?q?=E7=9A=84=E6=A3=80=E6=B5=8B=20(#704)=20(#705)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../check/SeataDataSourceProxyChecker.java | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 dynamic-datasource-spring-boot-starter/src/main/java/com/baomidou/dynamic/datasource/check/SeataDataSourceProxyChecker.java diff --git a/dynamic-datasource-spring-boot-starter/src/main/java/com/baomidou/dynamic/datasource/check/SeataDataSourceProxyChecker.java b/dynamic-datasource-spring-boot-starter/src/main/java/com/baomidou/dynamic/datasource/check/SeataDataSourceProxyChecker.java new file mode 100644 index 0000000..d5d58cb --- /dev/null +++ b/dynamic-datasource-spring-boot-starter/src/main/java/com/baomidou/dynamic/datasource/check/SeataDataSourceProxyChecker.java @@ -0,0 +1,78 @@ +/* + * Copyright © 2018 organization baomidou + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.baomidou.dynamic.datasource.check; + +import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties; +import lombok.extern.slf4j.Slf4j; +import org.aopalliance.aop.Advice; +import org.springframework.aop.Advisor; +import org.springframework.aop.framework.Advised; +import org.springframework.aop.support.AopUtils; +import org.springframework.beans.factory.SmartInitializingSingleton; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Slf4j +@Component +@ConditionalOnProperty(prefix = DynamicDataSourceProperties.PREFIX, name = "seata", havingValue = "true", matchIfMissing = false) +public class SeataDataSourceProxyChecker implements SmartInitializingSingleton { + private final ApplicationContext applicationContext; + private final Class seataAdviceClass = loadSeataAdviceClass(); + + public SeataDataSourceProxyChecker(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + @Override + public void afterSingletonsInstantiated() { + Map dataSourceMap = applicationContext.getBeansOfType(DynamicRoutingDataSource.class); + for (Map.Entry entry : dataSourceMap.entrySet()) { + String beanName = entry.getKey(); + DynamicRoutingDataSource ds = entry.getValue(); + if (isSeataProxyBean(ds)) { + log.warn("Seata auto-agent detected: AbstractDeliveringDataSource (beanName: {}). " + + "Please disable seata.enableAutoDataSourceProxy to avoid unknown exceptions.", beanName); + } + } + } + + private boolean isSeataProxyBean(DynamicRoutingDataSource bean) { + if (seataAdviceClass == null || !AopUtils.isAopProxy(bean) || !(bean instanceof Advised)) { + return false; + } + Advised advised = (Advised) bean; + for (Advisor advisor : advised.getAdvisors()) { + Advice advice = advisor.getAdvice(); + if (seataAdviceClass.isAssignableFrom(advice.getClass())) { + return true; + } + } + return false; + } + + private static Class loadSeataAdviceClass() { + try { + return Class.forName("io.seata.spring.annotation.datasource.SeataAutoDataSourceProxyAdvice"); + } catch (ClassNotFoundException | NoClassDefFoundError e) { + log.debug("SeataAutoDataSourceProxyAdvice not found, skipping Seata proxy check.", e); + return null; + } + } +}