fix: 去掉无用代码

This commit is contained in:
tjlygdx
2026-09-09 15:17:10 +08:00
parent 5316a40bb3
commit f28d9ec22d
14 changed files with 1 additions and 934 deletions

View File

@@ -32,17 +32,8 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
</dependency>
</dependencies>
</project>
</project>

View File

@@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>sdk</artifactId>
<groupId>io.dataease</groupId>
<version>${dataease.version}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>distributed</artifactId>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>io.dataease</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>
</project>

View File

@@ -1,12 +0,0 @@
package io.dataease;
import io.dataease.rpc.DeFeignRegister;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@EnableFeignClients
@Import(DeFeignRegister.class)
public class DeFeignConfiguration {
}

View File

@@ -1,34 +0,0 @@
package io.dataease.dds;
import java.util.ArrayDeque;
import java.util.Deque;
public class DynamicContextHolder {
private static final ThreadLocal<Deque<String>> CONTEXT_HOLDER = new ThreadLocal() {
@Override
protected Object initialValue() {
return new ArrayDeque();
}
};
public static String peek() {
return CONTEXT_HOLDER.get().peek();
}
public static void push(String dataSource) {
CONTEXT_HOLDER.get().push(dataSource);
}
public static void poll() {
Deque<String> deque = CONTEXT_HOLDER.get();
deque.poll();
if (deque.isEmpty()) {
CONTEXT_HOLDER.remove();
}
}
}

View File

@@ -1,15 +0,0 @@
package io.dataease.dds;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicContextHolder.peek();
}
}

View File

@@ -1,23 +0,0 @@
package io.dataease.dds.config;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.LinkedHashMap;
import java.util.Map;
@ConfigurationProperties(prefix = "dynamic")
public class DynamicDataSourceProperties {
private Map<String, DataSourceProperties> datasource = new LinkedHashMap<>();
public Map<String, DataSourceProperties> getDatasource() {
return datasource;
}
public void setDatasource(Map<String, DataSourceProperties> datasource) {
this.datasource = datasource;
}
}

View File

@@ -1,95 +0,0 @@
package io.dataease.dds.config;
import com.zaxxer.hikari.HikariDataSource;
import io.dataease.dds.DynamicDataSource;
import io.dataease.dds.constant.DataSourceConstant;
import io.dataease.dds.interceptor.DSInterceptor;
import io.dataease.dds.provider.TenantDatasourceProvider;
import io.dataease.flyway.TenantFlywayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableConfigurationProperties(DynamicDataSourceProperties.class)
public class DynamicDsConfig implements WebMvcConfigurer {
@Value("${de.tenant.ds.lazy:false}")
private Boolean tenantDsLazyLoad;
@Value("${spring.application.name}")
private String appName;
@Autowired
private DynamicDataSourceProperties properties;
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
@Bean
public DynamicDataSource dynamicDataSource(DataSourceProperties dataSourceProperties) {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
//设置多个数据源的map
Map<Object, Object> dynamicDataSourceMap = getDynamicDataSource();
HikariDataSource defaultDataSource = dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
dynamicDataSourceMap.put(DataSourceConstant.DATA_SOURCE_MANAGE, defaultDataSource);
if (!tenantDsLazyLoad) {
Map<String, DataSource> dbInfo = TenantDatasourceProvider.getDbInfo(defaultDataSource);
if (!CollectionUtils.isEmpty(dbInfo)) {
dynamicDataSourceMap.putAll(dbInfo);
}
}
dynamicDataSource.setTargetDataSources(dynamicDataSourceMap);
for (Map.Entry<Object, Object> entry : dynamicDataSourceMap.entrySet()) {
Object key = entry.getKey();
boolean isManage = key.equals(DataSourceConstant.DATA_SOURCE_MANAGE);
try {
TenantFlywayUtil.executeFlyway((HikariDataSource) entry.getValue(), isManage, appName);
} catch (Exception e) {
// 记录日志 循环继续
}
}
//默认数据源
dynamicDataSource.setDefaultTargetDataSource(defaultDataSource);
return dynamicDataSource;
}
/**
* 从配置文件加载额外的数据源
* DE官方库业务库可以从这里加载进去(客户业务库是从数据库读进去)
*
* @return
*/
private Map<Object, Object> getDynamicDataSource() {
Map<String, DataSourceProperties> dataSourcePropertiesMap = properties.getDatasource();
Map<Object, Object> targetDataSources = new HashMap<>(dataSourcePropertiesMap.size());
dataSourcePropertiesMap.forEach((k, v) -> {
HikariDataSource hikariDataSource = v.initializeDataSourceBuilder().type(HikariDataSource.class).build();
targetDataSources.put(k, hikariDataSource);
});
return targetDataSources;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new DSInterceptor());
}
}

