最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

利用SpringBoot實(shí)現(xiàn)多數(shù)據(jù)源的兩種方式總結(jié)

 更新時(shí)間:2021年10月24日 10:39:14   作者:風(fēng)雪留客  
關(guān)于動態(tài)數(shù)據(jù)源的切換的方案有很多,核心只有兩種,一種是構(gòu)建多套環(huán)境,另一種是基于spring原生的AbstractRoutingDataSource切換,這篇文章主要給大家介紹了關(guān)于利用SpringBoot實(shí)現(xiàn)多數(shù)據(jù)源的兩種方式,需要的朋友可以參考下

前言

公司項(xiàng)目有連接多個(gè)不同數(shù)據(jù)庫的需求,特研究了一下,根據(jù)網(wǎng)上的資料,造了一個(gè)基于AOP方式的數(shù)據(jù)源切換輪子,但繼續(xù)探索,突然發(fā)現(xiàn)有開源的多數(shù)據(jù)源管理啟動器。不過,本篇兩種方式都會介紹。

基于dynamic-datasource實(shí)現(xiàn)多數(shù)據(jù)源

dynamic-datasource介紹

dynamic-datasource-spring-boot-starter 是一個(gè)基于springboot的快速集成多數(shù)據(jù)源的啟動器。

其支持 Jdk 1.7+, SpringBoot 1.4.x 1.5.x 2.x.x

dynamic-datasource特性

  • 支持 數(shù)據(jù)源分組 ,適用于多種場景 純粹多庫 讀寫分離 一主多從 混合模式。
  • 支持?jǐn)?shù)據(jù)庫敏感配置信息 加密 ENC()。
  • 支持每個(gè)數(shù)據(jù)庫獨(dú)立初始化表結(jié)構(gòu)schema和數(shù)據(jù)庫database。
  • 支持無數(shù)據(jù)源啟動,支持懶加載數(shù)據(jù)源(需要的時(shí)候再創(chuàng)建連接)。
  • 支持 自定義注解 ,需繼承DS(3.2.0+)。
  • 提供并簡化對Druid,HikariCp,BeeCp,Dbcp2的快速集成。
  • 提供對Mybatis-Plus,Quartz,ShardingJdbc,P6sy,Jndi等組件的集成方案。
  • 提供 自定義數(shù)據(jù)源來源 方案(如全從數(shù)據(jù)庫加載)。
  • 提供項(xiàng)目啟動后 動態(tài)增加移除數(shù)據(jù)源 方案。
  • 提供Mybatis環(huán)境下的 純讀寫分離 方案。
  • 提供使用 spel動態(tài)參數(shù) 解析數(shù)據(jù)源方案。內(nèi)置spel,session,header,支持自定義。
  • 支持 多層數(shù)據(jù)源嵌套切換 。(ServiceA >>> ServiceB >>> ServiceC)。
  • 提供 基于seata的分布式事務(wù)方案。
  • 提供 本地多數(shù)據(jù)源事務(wù)方案。 附:不能和原生spring事務(wù)混用。

我們目前只探討使用dynamic-datasource進(jìn)行數(shù)據(jù)源切換,其他請自行搜索

dynamic-datasource的相關(guān)約定

  • dynamic-datasource只做 切換數(shù)據(jù)源 這件核心的事情,并不限制你的具體操作,切換了數(shù)據(jù)源可以做任何CRUD。
  • 配置文件所有以下劃線 _ 分割的數(shù)據(jù)源 首部 即為組的名稱,相同組名稱的數(shù)據(jù)源會放在一個(gè)組下。
  • 切換數(shù)據(jù)源可以是組名,也可以是具體數(shù)據(jù)源名稱。組名則切換時(shí)采用負(fù)載均衡算法切換。
  • 默認(rèn)的數(shù)據(jù)源名稱為 master ,你可以通過 spring.datasource.dynamic.primary 修改。
  • 方法上的注解優(yōu)先于類上注解。
  • DS支持繼承抽象類上的DS,暫不支持繼承接口上的DS。

 引入dynamic-datasource依賴

<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
  <version>${version}</version>
</dependency>

配置數(shù)據(jù)源

