网站怎么做搜索功能,阿里云邮箱企业版,百度推广登录入口电脑,金坛市政建设有限公司网站目录 前言
1.引入Springboot相关的aop切面依赖 2.创建自定义注解DataSourceKey
3.创建对ThreadLocal类
4.创建aop切面
5.创建动态数据源类
6.创建多数据库连接配置类
7.关键代码讲解
8.nacos主要配置 前言 通过Spring AOP#xff08;面向切面编程#xff09;的功能来动…目录 前言
1.引入Springboot相关的aop切面依赖 2.创建自定义注解DataSourceKey
3.创建对ThreadLocal类
4.创建aop切面
5.创建动态数据源类
6.创建多数据库连接配置类
7.关键代码讲解
8.nacos主要配置 前言 通过Spring AOP面向切面编程的功能来动态地切换数据源。使用Aspect和Component注解通过切面扫描自定义注解获取数据源的key可以在不修改原有业务代码的情况下在service里面的类方法中加入DataSourceKey注解即可访问指定的数据源。
1.引入Springboot相关的aop切面依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId/dependency 2.创建自定义注解DataSourceKey
Target(ElementType.METHOD)
Retention(RetentionPolicy.RUNTIME)
public interface DataSourceKey {//默认使用auth数据库String value() default dataSourceSystem;
}
3.创建对ThreadLocal类 通过线程隔离的方式实现数据源的切换。
package com.example.auth.datasource;/*** 数据库上下文切换对象针对每个线程做不同操作*/
public class DataSourceContextHolder {private static final ThreadLocalString contextHolder new ThreadLocal();public static void setDataSourceKey(String dataSourceKey) {contextHolder.set(dataSourceKey);}public static String getDataSourceKey() {return contextHolder.get();}public static void clearDataSourceKey() {contextHolder.remove();}
}4.创建aop切面 通过包扫描动态切换数据源主要通过扫描注解的方式获取数据源的key值即数据源名称。
package com.example.auth.datasource;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.DeclareAnnotation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/*** 多数据源切面*/
Aspect
Component
public class DatasourceAspect {private Logger logger LoggerFactory.getLogger(DatasourceAspect.class);Before(annotation(dataSourceKey) execution(* com.example.auth.datasource.*.*(..)))public void beforeSwitchDataSource(JoinPoint joinPoint, DataSourceKey dataSourceKey) {String key dataSourceKey.value();logger.info(key:{},key);DataSourceContextHolder.setDataSourceKey(key);}Before(annotation(dataSourceKey) execution(* com.example.auth.service.*.*(..)))public void beforeServiceSwitchDataSource(JoinPoint joinPoint, DataSourceKey dataSourceKey) {String key dataSourceKey.value();logger.info(key:{},key);DataSourceContextHolder.setDataSourceKey(key);}After(annotation(dataSourceKey) execution(* com.example.auth.service.*.*(..)))public void afterServiceSwitchDataSource(JoinPoint joinPoint, DataSourceKey dataSourceKey) {String key dataSourceKey.value();logger.info(key:{},key);DataSourceContextHolder.clearDataSourceKey();}After(annotation(dataSourceKey) execution(* com.example.auth.datasource.*.*(..)) )public void afterSwitchDataSource(JoinPoint joinPoint, DataSourceKey dataSourceKey) {logger.info(key:{},dataSourceKey.value());DataSourceContextHolder.clearDataSourceKey();}}5.创建动态数据源类 通过该类可动态改变数据源名称。
package com.example.auth.datasource;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource {private Logger logger LoggerFactory.getLogger(DynamicDataSource.class);Overrideprotected Object determineCurrentLookupKey() {String key DataSourceContextHolder.getDataSourceKey();logger.info(数据源:{},key);return DataSourceContextHolder.getDataSourceKey();}
}6.创建多数据库连接配置类
package com.example.auth.datasource;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import javax.activation.DataContentHandler;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;/*** 多数据源配置*/
Configuration
MapperScan(basePackages com.example.auth.mapper)
public class MultiDataSourceConfig {private Logger logger LoggerFactory.getLogger(MultiDataSourceConfig.class);Autowiredprivate DataSource dataSourceAuth;Autowiredprivate DataSource dataSourceConsumer;Autowiredprivate DataSource dataSourceMq;Autowiredprivate DataSource dataSourceGateway;Autowiredprivate DataSource dataSourceSystem;AutowiredQualifier(dynamicDataSource)private DataSource dynamicDataSource;Autowiredprivate StringEncryptor stringEncryptor;Bean(name dataSourceAuth)ConfigurationProperties(prefix spring.datasource.auth)public DataSource dataSourceAuth() {return DataSourceBuilder.create().build();}Bean(name dataSourceConsumer)ConfigurationProperties(prefix spring.datasource.consumer)public DataSource dataSourceConsumer() {return DataSourceBuilder.create().build();}Bean(name dataSourceMq)ConfigurationProperties(prefix spring.datasource.mq)public DataSource dataSourceMq() {return DataSourceBuilder.create().build();}Bean(name dataSourceGateway)ConfigurationProperties(prefix spring.datasource.gateway)public DataSource dataSourceGateway() {return DataSourceBuilder.create().build();}Bean(name dataSourceSystem)ConfigurationProperties(prefix spring.datasource.system)public DataSource dataSourceSystem() {return DataSourceBuilder.create().build();}Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor new MybatisPlusInterceptor();//分页插件interceptor.addInnerInterceptor(new PaginationInnerInterceptor());//注册乐观锁插件interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;}Beanpublic StringEncryptor stringEncryptor() {PooledPBEStringEncryptor encryptor new PooledPBEStringEncryptor();SimpleStringPBEConfig config new SimpleStringPBEConfig();config.setPassword(encryptionkey); // 加密密钥config.setAlgorithm(PBEWithHmacSHA512AndAES_256);config.setKeyObtentionIterations(1000);config.setPoolSize(1);config.setProviderName(SunJCE);config.setSaltGeneratorClassName(org.jasypt.salt.RandomSaltGenerator);config.setStringOutputType(base64);encryptor.setConfig(config);return encryptor;}PostConstructpublic void init(){/* String enStr stringEncryptor.encrypt(Root123);String deSTr stringEncryptor.decrypt(N8VBWG5nOHvy5efX3/mlPAmdBykE7iDZFl362LyeaPRXMbLT0PzEIlB/KDXrNYz6);System.out.println(enStrenStr);System.out.println(deSTrdeSTr);*/}/*** 不加* param interceptor* return* throws Exception*/Beanpublic SqlSessionFactory sqlSessionFactory (MybatisPlusInterceptor interceptor) throws Exception {MybatisSqlSessionFactoryBean ssfb new MybatisSqlSessionFactoryBean();ssfb.setDataSource(dynamicDataSource); // 使用 DynamicDataSourcessfb.setPlugins(interceptor);ssfb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(classpath:/mapper/*Mapper.xml));return ssfb.getObject();}Beanpublic DataSource dynamicDataSource() {DynamicDataSource dynamicDataSource new DynamicDataSource();// 假设你有多个数据源需要在这里将它们添加到 targetDataSources 中MapObject, Object targetDataSources new HashMap();targetDataSources.put(dataSourceSystem, dataSourceSystem);targetDataSources.put(dataSourceAuth, dataSourceAuth);targetDataSources.put(dataSourceConsumer, dataSourceConsumer);targetDataSources.put(dataSourceMq, dataSourceMq);targetDataSources.put(dataSourceGateway,dataSourceGateway);dynamicDataSource.setTargetDataSources(targetDataSources);dynamicDataSource.setDefaultTargetDataSource(dataSourceSystem);// 设置默认数据源return dynamicDataSource;}}7.关键代码讲解 注入dynamicDataSource实体通过该实体bean动态获取数据源从而达到随意切换数据源的目的。 单个dataSource的注入如 dataSourceAuth主要是给动态数据源的切换提前准备多数据源。
8.nacos主要配置
spring:datasource:system: driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://localhost:3306/system?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf-8allowMultiQueriestruenullCatalogMeansCurrenttrueusername: rootpassword: ENC(N8VBWG5nOHvy5efX3/mlPAmdBykE7iDZFl362LyeaPRXMbLT0PzEIlB/KDXrNYz6)type: com.alibaba.druid.pool.DruidDataSourcedruid:initial-size: 5min-idle: 1max-active: 10max-wait: 60000validation-query: SELECT 1 FROM DUALtest-on-borrow: falsetest-on-return: falsetest-while-idle: truetime-between-eviction-runs-millis: 60000auth: driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://localhost:3306/auth?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf-8allowMultiQueriestruenullCatalogMeansCurrenttrueusername: rootpassword: ENC(N8VBWG5nOHvy5efX3/mlPAmdBykE7iDZFl362LyeaPRXMbLT0PzEIlB/KDXrNYz6)type: com.alibaba.druid.pool.DruidDataSourcedruid:initial-size: 5min-idle: 1max-active: 10max-wait: 60000validation-query: SELECT 1 FROM DUALtest-on-borrow: falsetest-on-return: falsetest-while-idle: truetime-between-eviction-runs-millis: 60000consumer: driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://localhost:3306/consumer?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf-8allowMultiQueriestruenullCatalogMeansCurrenttrueusername: rootpassword: ENC(N8VBWG5nOHvy5efX3/mlPAmdBykE7iDZFl362LyeaPRXMbLT0PzEIlB/KDXrNYz6)type: com.alibaba.druid.pool.DruidDataSourcedruid:initial-size: 5min-idle: 1max-active: 10max-wait: 60000validation-query: SELECT 1 FROM DUALtest-on-borrow: falsetest-on-return: falsetest-while-idle: truetime-between-eviction-runs-millis: 60000mq: driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://localhost:3306/mq?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf-8allowMultiQueriestruenullCatalogMeansCurrenttrueusername: rootpassword: ENC(N8VBWG5nOHvy5efX3/mlPAmdBykE7iDZFl362LyeaPRXMbLT0PzEIlB/KDXrNYz6)type: com.alibaba.druid.pool.DruidDataSourcedruid:initial-size: 5min-idle: 1max-active: 10max-wait: 60000validation-query: SELECT 1 FROM DUALtest-on-borrow: falsetest-on-return: falsetest-while-idle: truetime-between-eviction-runs-millis: 60000gateway: driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://localhost:3306/gateway?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf-8allowMultiQueriestruenullCatalogMeansCurrenttrueusername: rootpassword: ENC(N8VBWG5nOHvy5efX3/mlPAmdBykE7iDZFl362LyeaPRXMbLT0PzEIlB/KDXrNYz6)type: com.alibaba.druid.pool.DruidDataSourcedruid:initial-size: 5min-idle: 1max-active: 10max-wait: 60000validation-query: SELECT 1 FROM DUALtest-on-borrow: falsetest-on-return: falsetest-while-idle: truetime-between-eviction-runs-millis: 60000