View File

@@ -1,20 +0,0 @@
package io.dataease.dds.constant;
public class DataSourceConstant {
/**
* 这里的命名统一在配置文件命名的基础上加dataSource前缀且改小驼峰
* 默认数据源名称
*/
public static final String DATA_SOURCE_MANAGE = "manege-ds";
/**
* 递增可配数据源名称
* 这里的命名统一在配置文件命名的基础上加dataSource前缀且改小驼峰
* 后面可接着 db2... dbn 也可以根据
*/
public static final String DATA_SOURCE_OFFICIAL = "official-ds";
public static final String DS_NAME_PREFIX = "tenant_%s_%s";
}

View File

@@ -1,31 +0,0 @@
package io.dataease.dds.interceptor;
import io.dataease.dds.DynamicContextHolder;
import io.dataease.dds.constant.DataSourceConstant;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
/**
* 不同租户不同二级域名
* nginx下把租户ID以及租户创建时间设置在请求头
* 获取请求头部租户ID和创建时间
* 根据租户ID和创建时间获取租户数据源名称
* 切换数据源
*/
public class DSInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String tenant = request.getHeader("tenant");
String time = request.getHeader("time");
DynamicContextHolder.push(getTenantDsKey(tenant, time));
return true;
}
private String getTenantDsKey(String tenant, String time) {
if (null == tenant || null == time) return "official-ds";
return String.format(DataSourceConstant.DS_NAME_PREFIX, tenant, time);
}
}

View File

@@ -1,142 +0,0 @@
package io.dataease.dds.provider;
import io.dataease.utils.LogUtil;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class TenantDatasourceProvider {
private static final String MYSQL_DRIVER_CLASS_NAME = "com.mysql.cj.jdbc.Driver";
private static final String DS_NAME_PREFIX = "tenant_%s_%s";
private static final String ALL_TENANT_SQL = "select d.*, i.create_time from tenant_db d left join tenant_info i on d.tenant_id = i.id";
private static final String ONE_TENANT_SQL = "select d.*, i.create_time from tenant_db d left join tenant_info i on d.tenant_id = i.id where d.tenant_id = ? ";
/**
* 这里需要加上异常处理
* 某个数据源不能构建成功 continue 不能影响全局
* @param manage
* @return
*/
public static Map<String, DataSource> getDbInfo(DataSource manage) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = manage.getConnection();
statement = connection.prepareStatement(ALL_TENANT_SQL);
resultSet = statement.executeQuery();
List<Map<String, Object>> mapList = parseResultSet(resultSet);
if (!CollectionUtils.isEmpty(mapList)) {
return mapList.stream().collect(Collectors.toMap(TenantDatasourceProvider::getDsKey, TenantDatasourceProvider::buildHikari));
}
} catch (Exception e) {
LogUtil.error(e);
} finally {
close(connection,statement, resultSet);
}
return null;
}
public static Map<String, DataSource> getDbInfo(DataSource manage, Long tenantId) throws Exception{
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = manage.getConnection();
statement = connection.prepareStatement(ONE_TENANT_SQL);
statement.setLong(1, tenantId);
resultSet = statement.executeQuery();
List<Map<String, Object>> mapList = parseResultSet(resultSet);
if (!CollectionUtils.isEmpty(mapList)) {
return mapList.stream().collect(Collectors.toMap(TenantDatasourceProvider::getDsKey, TenantDatasourceProvider::buildHikari));
}
} catch (Exception e) {
LogUtil.error(e);
} finally {
close(connection,statement, resultSet);
}
return null;
}
private static String getDsKey(Map<String, Object> row) {
Long tenantId = (Long) row.get("tenant_id");
Long createTime = (Long) row.get("create_time");
Object dsKeyObj = null;
if (!ObjectUtils.isEmpty((dsKeyObj = row.get("ds_key")))) {
return dsKeyObj.toString();
}
return String.format(DS_NAME_PREFIX, tenantId.toString(), createTime.toString());
}
private static DataSource buildHikari(Map<String, Object> param) {
HikariConfig config = new HikariConfig();
config.setDriverClassName(param.getOrDefault("driver_class", MYSQL_DRIVER_CLASS_NAME).toString());
config.setJdbcUrl(param.get("url").toString());
config.setUsername(param.get("username").toString());
config.setPassword(param.get("pwd").toString());
HikariDataSource hikariDataSource = new HikariDataSource(config);
return hikariDataSource;
}
private static List<Map<String, Object>> parseResultSet(ResultSet resultSet) throws Exception{
List<Map<String, Object>> resultList = new ArrayList<>();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
while (resultSet.next()) {
Map<String, Object> row = new HashMap<>();
for (int i = 1; i <= columnCount; i++) {
Object cellVal = resultSet.getObject(i);
String columnLabel = metaData.getColumnLabel(i);
row.put(columnLabel, cellVal);
}
resultList.add(row);
}
return resultList;
}
public static void close(Connection connection, PreparedStatement statement, ResultSet rs) {
try {
if (connection != null && !connection.isClosed()) {
connection.close();
}
} catch (Exception e) {
LogUtil.error(e);
}
try {
if (statement != null) {
statement.close();
}
} catch (Exception e) {
LogUtil.error(e);
}
try {
if (rs != null && !rs.isClosed()) {
rs.close();
}
} catch (Exception e) {
LogUtil.error(e);
}
}
}

