Spring 多数据源配置详解

简介: 前言数据源是 JDBC 规范中用来获取关系型数据库连接的一个接口,主要通过池化技术来复用连接。

前言


数据源是 JDBC 规范中用来获取关系型数据库连接的一个接口,主要通过池化技术来复用连接。


简单点的 Java 项目或者拆分比较彻底的微服务模块中只会用到一个数据库实例,对应一个数据源。稍复杂点的项目,由于各种原因可能会使用到多个数据库实例,这些数据库可能属于不同的业务模块,可能用于分库分表,也可能用于读写分离。


使用多个数据库的情况下需要为每个数据库配置一个数据源,这本身并没有什么技术难度,重点在于如何在使用多数据源的情况下还能加入 Spring 的事务管理,这篇文章会详细介绍各种持久化技术如何在 Spring 中达到这个目标。


方案选型


在实现多数据源加入 Spring 事务管理这个大目标的前提下,我们需要做进一步的拆解。


主要需要考虑到多个数据源是否需要加入到一个事务中。


如果每个数据源对应一个事务可以使用单机事务,这个与在单数据源的情况下是类似的。

如果多个数据源需要加入到一个事务则只能使用分布式事务。


单机事务


在单机事务的情况下,每个数据源可以分别对应一个 Spring 事务管理器,也可以多个数据源使用一个事务管理器。由于 Spring 的事务管理会把数据源作为 key 存入线程上下文,所以一个线程下只能有一个数据源加入事务。


多事务管理器


单机事务情况下使用多个事务管理器,可以让每个数据源分别对应一个事务管理器,这和在单数据源的情况下是类似的,可以使用如下的图来表述。


image.png


不管哪种持久化技术,多个数据源配置多个事务管理器,在具体配置和使用事务方面都是类似的,可以概括为如下的流程。


为每个数据库分别配置一个数据源。

为每个数据源配置具体持久化技术操作数据库的核心类。

为每个数据源配置一个事务管理器。

为要加入事务的方法指定使用哪个事务管理器。

Spring 中常用的持久化技术主要就是 JdbcTemplate、MyBatis、Hibernate、JPA,本篇中的示例假定单数据源情况下你对 Spring 整合这些持久化技术具有一定的了解,限于篇幅本篇不会在细节上涉及太多,可点击链接了解更多内容。


下面看各持久化技术的多数据源多事务管理器如何进行配置与使用,不感兴趣的内容可直接跳过。


JdbcTemplate


如果业务比较简单,又不想引入其他依赖,可以使用 Spring 自带的 JdbcTemplate,假定有两个数据源,可以做如下配置。


@Configuration
@EnableTransactionManagement
public class JdbcTemplateConfiguration {
    // 第一个数据源的相关配置
    @Bean
    public DataSource dataSource1() {
        DataSource dataSource = ...;
        return dataSource;
    }
    @Bean
    public JdbcTemplate jdbcTemplate1() {
        return new JdbcTemplate(dataSource1());
    }
    @Bean
    public TransactionManager transactionManager1() {
        PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dataSource1());
        return transactionManager;
    }
    // 第二个数据源的相关配置
    @Bean
    public DataSource dataSource2() {
        DataSource dataSource = ...;
        return dataSource;
    }
    @Bean
    public JdbcTemplate jdbcTemplate2() {
        return new JdbcTemplate(dataSource2());
    }
    @Bean
    public TransactionManager transactionManager2() {
        PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dataSource2());
        return transactionManager;
    }
}


主要就是每个数据源配置一套 DataSourceJdbcTemplateTransactionManager,对应关系如下。


数据源

JdbcTemplate 事务管理器
dataSource1 jdbcTemplate1 transactionManager1
dataSource2

jdbcTemplate2

transactionManager2


一个方法内可以使用不同的数据源操作数据库,那么具体加入哪个事务管理器管理的事务呢呢?可以在 @Transactional 注解上指定事务管理器。

