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); } }