View File

@@ -1,42 +0,0 @@
package io.dataease.flyway;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.configuration.ClassicConfiguration;
import org.flywaydb.core.api.configuration.Configuration;
import javax.sql.DataSource;
import java.nio.charset.Charset;
public class TenantFlywayUtil {
private static final String FLYWAY_MANAGE_TABLE_NAME = "de_manage_version";
private static final String FLYWAY_TABLENAME_FORMAT = "de_tenant_%s_version";
private static final String FLYWAY_LOCATION = "classpath:db/migration";
private static final String FLYWAY_MANAGE_LOCATION = "classpath:db/distributed/manage";
private static Configuration buildConfiguration(DataSource dataSource, boolean isManager, String appName) {
ClassicConfiguration configuration = new ClassicConfiguration();
configuration.setValidateOnMigrate(true);
configuration.setBaselineOnMigrate(true);
configuration.setTable(isManager ? FLYWAY_MANAGE_TABLE_NAME : getVersionTableName(appName));
configuration.setEncoding(Charset.forName("utf-8"));
configuration.setOutOfOrder(true);
configuration.setBaselineVersionAsString("1");
configuration.setLocationsAsStrings(isManager ? FLYWAY_MANAGE_LOCATION : FLYWAY_LOCATION);
configuration.setDataSource(dataSource);
return configuration;
}
public static void executeFlyway(DataSource dataSource, boolean isManage, String appName) throws Exception {
Configuration configuration = buildConfiguration(dataSource, isManage, appName);
Flyway flyway = new Flyway(configuration);
flyway.migrate();
}
private static String getVersionTableName(String appName) {
return String.format(FLYWAY_TABLENAME_FORMAT, appName);
}
}

View File