@Service
public class UserService {
    @Qualifier("jdbcTemplate1")
    @Autowired
    private JdbcTemplate jdbcTemplate1;
    @Qualifier("jdbcTemplate2")
    @Autowired
    private JdbcTemplate jdbcTemplate2;
    @Transactional(transactionManager = "transactionManager1")
    public List<User> list1() {
        return jdbcTemplate1.query("select * from user", new UserRowMapper());
    }
    @Transactional(transactionManager = "transactionManager2")
    public List<User> list2() {
        return jdbcTemplate2.query("select * from user", new UserRowMapper());
    }
}


不过不建议在一个方法内使用多个数据源,Spring 基于线程上下文的事务设计导致只有指定的事务管理器内部的数据源会加入事务中。


MyBatis


除了 JdbcTemplate,另一个最常用的 ORM 框架是 MyBatis,多个数据源的情况下在 Spring 中可以做如下的配置。


@Configuration
@EnableTransactionManagement
@MapperScan(basePackages = "com.zzuhkp.mybatis.mapper1", sqlSessionFactoryRef = "sqlSessionFactory1")
@MapperScan(basePackages = "com.zzuhkp.mybatis.mapper2", sqlSessionFactoryRef = "sqlSessionFactory2")
public class MyBatisConfiguration {
    // 第一个数据源的相关配置
    @Bean
    public DataSource dataSource1() {
        DataSource dataSource = ...;
        return dataSource;
    }
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory1() {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 设置数据源
        sqlSessionFactoryBean.setDataSource(dataSource1());
        ...省略部分代码
        return sqlSessionFactoryBean;
    }
    @Bean
    public TransactionManager transactionManager1() {
        TransactionManager transactionManager = new DataSourceTransactionManager(dataSource1());
        return transactionManager;
    }
    // 第二个数据源的相关配置
    @Bean
    public DataSource dataSource2() {
        DataSource dataSource = ...;
        return dataSource;
    }
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory2() {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 设置数据源
        sqlSessionFactoryBean.setDataSource(dataSource2());
        ...省略部分代码
        return sqlSessionFactoryBean;
    }
    @Bean
    public TransactionManager transactionManager2() {
        TransactionManager transactionManager = new DataSourceTransactionManager(dataSource2());
        return transactionManager;
    }
}


主要就是为每个数据源配置一套 DataSource、SqlSessionFactoryBean、TransactionManager,以及配置 @MapperScan 注解。


@MapperScan 中的 basePackages 和 sqlSessionFactoryRef 属性将不同包下面 Mapper 底层的 SqlSession 区分开。


经过上面的配置后,各组件对应关系如下。


数据源

SqlSessionFactory

事务管理器

Mapper
dataSource1 sqlSessionFactory1 transactionManager1 com.zzuhkp.mybatis.mapper1
dataSource2 sqlSessionFactory2 transactionManager2 com.zzuhkp.mybatis.mapper2


由于 Spring 容器中存在多个事务管理器,必须要在事务方法的 @Transactional 注解上指定使用哪个事务管理器,示例如下。


@Service
public class UserService {
    @Autowired
    private UserMapper1 userMapper1;
    @Autowired
    private UserMapper2 userMapper2;
    @Transactional(transactionManager = "transactionManager1")
    public List<User> list1() {
        return userMapper1.list();
    }
    @Transactional(transactionManager = "transactionManager2")
    public List<User> list2() {
        return userMapper2.list();
    }
}


Hibernate


Hibernate 在前些年使用比较多,两个数据源的情况下在 Spring 中可以做如下配置。


