content: package cn.datax.service.data.standard.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.processor.DsProcessor;
  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.DynamicDataSourceProperties;
  import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.druid.DruidDynamicDataSourceConfiguration;
  import lombok.AllArgsConstructor;
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.beans.factory.config.BeanDefinition;
  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 javax.sql.DataSource;
  import java.util.Map;
  
  /**
   * 动态数据源核心自动配置类
   * @author AllDataDC
   * @date 2023/03/17
   */
  @Slf4j
  @Configuration
  @AllArgsConstructor
  @EnableConfigurationProperties(DynamicDataSourceProperties.class)
  @AutoConfigureBefore(DataSourceAutoConfiguration.class)
  @Import(value = {DruidDynamicDataSourceConfiguration.class, DynamicDataSourceCreatorAutoConfiguration.class})
  @ConditionalOnProperty(prefix = DynamicDataSourceProperties.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true)
  public class DynamicDSConfiguration {
  	
      private final DynamicDataSourceProperties properties;
  
      //读取多数据源配置，注入到spring容器中
      @Bean
      @ConditionalOnMissingBean
      public DynamicDataSourceProvider dynamicDataSourceProvider() {
          Map<String, DataSourceProperty> datasourceMap = properties.getDatasource();
          return new YmlDynamicDataSourceProvider(datasourceMap);
      }
  
      //注册自己的动态多数据源DataSource
      @Bean
      @ConditionalOnMissingBean
      public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
          DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
          dataSource.setPrimary(properties.getPrimary());
          dataSource.setStrict(properties.getStrict());
          dataSource.setStrategy(properties.getStrategy());
          dataSource.setProvider(dynamicDataSourceProvider);
          dataSource.setP6spy(properties.getP6spy());
          dataSource.setSeata(properties.getSeata());
          return dataSource;
      }
  
      //AOP切面，对DS注解过的方法进行增强，达到切换数据源的目的
      @Role(value = BeanDefinition.ROLE_INFRASTRUCTURE)
      @Bean
      @ConditionalOnMissingBean
      public DynamicDataSourceAnnotationAdvisor dynamicDatasourceAnnotationAdvisor(DsProcessor dsProcessor) {
          DynamicDataSourceAnnotationInterceptor interceptor = new DynamicDataSourceAnnotationInterceptor(properties.isAllowedPublicOnly(), dsProcessor);
          DynamicDataSourceAnnotationAdvisor advisor = new DynamicDataSourceAnnotationAdvisor(interceptor);
          advisor.setOrder(properties.getOrder());
          return advisor;
      }
  
  }