@@ -1,408 +0,0 @@
package io.dataease.rpc;
import feign.Request;
import io.dataease.feign.DeFeign;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.config.*;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.cloud.openfeign.*;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.*;
public class DeFeignRegister implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {
private ResourceLoader resourceLoader;
private Environment environment;
public DeFeignRegister() {
}
static void validateFallback(final Class clazz) {
Assert.isTrue(!clazz.isInterface(), "Fallback class must implement the interface annotated by @DeFeign");
}
static void validateFallbackFactory(final Class clazz) {
Assert.isTrue(!clazz.isInterface(), "Fallback factory must produce instances "
+ "of fallback classes that implement the interface annotated by @DeFeign");
}
static String getName(String name) {
if (!StringUtils.hasText(name)) {
return "";
}
String host = null;
try {
String url;
if (!name.startsWith("http://") && !name.startsWith("https://")) {
url = "http://" + name;
} else {
url = name;
}
host = new URI(url).getHost();
} catch (URISyntaxException ignored) {
}
Assert.state(host != null, "Service id not legal hostname (" + name + ")");
return name;
}
static String getUrl(String url) {
if (StringUtils.hasText(url) && !(url.startsWith("#{") && url.contains("}"))) {
if (!url.contains("://")) {
url = "http://" + url;
}
try {
new URL(url);
} catch (MalformedURLException e) {
throw new IllegalArgumentException(url + " is malformed", e);
}
}
return url;
}
static String getPath(String path) {
if (StringUtils.hasText(path)) {
path = path.trim();
if (!path.startsWith("/")) {
path = "/" + path;
}
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
}
return path;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
registerDeFeigns(metadata, registry);
}
public void registerDeFeigns(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
LinkedHashSet<BeanDefinition> candidateComponents = new LinkedHashSet<>();
Map<String, Object> attrs = metadata.getAnnotationAttributes(EnableFeignClients.class.getName());
final Class<?>[] clients = attrs == null ? null : (Class<?>[]) attrs.get("clients");
if (clients == null || clients.length == 0) {
ClassPathScanningCandidateComponentProvider scanner = getScanner();
scanner.setResourceLoader(this.resourceLoader);
scanner.addIncludeFilter(new AnnotationTypeFilter(DeFeign.class));
Set<String> basePackages = getBasePackages(metadata);
for (String basePackage : basePackages) {
candidateComponents.addAll(scanner.findCandidateComponents(basePackage));
}
} else {
for (Class<?> clazz : clients) {
candidateComponents.add(new AnnotatedGenericBeanDefinition(clazz));
}
}
for (BeanDefinition candidateComponent : candidateComponents) {
if (candidateComponent instanceof AnnotatedBeanDefinition beanDefinition) {
// verify annotated class is an interface
AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
Assert.isTrue(annotationMetadata.isInterface(), "@DeFeign can only be specified on an interface");
Map<String, Object> attributes = annotationMetadata
.getAnnotationAttributes(DeFeign.class.getCanonicalName());
registerDeFeign(registry, annotationMetadata, attributes);
}
}
}
private void registerDeFeign(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata,
Map<String, Object> attributes) {
String className = annotationMetadata.getClassName();
if (String.valueOf(false).equals(
environment.getProperty("spring.cloud.openfeign.lazy-attributes-resolution", String.valueOf(false)))) {
eagerlyRegisterDeFeignBeanDefinition(className, attributes, registry);
} else {
lazilyRegisterDeFeignBeanDefinition(className, attributes, registry);
}
}
private void eagerlyRegisterDeFeignBeanDefinition(String className, Map<String, Object> attributes,
BeanDefinitionRegistry registry) {
validate(attributes);
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);
definition.addPropertyValue("url", getUrl(null, attributes));
definition.addPropertyValue("path", getPath(null, attributes));
String name = getName(attributes);
definition.addPropertyValue("name", name);
String contextId = getContextId(null, attributes);
definition.addPropertyValue("contextId", contextId);
definition.addPropertyValue("type", className);
definition.addPropertyValue("dismiss404", Boolean.parseBoolean(String.valueOf(attributes.get("dismiss404"))));
Object fallback = attributes.get("fallback");
if (fallback != null) {
definition.addPropertyValue("fallback",
(fallback instanceof Class ? fallback : ClassUtils.resolveClassName(fallback.toString(), null)));
}
Object fallbackFactory = attributes.get("fallbackFactory");
if (fallbackFactory != null) {
definition.addPropertyValue("fallbackFactory", fallbackFactory instanceof Class ? fallbackFactory
: ClassUtils.resolveClassName(fallbackFactory.toString(), null));
}
definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory"));
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
definition.addPropertyValue("refreshableClient", isClientRefreshEnabled());
String[] qualifiers = getQualifiers(attributes);
if (ObjectUtils.isEmpty(qualifiers)) {
qualifiers = new String[]{contextId + "DeFeign"};
}
// This is done so that there's a way to retrieve qualifiers while generating AOT
// code
definition.addPropertyValue("qualifiers", qualifiers);
AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
beanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, className);
// has a default, won't be null
boolean primary = (Boolean) attributes.get("primary");
beanDefinition.setPrimary(primary);
BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className, qualifiers);
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
registerRefreshableBeanDefinition(registry, contextId, Request.Options.class, OptionsFactoryBean.class);
registerRefreshableBeanDefinition(registry, contextId, RefreshableUrl.class, RefreshableUrlFactoryBean.class);
}
private void lazilyRegisterDeFeignBeanDefinition(String className, Map<String, Object> attributes,
BeanDefinitionRegistry registry) {
ConfigurableBeanFactory beanFactory = registry instanceof ConfigurableBeanFactory
? (ConfigurableBeanFactory) registry : null;
Class clazz = ClassUtils.resolveClassName(className, null);
String contextId = getContextId(beanFactory, attributes);
String name = getName(attributes);
FeignClientFactoryBean factoryBean = new FeignClientFactoryBean();
factoryBean.setBeanFactory(beanFactory);
factoryBean.setName(name);
factoryBean.setContextId(contextId);
factoryBean.setType(clazz);
factoryBean.setRefreshableClient(isClientRefreshEnabled());
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(clazz, () -> {
factoryBean.setUrl(getUrl(beanFactory, attributes));
factoryBean.setPath(getPath(beanFactory, attributes));
factoryBean.setDismiss404(Boolean.parseBoolean(String.valueOf(attributes.get("dismiss404"))));
Object fallback = attributes.get("fallback");
if (fallback != null) {
factoryBean.setFallback(fallback instanceof Class ? (Class<?>) fallback
: ClassUtils.resolveClassName(fallback.toString(), null));
}
Object fallbackFactory = attributes.get("fallbackFactory");
if (fallbackFactory != null) {
factoryBean.setFallbackFactory(fallbackFactory instanceof Class ? (Class<?>) fallbackFactory
: ClassUtils.resolveClassName(fallbackFactory.toString(), null));
}
return factoryBean.getObject();
});
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
definition.setLazyInit(true);
validate(attributes);
AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
beanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, className);
beanDefinition.setAttribute("DeFeignsRegistrarFactoryBean", factoryBean);
// has a default, won't be null
boolean primary = (Boolean) attributes.get("primary");
beanDefinition.setPrimary(primary);
String[] qualifiers = getQualifiers(attributes);
if (ObjectUtils.isEmpty(qualifiers)) {
qualifiers = new String[]{contextId + "DeFeign"};
}
BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className, qualifiers);
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
registerRefreshableBeanDefinition(registry, contextId, Request.Options.class, OptionsFactoryBean.class);
registerRefreshableBeanDefinition(registry, contextId, RefreshableUrl.class, RefreshableUrlFactoryBean.class);
}
private void validate(Map<String, Object> attributes) {
AnnotationAttributes annotation = AnnotationAttributes.fromMap(attributes);
validateFallback(annotation.getClass("fallback"));
validateFallbackFactory(annotation.getClass("fallbackFactory"));
}
/* for testing */ String getName(Map<String, Object> attributes) {
return getName(null, attributes);
}
String getName(ConfigurableBeanFactory beanFactory, Map<String, Object> attributes) {
String name = (String) attributes.get("serviceId");
if (!StringUtils.hasText(name)) {
name = (String) attributes.get("name");
}
if (!StringUtils.hasText(name)) {
name = (String) attributes.get("value");
}
name = resolve(beanFactory, name);
return getName(name);
}
private String getContextId(ConfigurableBeanFactory beanFactory, Map<String, Object> attributes) {
String contextId = (String) attributes.get("contextId");
if (!StringUtils.hasText(contextId)) {
return getName(attributes);
}
contextId = resolve(beanFactory, contextId);
return getName(contextId);
}
private String resolve(ConfigurableBeanFactory beanFactory, String value) {
if (StringUtils.hasText(value)) {
if (beanFactory == null) {
return this.environment.resolvePlaceholders(value);
}
BeanExpressionResolver resolver = beanFactory.getBeanExpressionResolver();
String resolved = beanFactory.resolveEmbeddedValue(value);
if (resolver == null) {
return resolved;
}
Object evaluateValue = resolver.evaluate(resolved, new BeanExpressionContext(beanFactory, null));
if (evaluateValue != null) {
return String.valueOf(evaluateValue);
}
return null;
}
return value;
}
private String getUrl(ConfigurableBeanFactory beanFactory, Map<String, Object> attributes) {
String url = resolve(beanFactory, (String) attributes.get("url"));
return getUrl(url);
}
private String getPath(ConfigurableBeanFactory beanFactory, Map<String, Object> attributes) {
String path = resolve(beanFactory, (String) attributes.get("path"));
return getPath(path);
}
protected ClassPathScanningCandidateComponentProvider getScanner() {
return new ClassPathScanningCandidateComponentProvider(false, this.environment) {
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
boolean isCandidate = false;
if (beanDefinition.getMetadata().isIndependent()) {
if (!beanDefinition.getMetadata().isAnnotation()) {
isCandidate = true;
}
}
return isCandidate;
}
};
}
protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
Map<String, Object> attributes = importingClassMetadata
.getAnnotationAttributes(EnableFeignClients.class.getCanonicalName());
Set<String> basePackages = new HashSet<>();
for (String pkg : (String[]) attributes.get("value")) {
if (StringUtils.hasText(pkg)) {
basePackages.add(pkg);
}
}
for (String pkg : (String[]) attributes.get("basePackages")) {
if (StringUtils.hasText(pkg)) {
basePackages.add(pkg);
}
}
for (Class<?> clazz : (Class[]) attributes.get("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName()));
}
return basePackages;
}
private String getQualifier(Map<String, Object> client) {
if (client == null) {
return null;
}
String qualifier = (String) client.get("qualifier");
if (StringUtils.hasText(qualifier)) {
return qualifier;
}
return null;
}
private String[] getQualifiers(Map<String, Object> client) {
if (client == null) {
return null;
}
List<String> qualifierList = new ArrayList<>(Arrays.asList((String[]) client.get("qualifiers")));
qualifierList.removeIf(qualifier -> !StringUtils.hasText(qualifier));
if (qualifierList.isEmpty() && getQualifier(client) != null) {
qualifierList = Collections.singletonList(getQualifier(client));
}
return !qualifierList.isEmpty() ? qualifierList.toArray(new String[0]) : null;
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
/**
* This method registers beans definition with refreshScope.
*
* @param registry spring bean definition registry
* @param contextId name of feign client
* @param beanType type of bean
* @param factoryBeanType points to a relevant bean factory
*/
private void registerRefreshableBeanDefinition(BeanDefinitionRegistry registry, String contextId, Class<?> beanType,
Class<?> factoryBeanType) {
if (isClientRefreshEnabled()) {
String beanName = beanType.getCanonicalName() + "-" + contextId;
BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(factoryBeanType);
definitionBuilder.setScope("refresh");
definitionBuilder.addPropertyValue("contextId", contextId);
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(definitionBuilder.getBeanDefinition(),
beanName);
definitionHolder = ScopedProxyUtils.createScopedProxy(definitionHolder, registry, true);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}
}
private boolean isClientRefreshEnabled() {
return environment.getProperty("spring.cloud.openfeign.client.refresh-enabled", Boolean.class, false);
}
}

