diff --git a/README.md b/README.md
index daee01a..ed1624c 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,7 @@
| saas-datasource-spring-boot-starter | dynamic-datasource-spring-boot-starter | mybatis-plus-boot-starter | mybatis-spring-boot-starter |
| :----: | :----: | :----: | :----: |
+| 1.3.0 | version in (3.1.1, 3.4.1] | version <= 3.5.1 (latest) | version <= 2.2.2 (latest) |
| 1.2.0 | version in (2.4.2, 3.1.1] | version <= 3.5.1 (latest) | version <= 2.2.2 (latest) |
| 1.1.0 & 1.0.0 | version <= 2.4.2 |
根据`@SaaS`注解的位置分为两种情况:
1. 如果注解在Mapper上,则 version <= 3.0.7.1,若高于此版本dynamic-datasource会报错;
2. 如果注解不在Mapper上,则可使用目前最新版本 version <= 3.5.1 (latest)。
按[最佳实践](#最佳实践),推荐上述第二种情况,注解不要放在Mapper上。
| version <= 2.2.2 (latest) |
@@ -50,7 +51,7 @@
com.air-software
saas-datasource-spring-boot-starter
- 1.2.0
+ 1.3.0
```
@@ -72,7 +73,6 @@ spring:
url: jdbc:mysql://localhost/saas_common?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&autoReconnectForPools=true&allowMultiQueries=true
username: root
password: 123456
- driver-class-name: com.mysql.jdbc.Driver
druid:
filters: stat
initial-size: 1
@@ -116,7 +116,6 @@ public class MySaaSDataSourceProvider implements SaaSDataSourceProvider {
dataSourceProperty.setUrl(jdbcUrl);
dataSourceProperty.setUsername(dataSourceConfig.getUsername());
dataSourceProperty.setPassword(dataSourceConfig.getPassword());
- dataSourceProperty.setDriverClassName(dataSourceConfig.getDriverClassName());
dataSourceProperty.setPoolName(dsKey);
return saasDataSourceCreator.createDruidDataSource(dataSourceProperty);
@@ -198,9 +197,16 @@ public class SaaSApplication {
## 更新日志
+### 1.3.0
+
+- 更新并适配`dynamic-datasource-spring-boot-starter`至`3.4.1`版本;
+- 更新并适配`spring-boot-starter-web`至`2.1.1.RELEASE`版本;
+- 新增`SaaSDataSourceClassResolver`来解析注解标记的类,原因是`dynamic-datasource-spring-boot-starter`在`3.1.1`版本后删除了本工具之前使用的对应API,所以只能本工具自己再实现一个;
+- 支持`SPI`,开发者可以省略`driverClassName`配置了。
+
### 1.2.0
-- 更新并适配`dynamic-datasource-spring-boot-starter`至3.1.1版本;
+- 更新并适配`dynamic-datasource-spring-boot-starter`至`3.1.1`版本;
- 优化了`SaaSDataSource`,底层改为使用`ArrayDeque`来实现栈;
- 增加`SaaSDataSource.removeAll`方法,可强制移除所有数据源,包含DynamicDataSource上下文中的数据源。如果你不确定业务流程完成后是否还有残留数据,可在最后(比如拦截器的`afterCompletion`中)调用此方法来确保移除。
diff --git a/pom.xml b/pom.xml
index 135f442..9007a89 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.air-software
saas-datasource-spring-boot-starter
- 1.2.0
+ 1.3.0
jar
saas-datasource-spring-boot-starter
@@ -51,13 +51,13 @@
org.springframework.boot
spring-boot-starter-web
+ 2.1.1.RELEASE
provided
- 2.0.5.RELEASE
com.baomidou
dynamic-datasource-spring-boot-starter
- 3.1.1
+ 3.4.1
com.alibaba
diff --git a/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceAnnotationInterceptor.java b/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceAnnotationInterceptor.java
index f4767e8..9866cc0 100644
--- a/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceAnnotationInterceptor.java
+++ b/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceAnnotationInterceptor.java
@@ -18,7 +18,6 @@
import com.airsoftware.saas.datasource.annotation.SaaS;
import com.airsoftware.saas.datasource.context.SaaSDataSource;
import com.airsoftware.saas.datasource.util.StringUtil;
-import com.baomidou.dynamic.datasource.support.DataSourceClassResolver;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@@ -43,7 +42,7 @@ public class SaaSDataSourceAnnotationInterceptor implements MethodInterceptor {
@Setter
private SaaSDataSourceManager manager;
- private DataSourceClassResolver dataSourceClassResolver = new DataSourceClassResolver();
+ private SaaSDataSourceClassResolver classResolver = new SaaSDataSourceClassResolver();
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
@@ -91,7 +90,7 @@ public Object invoke(MethodInvocation invocation) throws Throwable {
*/
private String getDsKeyField(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
- Class> declaringClass = dataSourceClassResolver.targetClass(invocation);
+ Class> declaringClass = classResolver.targetClass(invocation);
SaaS saas = method.isAnnotationPresent(SaaS.class) ? method.getAnnotation(SaaS.class)
: AnnotationUtils.findAnnotation(declaringClass, SaaS.class);
Assert.notNull(saas, "Can not find @SaaS annotation, please ensure that you put the @SaaS annotation in right place.");
diff --git a/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceClassResolver.java b/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceClassResolver.java
new file mode 100644
index 0000000..f92a49f
--- /dev/null
+++ b/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceClassResolver.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2018-2022 AIR Software.
+ *
+ * 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
+ *
+ * https://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.airsoftware.saas.datasource.core;
+
+import org.aopalliance.intercept.MethodInvocation;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Proxy;
+
+/**
+ * 数据源类解析器
+ *
+ * @author bit
+ */
+public class SaaSDataSourceClassResolver {
+
+ private static boolean mpEnabled = false;
+
+ private static Field mapperInterfaceField;
+
+ static {
+ Class> proxyClass = null;
+ try {
+ proxyClass = Class.forName("com.baomidou.mybatisplus.core.override.MybatisMapperProxy");
+ } catch (ClassNotFoundException e1) {
+ try {
+ proxyClass = Class.forName("com.baomidou.mybatisplus.core.override.PageMapperProxy");
+ } catch (ClassNotFoundException e2) {
+ try {
+ proxyClass = Class.forName("org.apache.ibatis.binding.MapperProxy");
+ } catch (ClassNotFoundException ignored) {
+ }
+ }
+ }
+ if (proxyClass != null) {
+ try {
+ mapperInterfaceField = proxyClass.getDeclaredField("mapperInterface");
+ mapperInterfaceField.setAccessible(true);
+ mpEnabled = true;
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public Class> targetClass(MethodInvocation invocation) throws IllegalAccessException {
+ if (mpEnabled) {
+ Object target = invocation.getThis();
+ Class> targetClass = target.getClass();
+ return Proxy.isProxyClass(targetClass) ? (Class>) mapperInterfaceField.get(Proxy.getInvocationHandler(target)) : targetClass;
+ }
+ return invocation.getMethod().getDeclaringClass();
+ }
+
+}
diff --git a/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceCreator.java b/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceCreator.java
index e114e23..7e46947 100644
--- a/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceCreator.java
+++ b/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceCreator.java
@@ -26,7 +26,6 @@
*
* @author bit
*/
-
public class SaaSDataSourceCreator {
private DynamicDataSourceProperties properties;
@@ -42,7 +41,7 @@ public SaaSDataSourceCreator(DynamicDataSourceProperties properties) {
* @return 数据源
*/
public DataSource createDruidDataSource(DataSourceProperty dataSourceProperty) {
- DruidDataSourceCreator druidDataSourceCreator = new DruidDataSourceCreator(properties.getDruid());
+ DruidDataSourceCreator druidDataSourceCreator = new DruidDataSourceCreator(properties);
dataSourceProperty.setDruid(properties.getDruid());
return druidDataSourceCreator.createDataSource(dataSourceProperty);
}
diff --git a/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceManager.java b/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceManager.java
index 0c8997b..a628701 100644
--- a/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceManager.java
+++ b/src/main/java/com/airsoftware/saas/datasource/core/SaaSDataSourceManager.java
@@ -41,7 +41,7 @@ public class SaaSDataSourceManager {
* @param dsKey
*/
public void addDataSource(String dsKey) {
- Map dsMap = dynamicRoutingDataSource.getCurrentDataSources();
+ Map dsMap = dynamicRoutingDataSource.getDataSources();
// 如果已被缓存则直接返回
if (dsMap != null && dsMap.containsKey(dsKey)) {
return;