@Configuration
@EnableTransactionManagement
public class HibernateConfiguration {
    // 第一个数据源的相关配置
    @Bean
    public DataSource dataSource1() {
        DataSource dataSource = ...
        return dataSource;
    }
    @Bean
    public LocalSessionFactoryBean sessionFactory1() {
        LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
        ...省略配置内容
        return factoryBean;
    }
    @Bean
    public TransactionManager transactionManager1(@Qualifier("sessionFactory1") SessionFactory sessionFactory1) {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory1);
        transactionManager.setDataSource(dataSource1());
        return transactionManager;
    }
    // 第二个数据源的相关配置
    @Bean
    public DataSource dataSource2() {
        DataSource dataSource = ...
        return dataSource;
    }
    @Bean
    public LocalSessionFactoryBean sessionFactory2() {
        LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
        ...省略配置内容
        return factoryBean;
    }
    @Bean
    public TransactionManager transactionManager2(@Qualifier("sessionFactory2") SessionFactory sessionFactory2) {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory2);
        transactionManager.setDataSource(dataSource1());
        return transactionManager;
    }
}


为每套数据源分别配置了 DataSourceLocalSessionFactoryBeanTransactionManager,对应关系如下。


数据源

LocalSessionFactoryBean 事务管理器
dataSource1 sessionFactory1 transactionManager1
dataSource2 sessionFactory2 transactionManager2


同样需要在事务方法的 @Transactional 注解上指定要使用的事务管理器。


@Service
public class UserService {
    @Qualifier("sessionFactory1")
    @Autowired
    private SessionFactory sessionFactory1;
    @Qualifier("sessionFactory2")
    @Autowired
    private SessionFactory sessionFactory2;
    @Qualifier("jdbcTemplate2")
    @Autowired
    private JdbcTemplate jdbcTemplate2;
    @Transactional(transactionManager = "transactionManager1")
    public List<User> list1() {
        return sessionFactory1.getCurrentSession().createSQLQuery("select * from user").list();
    }
    @Transactional(transactionManager = "transactionManager2")
    public List<User> list2() {
        return sessionFactory2.getCurrentSession().createSQLQuery("select * from user").list();
    }
}


JPA


基于 JPA 规范操作数据库可以随时替换实现,是 Hibernate 的另一个选择。使用 spring-data-jpa 模块,第一个数据源的配置如下。


@Configuration
@EnableJpaRepositories(basePackages = "com.zzuhkp.jpa.repository1",
        entityManagerFactoryRef = "entityManagerFactory1",
        transactionManagerRef = "transactionManager1")
@EnableTransactionManagement
public class JpaConfiguration1 {
    @Bean
    public DataSource dataSource1() {
        DataSource dataSource = ...
        return dataSource;
    }
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory1() {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource1());
        ...省略部分配置
        return entityManagerFactoryBean;
    }
    @Bean
    public TransactionManager transactionManager1(@Qualifier("entityManagerFactory1") EntityManagerFactory entityManagerFactory1) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory1);
        transactionManager.setDataSource(dataSource1());
        return transactionManager;
    }
}


第二个数据源与第一个数据源的配置类似,不再列出,主要就是为每个数据源配置一套 DataSource、EntityManagerFactory、TransactionManager,以及为创建 Repository 接口实例提供 @EnableJpaRepositories,由于 @EnableJpaRepositories 不支持重复注解,可为每个数据源分别提供一个配置类,各组件对应关系如下。


数据源

EntityManagerFactory 事务管理器 Repository

dataSource1

entityManagerFactory1

transactionManager1

com.zzuhkp.jap.repository1

dataSource2

entityManagerFactory2 transactionManager2 com.zzuhkp.jap.repository2


事务方法配置事务管理器的示例如下。


@Service
public class UserService {
    @Autowired
    private UserRepository1 userRepository1;
    @Autowired
    private UserRepository2 userRepository2;
    @Transactional(transactionManager = "transactionManager1")
    public List<User> list1() {
        return userRepository1.findAll();
    }
    @Transactional(transactionManager = "transactionManager2")
    public List<User> list2() {
        return userRepository2.findAll();
    }
}


单事务管理器


多个数据源配置单个事务管理器的好处是可以避免在事务方法上指定要使用的事务管理器。由于每个事务管理器内部只有一个数据源,因此只能使用一个动态数据源,使得在进入事务方法前,Spring 事务管理使用动态数据源路由到的目标数据源获取连接。


