Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: more detailed Datasouce routing support #697

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,5 @@ public class DynamicDataSourceProperties {
*/
@NestedConfigurationProperty
private DynamicDatasourceAopProperties aop = new DynamicDatasourceAopProperties();

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
import lombok.Data;
import org.springframework.core.Ordered;

import java.util.List;
import java.util.Map;

/**
* 多数据源aop相关配置
*
Expand All @@ -38,4 +41,14 @@ public class DynamicDatasourceAopProperties {
* aop allowedPublicOnly
*/
private Boolean allowedPublicOnly = true;

/**
* aop scanPackagePatterns
*/
private List<String> scanPackagePatterns;

/**
* dynamic datasource routes
*/
private Map<String, String> dsRoutes;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.dynamic.datasource.aop.DynamicDataSourceAnnotationAdvisor;
import com.baomidou.dynamic.datasource.aop.DynamicDataSourceAnnotationInterceptor;
import com.baomidou.dynamic.datasource.aop.DynamicLocalTransactionInterceptor;
import com.baomidou.dynamic.datasource.aop.*;
import com.baomidou.dynamic.datasource.processor.DsJakartaHeaderProcessor;
import com.baomidou.dynamic.datasource.processor.DsJakartaSessionProcessor;
import com.baomidou.dynamic.datasource.processor.DsProcessor;
Expand Down Expand Up @@ -87,6 +85,18 @@ public Advisor dynamicDatasourceAnnotationAdvisor(DsProcessor dsProcessor) {
return advisor;
}

@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Bean
@ConditionalOnProperty(prefix = DynamicDataSourceProperties.PREFIX + ".aop", name = "enabled", havingValue = "true", matchIfMissing = true)
public Advisor dynamicDataSourceNamedAdvisor(DsProcessor dsProcessor) {
DynamicDatasourceAopProperties aopProperties = properties.getAop();
DynamicDataSourceNamedInterceptor interceptor = new DynamicDataSourceNamedInterceptor(dsProcessor);
interceptor.addPatternMap(aopProperties.getDsRoutes());
DynamicDataSourceNamedAdvisor advisor = new DynamicDataSourceNamedAdvisor(interceptor, aopProperties.getScanPackagePatterns());
advisor.setOrder(aopProperties.getOrder() + 1);
return advisor;
}

@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Bean
@ConditionalOnProperty(prefix = DynamicDataSourceProperties.PREFIX, name = "seata", havingValue = "false", matchIfMissing = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
"com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure",
"com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceAutoConfigure"
})
@Import({DruidDynamicDataSourceConfiguration.class, DynamicDataSourceCreatorAutoConfiguration.class, DynamicDataSourceAopConfiguration.class, DynamicDataSourceAssistConfiguration.class})
@Import({DruidDynamicDataSourceConfiguration.class, DynamicDataSourceCreatorAutoConfiguration.class,
DynamicDataSourceAopConfiguration.class, DynamicDataSourceAssistConfiguration.class})
@ConditionalOnProperty(prefix = DynamicDataSourceProperties.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true)
public class DynamicDataSourceAutoConfiguration implements InitializingBean {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.baomidou.dynamic.datasource.aop;

import org.aopalliance.aop.Advice;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractPointcutAdvisor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.PatternMatchUtils;

import java.util.List;

/**
* @author yuhuangbin
*/
public class DynamicDataSourceNamedAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {

/**
* the advice
*/
private final Advice advice;
/**
* the pointcut
*/
private final Pointcut pointcut;


public DynamicDataSourceNamedAdvisor(Advice advice, List<String> scanPackages) {
this.advice = advice;
this.pointcut = new ClassPackageNamedPointCut(scanPackages);
}

@Override
public Pointcut getPointcut() {
return pointcut;
}

@Override
public Advice getAdvice() {
return advice;
}

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (this.advice instanceof BeanFactoryAware) {
((BeanFactoryAware) this.advice).setBeanFactory(beanFactory);
}
}

public static class ClassPackageNamedPointCut implements Pointcut {

private final ClassFilter classFilter;

public ClassPackageNamedPointCut(List<String> packagePatterns) {
this.classFilter = clazz -> !CollectionUtils.isEmpty(packagePatterns)
&& PatternMatchUtils.simpleMatch(packagePatterns.toArray(new String[0]), ClassUtils.getPackageName(clazz));
}

@Override
public ClassFilter getClassFilter() {
return classFilter;
}

@Override
public MethodMatcher getMethodMatcher() {
return MethodMatcher.TRUE;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
* @since 3.4.0
*/
@Slf4j
public class DynamicDatasourceNamedInterceptor implements MethodInterceptor {
public class DynamicDataSourceNamedInterceptor implements MethodInterceptor {

private static final String DYNAMIC_PREFIX = "#";
private final Map<String, String> nameMap = new HashMap<>();
Expand All @@ -50,7 +50,7 @@ public class DynamicDatasourceNamedInterceptor implements MethodInterceptor {
*
* @param dsProcessor dsProcessor
*/
public DynamicDatasourceNamedInterceptor(DsProcessor dsProcessor) {
public DynamicDataSourceNamedInterceptor(DsProcessor dsProcessor) {
this.dsProcessor = dsProcessor;
}

Expand Down Expand Up @@ -126,7 +126,7 @@ private String findDsKey(MethodInvocation invocation) {
}

// Look for direct name match.
String methodName = method.getName();
String methodName = ClassUtils.getQualifiedMethodName(method);
String dsKey = this.nameMap.get(methodName);

if (dsKey == null) {
Expand Down