spring:
  datasource:
    dynamic:
      primary: mysql #設(shè)置默認(rèn)的數(shù)據(jù)源或者數(shù)據(jù)源組,默認(rèn)值即為master
      strict: false #嚴(yán)格匹配數(shù)據(jù)源,默認(rèn)false. true未匹配到指定數(shù)據(jù)源時(shí)拋異常,false使用默認(rèn)數(shù)據(jù)源
      datasource:
        mysql:
          url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver # 3.2.0開始支持SPI可省略此配置
        pgsql:
          url: ENC(xxxxx) # 內(nèi)置加密
          username: ENC(xxxxx)
          password: ENC(xxxxx)
          driver-class-name: org.postgresql.Driver

使用 @DS 切換數(shù)據(jù)源

@DS 可以注解在方法上或類上,同時(shí)存在就近原則 方法上注解 優(yōu)先于 類上注解

注解 結(jié)果
不使用@DS注解 默認(rèn)數(shù)據(jù)源,即primary: mysql
@DS(“dsName”) dsName可以為組名也可以為具體某個(gè)庫的名稱

@DS使用實(shí)例

@Service
@DS("mysql")
public class UserServiceImpl implements UserService {

  @Autowired
  private JdbcTemplate jdbcTemplate;

  // 不使用@DS注解則代表使用默認(rèn)數(shù)據(jù)源
  // 如果類上存在,則使用類上標(biāo)注的數(shù)據(jù)源
  public List selectAll() {
    return  jdbcTemplate.queryForList("select * from user");
  }
  
  @Override
  @DS("pgsql")
  // 方法上注解 優(yōu)先于 類上注解,即使類上標(biāo)注也優(yōu)先采用方法上的標(biāo)注
  public List selectByCondition() {
    return  jdbcTemplate.queryForList("select * from user where age >10");
  }
}

基于AOP手動實(shí)現(xiàn)多數(shù)據(jù)源

本次代碼參考 https://github.com/mianshenglee/my-example/tree/master/multi-datasource/dynamic-datasource ,因源碼不滿足的需求,因此我在此基礎(chǔ)做了修改。

項(xiàng)目工程結(jié)構(gòu)

項(xiàng)目依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>me.mason.demo</groupId>
    <artifactId>dynamic-datasource</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>dynamic-datasource</name>
    <description>Demo project for dynamic datasource</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--spring boot-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!--mysql 驅(qū)動-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

配置文件

server.port=8080
server.servlet.context-path=/dd

logging.level.root=INFO
logging.level.me.mason.demo.dynamicdatasource.mapper=DEBUG

# mybatis-plus
mybatis-plus.type-aliases-package=me.mason.demo.dynamicdatasource.entity
# 默認(rèn)位置,可不配置
#mybatis-plus.mapper-locations=classpath*:/mapper/*.xml
mybatis.mapper-locations=classpath*:/mapper/*.xml
# 使用數(shù)據(jù)庫自增ID
mybatis-plus.global-config.db-config.id-type=auto

# master
spring.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.master.url=jdbc:mysql://10.0.1.243:3306/scheduling?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=UTF-8
spring.datasource.master.username=root
spring.datasource.master.password=123456

# slave
spring.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.slave.url=jdbc:mysql://10.0.1.243:3306/scheduling1?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=UTF-8
spring.datasource.slave.username=root
spring.datasource.slave.password=123456

自定義注解

// 標(biāo)記注解可使用在方法與類上
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DS {
	// 默認(rèn)值為MASTER
    String value() default DataSourceConstants.DS_KEY_MASTER;
}

編寫DataSourceConstants

/**
 * 數(shù)據(jù)源常量
 **/
public class DataSourceConstants {
    /**
     * master數(shù)據(jù)源
     */
    public static final String DS_KEY_MASTER = "master";
    /**
     * slave數(shù)據(jù)源
     */
    public static final String DS_KEY_SLAVE = "slave";
}

動態(tài)數(shù)據(jù)源名稱上下文處理

/**
 * 動態(tài)數(shù)據(jù)源名稱上下文處理
 **/
public class DynamicDataSourceContextHolder {

    /**
     * 動態(tài)數(shù)據(jù)源名稱上下文
     */
    private static final ThreadLocal<String> DATASOURCE_CONTEXT_KEY_HOLDER = new ThreadLocal<>();

    /**
     * 設(shè)置數(shù)據(jù)源
     * @param key
     */
    public static void setContextKey(String key){
        DATASOURCE_CONTEXT_KEY_HOLDER.set(key);
    }