多个事务管理器与单个事务管理器的区别可以用如下的图示来表示。


1111.png


我们的重点也将放在如何在动态数据源内部路由目标数据源。Spring 内部提供了一个 AbstractRoutingDataSource 数据源类用于路由目标数据源,实现比较简单,主要就是将目标数据源以 key-value 的形式存入到内部,由用户决定获取目标数据源的 key。


以 JdbcTemplate 持久化技术为例,可以修改上述示例中的配置如下。


@Configuration
@EnableTransactionManagement
public class JdbcTemplateConfiguration {
    // 第一个数据源的相关配置
    @Bean
    public DataSource dataSource1() {
        DataSource dataSource = ...;
        return dataSource;
    }
    @Bean
    public DataSource dataSource2() {
        DataSource dataSource = ...;
        return dataSource;
    }
    @Bean
    @Primary
    public DataSource primaryDataSource() {
        // 目标数据源
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("dataSource1", dataSource1());
        targetDataSources.put("dataSource2", dataSource2());
        AbstractRoutingDataSource dataSource = new AbstractRoutingDataSource() {
            @Override
            protected Object determineCurrentLookupKey() {
                return DataSourceKeyHolder.get();
            }
        };
        dataSource.setTargetDataSources(targetDataSources);
        dataSource.setDefaultTargetDataSource(dataSource1());
        return dataSource;
    }
    @Bean
    public JdbcTemplate jdbcTemplate1() {
        return new JdbcTemplate(primaryDataSource());
    }
    @Bean
    public TransactionManager transactionManager() {
        PlatformTransactionManager transactionManager = new DataSourceTransactionManager(primaryDataSource());
        return transactionManager;
    }
}


和前面的示例相比,主要是加了一个主数据源,由主数据源路由目标数据源,两个 JdbcTemplate 合并为一个使用主数据源的 JdbcTemplate,两个事务管理器合并为一个使用主数据源的事务管理器。


主数据源是一个实现 AbstractRoutingDataSource 抽象类的动态数据源,这个类只有一个用于获取目标数据源 key 值的 determineCurrentLookupKey 方法需要实现,此外再设置一下可用的目标数据源以及默认数据源就可以了。


在获取 key 值的时候则使用到了我们自定义的 DataSourceKeyHolder.get() 方法,这个方法也比较简单,主要就是将 key 放在线程上下文中,可以在进行事务方法前手动设置 key,也可以利用 AOP 拦截方法,根据方法所在的包名、类名、或者方法上的注解动态设置 key。


DataSourceKeyHolder 定义如下。


public class DataSourceKeyHolder {
    private static ThreadLocal<String> threadLocal = new ThreadLocal<>();
    public static String get() {
        return threadLocal.get();
    }
    public static void set(String key) {
        threadLocal.set(key);
    }
}


假如我们想利用 AOP,在不同的包下面使用不同的数据源,可以配置如下的切面。


@Aspect
@Component
public class DataSourceAop {
    @Around("execution(* com.zzuhkp.template.business1..*.*(..))")
    public Object dataSource1(ProceedingJoinPoint joinPoint) throws Throwable {
        return advice(joinPoint, "datasource1");
    }
    @Around("execution(* com.zzuhkp.template.business2..*.*(..))")
    public Object dataSource2(ProceedingJoinPoint joinPoint) throws Throwable {
        return advice(joinPoint, "datasource2");
    }
    private Object advice(ProceedingJoinPoint joinPoint, String key) throws Throwable {
        String prevKey = DataSourceKeyHolder.get();
        DataSourceKeyHolder.set(key);
        try {
            return joinPoint.proceed();
        } catch (Exception e) {
            throw e;
        } finally {
            DataSourceKeyHolder.set(prevKey);
        }
    }
}


经过这样的配置,com.zzuhkp.template.business1 包将使用 dataSource1 数据源,com.zzuhkp.template.business2 包将使用 dataSource2 数据源。

