第一步、在nacos中加入
spring:
datasource:
master:
url: jdbc:mysql://base-mysql:3306/XXX?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
name: master
initialize: true
filters: stat
slave1:
url: jdbc:mysql://base-mysql:3306/XXX?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
name: slave1
initialize: true
filters: stat
其中的的 base-mysql是配置了host 使用ip即可
这样我们就配置好了两个数据源分别为 master和slave1
之后去到spring 启动页面添加
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
之后自定义的数据源的注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.METHOD
})
public @interface MyDataSource {
String value() default "master";
}
操作数据源
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DynamicDataSourceSwitcher {
static Logger logger = LoggerFactory.getLogger(DynamicDataSourceSwitcher.class);
public static final String Mater = "master";
public static final String Slave1 = "slave1";
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void setDataSource(String name){
logger.info("-------- 设置数据源数据源为 :{} ", name);
contextHolder.set(name);
}
public static String getDataSource(){
if (StringUtils.isEmpty(CONTEXTHOLDER.get())) {
setDataSource(MATER);
}
return contextHolder.get();
}
public static void cleanDataSource(){
contextHolder.remove();
}
}
多数据源bean的配置类
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class MultipleDataSourceConfig {
@Bean("master")
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource createMasterDataSource(){
return new DruidDataSource();
}
@Bean("slave1")
@ConfigurationProperties(prefix = "spring.datasource.slave1")
public DataSource createSlave1DataSource(){
return new DruidDataSource();
}
/**
* 设置动态数据源,通过@Primary 来确定主DataSource
* @return
*/
@Bean
@Primary
public DataSource createDynamicDataSource(@Qualifier("master") DataSource master, @Qualifier("slave1") DataSource slave1){
DynamicDataSource dynamicDataSource = new DynamicDataSource();
//设置默认数据源
dynamicDataSource.setDefaultTargetDataSource(master);
//配置多数据源
Map<Object, Object> map = new HashMap<>();
map.put("master",master);
map.put("slave1",slave1);
dynamicDataSource.setTargetDataSources(map);
return dynamicDataSource;
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
Logger logger = LoggerFactory.getLogger(DynamicDataSource.class);
@Override
protected Object determineCurrentLookupKey() {
logger.info("------------------当前数据源 {}", DynamicDataSourceSwitcher.getDataSource());
return DynamicDataSourceSwitcher.getDataSource();
}
}
创建aop切面
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Aspect
@Component
@Order(1)
public class DynamicDataSourceAspect {
private Logger logger = LoggerFactory.getLogger(DynamicDataSourceAspect.class);
/**
* 切入点只对@Service注解的类上的@DataSource方法生效
* @param myDataSource
*/
@Pointcut(value="@within(org.springframework.stereotype.Service) && @annotation(myDataSource)" )
public void dynamicDataSourcePointCut(MyDataSource myDataSource){}
@Before(value = "dynamicDataSourcePointCut(myDataSource)")
public void switchDataSource(MyDataSource myDataSource) {
DynamicDataSourceSwitcher.setDataSource(myDataSource.value());
}
/**
* 切点执行完后 切换成主数据库
* @param myDataSource
*/
@After(value="dynamicDataSourcePointCut(myDataSource)")
public void after(MyDataSource myDataSource){
DynamicDataSourceSwitcher.cleanDataSource();
}
}
之后在service中使用即可
@Override
@MyDataSource(value = DynamicDataSourceSwitcher.Slave1)
public List<Map> getAllByArticleTitleOne() {
return articleBodysMapper.getAllByArticleTitleOne();
}
这样就成功使用的是Slave1的数据库
之后配置监控页面
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DruidConfig {
/**
* 配置Druid的监控:一个管理后台的Servlet
*/
@Bean
public ServletRegistrationBean<StatViewServlet> statViewServlet() {
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
Map<String, String> initParams = new HashMap<String, String>(16);
//用户名
initParams.put("loginUsername", "admin");
//密码
initParams.put("loginPassword", "123456");
//IP白名单(没有配置或者为空,则允许所有访问)
initParams.put("allow", "");
//IP黑名单 (存在共同时,deny优先于allow)
initParams.put("deny", "");
bean.setInitParameters(initParams);
return bean;
}
@Bean
public FilterRegistrationBean<WebStatFilter> webStatFilter() {
FilterRegistrationBean<WebStatFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new WebStatFilter());
Map<String, String> initParams = new HashMap<>(16);
initParams.put("exclusions", "*.js,*.css,/druid/*");
bean.setInitParameters(initParams);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}
上面配置的就是访问路径和账号密码之类的,
搞好之后就可以通过
服务IP地址+服务名称+/druid/login.html
http://192.168.2.112/other/druid/index.html
访问
或
本机ip+运行服务端口号+/druid/login.html
http://192.168.1.101:6009/druid/login.html
注意配置了spring security记得放行 - /druid/**
服务IP地址+服务名称+/druid/login.html
这种方式我这边会报权限问题刷新一下自动跳转成本机ip+运行服务端口号+/druid/login.html
不知道为什么,明明放行了emm