    /**
     * 獲取數(shù)據(jù)源名稱
     * @return
     */
    public static String getContextKey(){
        String key = DATASOURCE_CONTEXT_KEY_HOLDER.get();
        return key == null?DataSourceConstants.DS_KEY_MASTER:key;
    }

    /**
     * 刪除當(dāng)前數(shù)據(jù)源名稱
     */
    public static void removeContextKey(){
        DATASOURCE_CONTEXT_KEY_HOLDER.remove();
    }
}

獲取當(dāng)前動態(tài)數(shù)據(jù)源方法

/**
 * 動態(tài)數(shù)據(jù)源
 **/
public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getContextKey();
    }
}

動態(tài)數(shù)據(jù)源配置

/**
 * 動態(tài)數(shù)據(jù)源配置
 **/
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class })
@Configuration
// 此處我們
//@PropertySource("classpath:config/jdbc.properties")
@MapperScan(basePackages = "me.mason.demo.dynamicdatasource.mapper")
public class DynamicDataSourceConfig {
    @Bean(DataSourceConstants.DS_KEY_MASTER)
    // 需要與配置文件中對應(yīng)
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DruidDataSource masterDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(DataSourceConstants.DS_KEY_SLAVE)
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DruidDataSource slaveDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public DynamicDataSource dynamicDataSource() {
        Map<Object, Object> dataSourceMap = new HashMap<>(2);
        dataSourceMap.put(DataSourceConstants.DS_KEY_MASTER, masterDataSource());
        dataSourceMap.put(DataSourceConstants.DS_KEY_SLAVE, slaveDataSource());
        //設(shè)置動態(tài)數(shù)據(jù)源
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setTargetDataSources(dataSourceMap);
        dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
        return dynamicDataSource;
    }

}

AOP切面

/**
 * 切面
 */
@Aspect
@Component
//@Order(-10)
public class DynamicDataSourceAspect {
	// 以在類上使用了@Service作為切入點(diǎn)
    @Pointcut("@within(org.springframework.stereotype.Service)")
    public void dataSourcePointCut() {
    }

    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Class<?> aClass = Class.forName(signature.getDeclaringType().getName());
        // 方法優(yōu)先,如果方法上存在注解,則優(yōu)先使用方法上的注解
        if (signature.getMethod().isAnnotationPresent(DS.class)) { DynamicDataSourceContextHolder.setContextKey(signature.getMethod().getAnnotation(DS.class).value());
            // 其次類優(yōu)先,如果類上存在注解,則使用類上的注解
        }else  if (aClass.isAnnotationPresent(DS.class)) { DynamicDataSourceContextHolder.setContextKey(aClass.getAnnotation(DS.class).value());
            // 如果都不存在,則使用默認(rèn)
        }   else {
 DynamicDataSourceContextHolder.setContextKey(DataSourceConstants.DS_KEY_MASTER);
        }
        try {
            return joinPoint.proceed();
        } finally {
            DynamicDataSourceContextHolder.removeContextKey();
        }
    }
}

編寫TestUser實(shí)體

@Data
@TableName("test_user")
public class TestUser implements Serializable {

    private static final long serialVersionUID = 1L;

    /** id */
    private Long id;
    /** 姓名 */
    private String name;
    /** 手機(jī)號 */
    private String phone;
    /** 職稱職別 */
    private String title;
    /** 郵箱 */
    private String email;
    /** 性別 */
    private String gender;
    /** 出生時(shí)間 */
    private Date dateOfBirth;
    /** 1:已刪除,0:未刪除 */
    private Integer deleted;
    /** 創(chuàng)建時(shí)間 */
    private Date sysCreateTime;
    /** 創(chuàng)建人 */
    private String sysCreateUser;
    /** 更新時(shí)間 */
    private Date sysUpdateTime;
    /** 更新人 */
    private String sysUpdateUser;
    /** 版本號 */
    private Long recordVersion;

    public TestUser() {
    }

}

TestUserMapper

@Repository
public interface TestUserMapper extends BaseMapper<TestUser> {

    /**
     * 自定義查詢
     * @param wrapper 條件構(gòu)造器
     * @return
     */
    List<TestUser> selectAll(@Param(Constants.WRAPPER) Wrapper<TestUser> wrapper);
}