service 示例如下。


package com.zzuhkp.template.business1;
@Service
public class Business1Service {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Transactional(rollbackFor = Exception.class)
    public void doSomething(){
        jdbcTemplate.update("...");
    }
}


Business1Service 类在 business1 包中,将使用 dataSource1 作为数据源并加入 Spring 事务管理。


由于主数据源被设置为 Primary,spring-boot 环境下还能利用自动化配置的特性,用户只需要配置数据源就可以了,其他的工作可以由具体的持久化技术对应的 spring-boot-starter 直接完成。


分布式事务


如果想要多个数据源加入一个事务则需要使用分布式事务的一些解决方案,这些解决方案一般来说都比较复杂,能够使用单机事务的情况下务必不要使用分布式事务。


分布式事务的一些常见解决方案包括 XA、TCC、本地消息、事务消息、最大努力通知,等等…


这里介绍是是基于 XA 协议实现的 JTA 在 Spring 中的应用,由于 JTA 只是一套规范,在非 EJB 容器环境下我们可以使用 Atomikos 作为实现。


2222.png


Spring 环境下的 Atomikos 配置如下。


@Configuration
@EnableTransactionManagement
public class JTAConfiguration {
    // 数据源一配置
    @Bean(initMethod = "init", destroyMethod = "close")
    public AtomikosDataSourceBean dataSource1() {
        AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
        ...省略配置
        return ds;
    }
    @Bean
    public JdbcTemplate jdbcTemplate1() {
        return new JdbcTemplate(dataSource1());
    }
    // 数据源二配置
    @Bean(initMethod = "init", destroyMethod = "close")
    public AtomikosDataSourceBean dataSource2() {
        AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
        ...省略配置
        return ds;
    }
    @Bean
    public JdbcTemplate jdbcTemplate2() {
        return new JdbcTemplate(dataSource2());
    }
    // Atomikos 对 JTA 事务管理器的实现
    @Bean(initMethod = "init", destroyMethod = "close")
    public UserTransactionManager userTransactionManager() throws SystemException {
        UserTransactionManager userTransactionManager = new UserTransactionManager();
        userTransactionManager.setTransactionTimeout(300);
        userTransactionManager.setForceShutdown(true);
        return userTransactionManager;
    }
    // Spring 事务管理器
    @Bean
    public JtaTransactionManager jtaTransactionManager() throws SystemException {
        JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
        jtaTransactionManager.setTransactionManager(userTransactionManager());
        jtaTransactionManager.setUserTransaction(userTransactionManager());
        return jtaTransactionManager;
    }
}


我们为每个数据源分别配置了 Atomikos 提供的 DataSource 以及 JdbcTemplate,然后还配置了 Atomikos 提供的 JTA 事务管理器实现以及 Spring 的 JTA 事务管理器。


此时在 Spring 项目中已经可以正常使用事务了,与单机事务完全一致,示例如下。


@Service
public class UserService {
    @Qualifier("jdbcTemplate1")
    @Autowired
    private JdbcTemplate jdbcTemplate1;
    @Qualifier("jdbcTemplate2")
    @Autowired
    private JdbcTemplate jdbcTemplate2;
    @Transactional(rollbackFor = Exception.class)
    public List<User> list1() {
        List<User> list = new ArrayList<>();
        list.addAll(jdbcTemplate1.query("select * from user", new UserRowMapper()));
        list.addAll(jdbcTemplate2.query("select * from user", new UserRowMapper()));
        return list;
    }
}


事务方法内可以使用多个数据源操作数据库,由 Spring 事务管理器协调将这些数据源对数据库的操作加入到一个 JTA 事务中。


总结

本文主要介绍了 Spring 项目中的多个数据源如何加入到 Spring 的事务管理中,包括了多种持久化技术以及单机事务与分布式事务的解决方案,内容相对比较全面了,如果你还有疑问,不妨留言交流。


