package com.baomidou.samples.mybatisplus3.config;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.aop.DynamicDataSourceAnnotationAdvisor;
import com.baomidou.dynamic.datasource.aop.DynamicDataSourceAnnotationInterceptor;
import com.baomidou.dynamic.datasource.aop.DynamicLocalTransactionAdvisor;
import com.baomidou.dynamic.datasource.processor.DsHeaderProcessor;
import com.baomidou.dynamic.datasource.processor.DsProcessor;
import com.baomidou.dynamic.datasource.processor.DsSessionProcessor;
import com.baomidou.dynamic.datasource.processor.DsSpelExpressionProcessor;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.provider.YmlDynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceCreatorAutoConfiguration;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceHealthCheckConfiguration;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.druid.DruidDynamicDataSourceConfiguration;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Role;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.util.Base64Utils;
import javax.sql.DataSource;
import java.util.Map;
/**
* overwrite DynamicDataSourceAutoConfiguration with DynamicDataSourceAutoConfig
* @author Tony Xi
* @since 2021-11-11
*/
@Configuration
@EnableConfigurationProperties({DynamicDataSourceProperties.class})
@AutoConfigureBefore(
value = {DataSourceAutoConfiguration.class},
name = {"com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure"}
)
@Import({DruidDynamicDataSourceConfiguration.class, DynamicDataSourceCreatorAutoConfiguration.class, DynamicDataSourceHealthCheckConfiguration.class})
@ConditionalOnProperty(
prefix = "spring.datasource.dynamic",
name = {"enabled"},
havingValue = "true",
matchIfMissing = true
)
public class DynamicDataSourceAutoConfig {
private static final Logger log = LoggerFactory.getLogger(com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration.class);
private final DynamicDataSourceProperties properties;
@Bean
@ConditionalOnMissingBean
public DynamicDataSourceProvider dynamicDataSourceProvider() {
Map<String, DataSourceProperty> datasourceMap = this.properties.getDatasource();
return new YmlDynamicDataSourceProvider(datasourceMap);
}
@Bean
@ConditionalOnMissingBean
public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
dynamicDataSourceProvider.loadDataSources();
dataSource.setPrimary(this.properties.getPrimary());
dataSource.setStrict(this.properties.getStrict());
dataSource.setStrategy(this.properties.getStrategy());
dataSource.setProvider(dynamicDataSourceProvider);
dataSource.setP6spy(this.properties.getP6spy());
dataSource.setSeata(this.properties.getSeata());
return dataSource;
}
@Role(2)
@Bean
public Advisor dynamicDatasourceAnnotationAdvisor(DsProcessor dsProcessor) {
DynamicDataSourceAnnotationInterceptor interceptor = new DynamicDataSourceAnnotationInterceptor(this.properties.isAllowedPublicOnly(), dsProcessor);
DynamicDataSourceAnnotationAdvisor advisor = new DynamicDataSourceAnnotationAdvisor(interceptor);
advisor.setOrder(this.properties.getOrder().intValue());
return advisor;
}
@Role(2)
@ConditionalOnProperty(
prefix = "spring.datasource.dynamic",
name = {"seata"},
havingValue = "false",
matchIfMissing = true
)
@Bean
public Advisor dynamicTransactionAdvisor() {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("@annotation(com.baomidou.dynamic.datasource.annotation.DSTransactional)");
return new DefaultPointcutAdvisor(pointcut, new DynamicLocalTransactionAdvisor());
}
@Bean
@ConditionalOnMissingBean
public DsProcessor dsProcessor(BeanFactory beanFactory) {
DsHeaderProcessor headerProcessor = new DsHeaderProcessor();
DsSessionProcessor sessionProcessor = new DsSessionProcessor();
DsSpelExpressionProcessor spelExpressionProcessor = new DsSpelExpressionProcessor();
spelExpressionProcessor.setBeanResolver(new BeanFactoryResolver(beanFactory));
headerProcessor.setNextProcessor(sessionProcessor);
sessionProcessor.setNextProcessor(spelExpressionProcessor);
return headerProcessor;
}
/**
* @author Tony Xi
* @since 2021-11-11
*/
public DynamicDataSourceAutoConfig(DynamicDataSourceProperties properties) {
this.properties = properties;
Map<String, DataSourceProperty> datasource = properties.getDatasource();
for (Map.Entry<String, DataSourceProperty> entry : datasource.entrySet()) {
DataSourceProperty dataSourceProperty = entry.getValue();
String password = dataSourceProperty.getPassword();
String username = dataSourceProperty.getUsername();
System.out.println(entry.getKey() + " --> "+username+", raw password: "+password+", after decode: "+password);
if (password.trim().startsWith("en") || password.trim().startsWith("de")) {
String tmp = password.substring(2);
String pswd = new String(java.util.Base64.getDecoder().decode(tmp));
dataSourceProperty.setPassword(pswd);
}
}
}
public static void main(String[] args) {
String encodeToString = java.util.Base64.getEncoder().encodeToString("111".getBytes());
System.out.println("en"+encodeToString);
}
}