TestUserService

@Service
//@DS(DataSourceConstants.DS_KEY_SLAVE)
public class TestUserService {
    @Autowired
    private TestUserMapper testUserMapper;

    /**
     * 查詢master庫User
     * @return
     */
//    @DS(DataSourceConstants.DS_KEY_MASTER)
    public List<TestUser> getMasterUser(){
        QueryWrapper<TestUser> queryWrapper = new QueryWrapper<>();
        return testUserMapper.selectAll(queryWrapper.isNotNull("name"));
    }

    /**
     * 查詢slave庫User
     * @return
     */
//    @DS(DataSourceConstants.DS_KEY_MASTER)
    public List<TestUser> getSlaveUser(){
        return testUserMapper.selectList(null);
    }
}

TestUserController

@RestController
@RequestMapping("/user")
public class TestUserController {
    @Autowired
    private TestUserService testUserService;
    /**
     * 查詢?nèi)?
     */
    @GetMapping("/listall")
    public Object listAll() {
        int initSize = 2;
        Map<String, Object> result = new HashMap<>(initSize);
        List<TestUser> masterUser = testUserService.getMasterUser();
        result.put("masterUser", masterUser);
        List<TestUser> slaveUser = testUserService.getSlaveUser();
        result.put("getSlaveUser", slaveUser);
        return ResponseResult.success(result);
    }

}

MapperXml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="me.mason.demo.dynamicdatasource.mapper.TestUserMapper">
    <select id="selectAll" resultType="me.mason.demo.dynamicdatasource.entity.TestUser">
        select * from test_user
        <if test="ew!=null">
          ${ew.customSqlSegment}
        </if>
    </select>
</mapper>

啟動測試

不使用注解

@Service
//@DS(DataSourceConstants.DS_KEY_SLAVE)
public class TestUserService {
    @Autowired
    private TestUserMapper testUserMapper;


    /**
     * 查詢master庫User
     * @return
     */
//    @DS(DataSourceConstants.DS_KEY_MASTER)
    public List<TestUser> getMasterUser(){
        QueryWrapper<TestUser> queryWrapper = new QueryWrapper<>();
        return testUserMapper.selectAll(queryWrapper.isNotNull("name"));
    }

    /**
     * 查詢slave庫User
     * @return
     */
//    @DS(DataSourceConstants.DS_KEY_MASTER)
    public List<TestUser> getSlaveUser(){
        return testUserMapper.selectList(null);
    }

}

效果

該代碼優(yōu)先級與使用框架效果一致,即不使用注解將默認(rèn)使用MASTER數(shù)據(jù)庫,方法上存在注解優(yōu)先使用方法上標(biāo)注的注解。

已知MASTER 6條數(shù)據(jù), SLAVE4條數(shù)據(jù)

訪問 http://127.0.0.1:8080/dd/user/listall 查看效果

類上使用注解

@Service
@DS(DataSourceConstants.DS_KEY_SLAVE)
public class TestUserService {
    @Autowired
    private TestUserMapper testUserMapper;


    /**
     * 查詢master庫User
     * @return
     */
//    @DS(DataSourceConstants.DS_KEY_MASTER)
    public List<TestUser> getMasterUser(){
        QueryWrapper<TestUser> queryWrapper = new QueryWrapper<>();
        return testUserMapper.selectAll(queryWrapper.isNotNull("name"));
    }

    /**
     * 查詢slave庫User
     * @return
     */
//    @DS(DataSourceConstants.DS_KEY_MASTER)
    public List<TestUser> getSlaveUser(){
        return testUserMapper.selectList(null);
    }
}

效果

方法上使用注解

@Service
@DS(DataSourceConstants.DS_KEY_SLAVE)
public class TestUserService {
    @Autowired
    private TestUserMapper testUserMapper;
    /**
     * 查詢master庫User
     * @return
     */
    @DS(DataSourceConstants.DS_KEY_SLAVE)
    public List<TestUser> getMasterUser(){
        QueryWrapper<TestUser> queryWrapper = new QueryWrapper<>();
        return testUserMapper.selectAll(queryWrapper.isNotNull("name"));
    }
    /**
     * 查詢slave庫User
     * @return
     */
    @DS(DataSourceConstants.DS_KEY_MASTER)
    public List<TestUser> getSlaveUser(){
        return testUserMapper.selectList(null);
    }
}