目录
相关文章
|
2月前
|
负载均衡 监控 Java
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
本文详细介绍了 Spring Cloud Gateway 的核心功能与实践配置。首先讲解了网关模块的创建流程,包括依赖引入(gateway、nacos 服务发现、负载均衡)、端口与服务发现配置,以及路由规则的设置(需注意路径前缀重复与优先级 order)。接着深入解析路由断言,涵盖 After、Before、Path 等 12 种内置断言的参数、作用及配置示例,并说明了自定义断言的实现方法。随后重点阐述过滤器机制,区分路由过滤器(如 AddRequestHeader、RewritePath、RequestRateLimiter 等)与全局过滤器的作用范围与配置方式,提
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
|
2月前
|
Java 关系型数据库 MySQL
Spring Boot自动配置:魔法背后的秘密
Spring Boot 自动配置揭秘:只需简单配置即可启动项目,背后依赖“约定大于配置”与条件化装配。核心在于 `@EnableAutoConfiguration` 注解与 `@Conditional` 系列条件判断,通过 `spring.factories` 或 `AutoConfiguration.imports` 加载配置类,实现按需自动装配 Bean。
|
2月前
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
|
4月前
|
Java Spring
Spring Boot配置的优先级?
在Spring Boot项目中,配置可通过配置文件和外部配置实现。支持的配置文件包括application.properties、application.yml和application.yaml,优先级依次降低。外部配置常用方式有Java系统属性(如-Dserver.port=9001)和命令行参数(如--server.port=10010),其中命令行参数优先级高于系统属性。整体优先级顺序为:命令行参数 &gt; Java系统属性 &gt; application.properties &gt; application.yml &gt; application.yaml。
864 0
|
30天前
|
前端开发 Java 应用服务中间件
《深入理解Spring》 Spring Boot——约定优于配置的革命者
Spring Boot基于“约定优于配置”理念,通过自动配置、起步依赖、嵌入式容器和Actuator四大特性,简化Spring应用的开发与部署,提升效率,降低门槛,成为现代Java开发的事实标准。
|
2月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
481 5
|
2月前
|
传感器 Java 数据库
探索Spring Boot的@Conditional注解的上下文配置
Spring Boot 的 `@Conditional` 注解可根据不同条件动态控制 Bean 的加载,提升应用的灵活性与可配置性。本文深入解析其用法与优势,并结合实例展示如何通过自定义条件类实现环境适配的智能配置。
165 0
探索Spring Boot的@Conditional注解的上下文配置
|
7月前
|
安全 Java API
深入解析 Spring Security 配置中的 CSRF 启用与 requestMatchers 报错问题
本文深入解析了Spring Security配置中CSRF启用与`requestMatchers`报错的常见问题。针对CSRF,指出默认已启用,无需调用`enable()`,只需移除`disable()`即可恢复。对于`requestMatchers`多路径匹配报错,分析了Spring Security 6.x中方法签名的变化,并提供了三种解决方案:分次调用、自定义匹配器及降级使用`antMatchers()`。最后提醒开发者关注版本兼容性,确保升级平稳过渡。
845 2
|
8月前
|
缓存 Java API
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
本文介绍了在Spring Boot中配置Swagger2的方法。通过创建一个配置类,添加`@Configuration`和`@EnableSwagger2`注解,使用Docket对象定义API文档的详细信息,包括标题、描述、版本和包路径等。配置完成后,访问`localhost:8080/swagger-ui.html`即可查看接口文档。文中还提示了可能因浏览器缓存导致的问题及解决方法。
953 0
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
|
3月前
|
安全 算法 Java
在Spring Boot中应用Jasypt以加密配置信息。
通过以上步骤,可以在Spring Boot应用中有效地利用Jasypt对配置信息进行加密,这样即使配置文件被泄露,其中的敏感信息也不会直接暴露给攻击者。这是一种在不牺牲操作复杂度的情况下提升应用安全性的简便方法。
916 10