1.引入jar包
1 <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter --> 2 <dependency> 3 <groupId>com.alibaba</groupId> 4 <artifactId>druid-spring-boot-starter</artifactId> 5 <version>1.1.21</version> 6 </dependency>
2.在application.properties中添加数据源(其中ql/ql1为数据源名称,可以自定义,可配置多个)
1 spring.datasource.druid.ql.type=com.alibaba.druid.pool.DruidDataSource 2 spring.datasource.druid.ql.driver-class-name=com.mysql.jdbc.Driver 3 spring.datasource.druid.ql.url =jdbc:mysql://127.0.0.1/ql?Unicode=true&characterEncoding=UTF-8 4 spring.datasource.druid.ql.username=root 5 spring.datasource.druid.ql.password=root 6 7 spring.datasource.druid.ql.initialSize=5 8 spring.datasource.druid.ql.minIdle=5 9 spring.datasource.druid.ql.maxActive=20 10 spring.datasource.druid.ql.maxWait=60000 11 spring.datasource.druid.ql.timeBetweenEvictionRunsMillis=60000 12 spring.datasource.druid.ql.minEvictableIdleTimeMillis=300000 13 spring.datasource.druid.ql.validationQuery=SELECT 1 14 spring.datasource.druid.ql.testWhileIdle=true 15 spring.datasource.druid.ql.testOnBorrow=false 16 spring.datasource.druid.ql.testOnReturn=false 17 spring.datasource.druid.ql.poolPreparedStatements=true 18 spring.datasource.druid.ql.maxPoolPreparedStatementPerConnectionSize=20 19 spring.datasource.druid.ql.filters=stat,wall,slf4j 20 21 22 spring.datasource.druid.ql.type=com.alibaba.druid.pool.DruidDataSource 23 spring.datasource.druid.ql.driver-class-name=com.mysql.jdbc.Driver 24 spring.datasource.druid.ql.url =jdbc:mysql://127.0.0.1/ql?Unicode=true&characterEncoding=UTF-8 25 spring.datasource.druid.ql.username=root 26 spring.datasource.druid.ql.password=root 27 28 spring.datasource.druid.ql1.initialSize=5 29 spring.datasource.druid.ql1.minIdle=5 30 spring.datasource.druid.ql1.maxActive=20 31 spring.datasource.druid.ql1.maxWait=60000 32 spring.datasource.druid.q1.timeBetweenEvictionRunsMillis=60000 33 spring.datasource.druid.ql1.minEvictableIdleTimeMillis=300000 34 spring.datasource.druid.ql1.validationQuery=SELECT 1 35 spring.datasource.druid.ql1.testWhileIdle=true 36 spring.datasource.druid.ql1.testOnBorrow=false 37 spring.datasource.druid.ql1.testOnReturn=false 38 spring.datasource.druid.ql1.poolPreparedStatements=true 39 spring.datasource.druid.ql1.maxPoolPreparedStatementPerConnectionSize=20 40 spring.datasource.druid.ql1.filters=stat,wall,slf4j
3.配置动态数据源 DynamicDataSource.java,初始化数据源
1 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; 2 3 import javax.sql.DataSource; 4 import java.util.Map; 5 6 /** 7 * 动态数据源 8 * @author zy 9 * @date 2020-05-20 10 */ 11 public class DynamicDataSource extends AbstractRoutingDataSource { 12 private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); 13 14 /** 15 * 配置DataSource, defaultTargetDataSource为主数据库 16 */ 17 public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) { 18 super.setDefaultTargetDataSource(defaultTargetDataSource); 19 super.setTargetDataSources(targetDataSources); 20 super.afterPropertiesSet(); 21 } 22 23 @Override 24 protected Object determineCurrentLookupKey() { 25 return getDataSource(); 26 } 27 28 public static void setDataSource(String dataSource) { 29 contextHolder.set(dataSource); 30 } 31 32 public static String getDataSource() { 33 return contextHolder.get(); 34 } 35 36 public static void clearDataSource() { 37 contextHolder.remove(); 38 } 39 40 }
4.多数据源配置
DataSourceAspect.java(配置切面)
1 import java.lang.reflect.Method; 2 3 import org.aspectj.lang.ProceedingJoinPoint; 4 import org.aspectj.lang.annotation.Around; 5 import org.aspectj.lang.annotation.Aspect; 6 import org.aspectj.lang.annotation.Pointcut; 7 import org.aspectj.lang.reflect.MethodSignature; 8 import org.slf4j.Logger; 9 import org.slf4j.LoggerFactory; 10 import org.springframework.core.Ordered; 11 import org.springframework.stereotype.Component; 12 13 /** 14 * 数据源AOP切面处理 15 * @author zy 16 * @date 2020-05-20 17 */ 18 @Aspect 19 @Component 20 public class DataSourceAspect implements Ordered { 21 protected Logger logger = LoggerFactory.getLogger(getClass()); 22 23 /** 24 * 切点: 所有配置 DataSource 注解的方法 25 */ 26 @Pointcut("@annotation(com.ql.config.DataSource)") 27 public void dataSourcePointCut() {} 28 29 @Around("dataSourcePointCut()") 30 public Object around(ProceedingJoinPoint point) throws Throwable { 31 MethodSignature signature = (MethodSignature) point.getSignature(); 32 Method method = signature.getMethod(); 33 DataSource ds = method.getAnnotation(DataSource.class); 34 // 通过判断 DataSource 中的值来判断当前方法应用哪个数据源 35 DynamicDataSource.setDataSource(ds.value()); 36 System.out.println("当前数据源: " + ds.value()); 37 logger.debug("set datasource is " + ds.value()); 38 try { 39 return point.proceed(); 40 } finally { 41 DynamicDataSource.clearDataSource(); 42 logger.debug("clean datasource"); 43 } 44 } 45 46 @Override 47 public int getOrder() { 48 return 1; 49 } 50 }
DataSource.java(自定义注解,默认为ql)
3 import java.lang.annotation.Documented; 4 import java.lang.annotation.ElementType; 5 import java.lang.annotation.Retention; 6 import java.lang.annotation.RetentionPolicy; 7 import java.lang.annotation.Target; 8 9 /** 10 * 多数据源注解 11 * @author zy 12 * @date 2020-05-20 13 */ 14 @Documented 15 @Target({ElementType.METHOD}) 16 @Retention(RetentionPolicy.RUNTIME) 17 public @interface DataSource { 18 String value() default DataSourceNames.QL; 19 }
DynamicDataSourceConfig.java(数据源切换类)
1 import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; 2 import org.springframework.boot.context.properties.ConfigurationProperties; 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5 import org.springframework.context.annotation.Primary; 6 7 import javax.sql.DataSource; 8 import java.util.HashMap; 9 import java.util.Map; 10 11 /** 12 * 配置多数据源 13 * @author zy 14 * @date 2020-05-20 15 */ 16 @Configuration 17 public class DynamicDataSourceConfig { 18 19 /** 20 * 创建 DataSource Bean 21 * */ 22 23 @Bean 24 @ConfigurationProperties("spring.datasource.druid.ql") 25 public DataSource qlDataSource(){ 26 DataSource dataSource = DruidDataSourceBuilder.create().build(); 27 return dataSource; 28 } 29 30 @Bean 31 @ConfigurationProperties("spring.datasource.druid.ql1") 32 public DataSource ql1DataSource(){ 33 DataSource dataSource = DruidDataSourceBuilder.create().build(); 34 return dataSource; 35 } 36 37 38 /** 39 * 如果还有数据源,在这继续添加 DataSource Bean 40 * */ 41 42 @Bean 43 @Primary 44 public DynamicDataSource dataSource( 45 DataSource qlDataSource, 46 DataSource ql1DataSource) { 47 Map<Object, Object> targetDataSources = new HashMap<>(6); 48 targetDataSources.put(DataSourceNames.QL, qlDataSource); 49 targetDataSources.put(DataSourceNames.QL1, dmsDataSource); 50 ); 51 // 还有数据源,在targetDataSources中继续添加 52 System.out.println("DataSources:" + targetDataSources); 53 return new DynamicDataSource(qlDataSource, targetDataSources); 54 } 55 }
5.修改启动类中的数据源
1 import org.springframework.boot.SpringApplication; 2 import org.springframework.boot.autoconfigure.SpringBootApplication; 3 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 4 import org.springframework.context.annotation.Import; 5 6 import com.xxl.job.qingling.config.DynamicDataSourceConfig; 7 8 /** 9 * @author zy 10 * 2019-12-23 09:14:46 11 */ 12 /** 13 * 动态数据源配置,需要将自有的配置依赖(DynamicDataSourceConfig),将原有的依赖去除(DataSourceAutoConfiguration) 14 * @author geYang 15 * @date 2018-05-15 16 */ 17 @Import({DynamicDataSourceConfig.class}) 18 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) 19 public class XxlJobExecutorApplication { 20 21 public static void main(String[] args) { 22 SpringApplication.run(XxlJobExecutorApplication.class, args); 23 } 24 25 }
6.配置druid监控
3 import javax.servlet.annotation.WebFilter; 4 5 import org.springframework.boot.web.servlet.FilterRegistrationBean; 6 import org.springframework.boot.web.servlet.ServletRegistrationBean; 7 import org.springframework.context.annotation.Bean; 8 import org.springframework.context.annotation.Configuration; 9 10 import com.alibaba.druid.support.http.StatViewServlet; 11 import com.alibaba.druid.support.http.WebStatFilter; 12 13 //这样的方式不需要在启动类头上添加注解:@ServletComponentScan 14 @Configuration 15 public class DruidConfiguration { 16 17 /** 18 * 注册一个StatViewServlet 19 * @return 20 */ 21 @Bean 22 public ServletRegistrationBean DruidStatViewServle(){ 23 24 //org.springframework.boot.context.embedded.ServletRegistrationBean提供类的进行注册. 25 ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*"); 26 27 //添加初始化参数:initParams 28 29 //白名单: 30 servletRegistrationBean.addInitParameter("allow",""); 31 32 //IP黑名单 (存在共同时,deny优先于allow) : 如果满足deny的话提示:Sorry, you are not permitted to view this page. 33 servletRegistrationBean.addInitParameter("deny",""); 34 35 //登录查看信息的账号密码. 36 servletRegistrationBean.addInitParameter("loginUsername","admin"); 37 servletRegistrationBean.addInitParameter("loginPassword","123456"); 38 39 //是否能够重置数据. 40 servletRegistrationBean.addInitParameter("resetEnable","false"); 41 return servletRegistrationBean; 42 } 43 44 /** 45 * 注册一个:filterRegistrationBean 46 * @return 47 */ 48 @Bean 49 public FilterRegistrationBean druidStatFilter(){ 50 FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter()); 51 52 //添加过滤规则. 53 filterRegistrationBean.addUrlPatterns("/*"); 54 55 //添加不需要忽略的格式信息. 56 filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); 57 58 return filterRegistrationBean; 59 } 60 61 }
7.效果图
启动图:
界面访问:http://ip:port/projectname/druid/login.html
简单分享,完事!