View File

@@ -1,31 +0,0 @@
-- ----------------------------
-- Table structure for tenant_info
-- ----------------------------
DROP TABLE IF EXISTS `tenant_info`;
CREATE TABLE `tenant_info`
(
`id` bigint NOT NULL COMMENT '租户ID',
`domain` varchar(255) NOT NULL COMMENT '二级域名',
`account` varchar(255) NOT NULL COMMENT '管理员账号',
`pwd` varchar(255) NOT NULL COMMENT '管理员密码',
`company` varchar(255) DEFAULT NULL COMMENT '租户公司',
`create_time` bigint NOT NULL COMMENT '创建时间',
`update_time` bigint DEFAULT NULL COMMENT '修改时间',
`enable` tinyint(1) NOT NULL COMMENT '是否可用',
`deleted` tinyint(1) NOT NULL COMMENT '是否已删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Table structure for tenant_db
-- ----------------------------
DROP TABLE IF EXISTS `tenant_db`;
CREATE TABLE `tenant_db`
(
`id` bigint NOT NULL COMMENT '数据源ID',
`tenant_id` bigint NOT NULL COMMENT '租户ID',
`url` varchar(255) NOT NULL COMMENT 'jdbcurl',
`username` varchar(255) NOT NULL COMMENT 'db用户',
`pwd` varchar(255) NOT NULL COMMENT 'db密码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@@ -15,7 +15,6 @@
<modules>
<module>common</module>
<module>api</module>
<module>distributed</module>
<module>extensions</module>
</modules>