效果

總結(jié)

到此這篇關(guān)于利用SpringBoot實(shí)現(xiàn)多數(shù)據(jù)源的兩種方式的文章就介紹到這了,更多相關(guān)SpringBoot實(shí)現(xiàn)多數(shù)據(jù)源內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java緩存池代碼實(shí)例詳解

    Java緩存池代碼實(shí)例詳解

    本篇文章主要介紹了Java實(shí)現(xiàn)簡單的緩存方法實(shí)例,需要的朋友可以參考下
    2017-04-04
  • @CacheEvict注解,清除緩存方式

    @CacheEvict注解,清除緩存方式

    這篇文章主要介紹了@CacheEvict注解,清除緩存方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Spring Boot命令行運(yùn)行器的實(shí)現(xiàn)方法

    Spring Boot命令行運(yùn)行器的實(shí)現(xiàn)方法

    這篇文章主要介紹了Spring Boot命令行運(yùn)行器的實(shí)現(xiàn)方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-10-10
  • Jackson自定義序列化反序列化注解加解密字段詳解

    Jackson自定義序列化反序列化注解加解密字段詳解

    這篇文章主要介紹了Jackson自定義序列化反序列化注解加解密字段詳解,一些場景中,數(shù)據(jù)庫字段用于存儲json格式數(shù)據(jù),處于安全的考慮,該json數(shù)據(jù)中,某些敏感信息字段需要做加密存儲,例如身份證號、手機(jī)號等,需要的朋友可以參考下
    2023-11-11
  • 通過Java實(shí)現(xiàn)中文分詞與文本關(guān)鍵詞提取

    通過Java實(shí)現(xiàn)中文分詞與文本關(guān)鍵詞提取

    這篇文章主要為大家詳細(xì)介紹了如何利用Java實(shí)現(xiàn)中文分詞以及文本關(guān)鍵詞提取功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)學(xué)習(xí)
    2023-06-06
  • Spring+SpringMVC+MyBatis整合實(shí)戰(zhàn)(SSM框架)

    Spring+SpringMVC+MyBatis整合實(shí)戰(zhàn)(SSM框架)

    框架整合難不難?難!東西多,配置文件復(fù)雜不好記憶,本文就來介紹一下Spring+SpringMVC+MyBatis整合實(shí)戰(zhàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2021-08-08
  • 一文詳解Java二分查找算法

    一文詳解Java二分查找算法

    二分查找(binary search),也稱折半搜索,是一種在有序數(shù)組中查找某一特定元素的搜索算法,接下來就來給大家講講都有哪些查找算法,以及經(jīng)典的二分查找法該如何實(shí)現(xiàn),需要的朋友可以參考下
    2023-07-07
  • Java如何使用poi生成簡單word文檔并導(dǎo)出

    Java如何使用poi生成簡單word文檔并導(dǎo)出

    這篇文章主要介紹了Java如何使用poi生成簡單word文檔并導(dǎo)出問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Spring Security方法鑒權(quán)的實(shí)現(xiàn)

    Spring Security方法鑒權(quán)的實(shí)現(xiàn)

    在Spring Security中,主要有兩種鑒權(quán)方式,一個(gè)是基于web請求的鑒權(quán),一個(gè)是基于方法的鑒權(quán),本文就來介紹一下Spring Security方法鑒權(quán)的實(shí)現(xiàn),感興趣的可以了解一下
    2023-12-12
  • Spring Shell打Jar包時(shí)常用小技巧

    Spring Shell打Jar包時(shí)常用小技巧

    這篇文章主要介紹了Spring Shell打Jar包時(shí)常用小技巧,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10

最新評論

金门县| 雷波县| 剑川县| 宜君县| 庆元县| 普宁市| 澄迈县| 孝昌县| 怀集县| 望城县| 揭东县| 两当县| 宽城| 南投市| 阿勒泰市| 南陵县| 饶河县| 无为县| 高平市| 伊宁市| 岳阳县| 武乡县| 天津市| 哈密市| 克什克腾旗| 香格里拉县| 甘洛县| 鄂尔多斯市| 砀山县| 化隆| 威海市| 赤城县| 安宁市| 三河市| 遂川县| 饶河县| 永嘉县| 保定市| 松滋市| 太白县| 特克斯县|