javascript
构建SpringCloud项目基础框架
文章目錄
- 父項目microcloud
- 本地模擬RPC調用
- common-api子模塊
- 創建dto類
- 創建服務接口
- 創建一個對象拷貝的工具類
- provider-dept-8001 子模塊
- bootstrap.yml
- application.yml
- logback-spring.xml
- Swagger配置
- 創建MyBatisPlus配置類
- 部門 數據庫創建腳本
- 創建Dept映射類
- 創建IDeptDAO數據接口
- 在生產端需要提供有業務接口的實現子類
- 啟動類
- 測試
- controller
- common-api子模塊修改
- consumer-springboot-80 子模塊
- application.yml
- controller
- 啟動類
父項目microcloud
添加common-api子模塊
添加 provider-dept-8001 子模塊
添加 consumer-springboot-80 子模塊
New Module
Gradle版本:
版本組合:
springboot : ‘2.2.5.RELEASE’, // SpringBoot版本號
springcloud : ‘Hoxton.SR3’, // SpringCloud版本號
alibabacloud : ‘2.2.1.RELEASE’, // SpringCloudAlibaba版本號
gradle.properties
project_group=com.yootk project_version=1.0.0 project_jdk=11dependencies.gradle
ext.versions = [ // 定義全部的依賴庫版本號springboot : '2.2.5.RELEASE', // SpringBoot版本號springcloud : 'Hoxton.SR3', // SpringCloud版本號alibabacloud : '2.2.1.RELEASE', // SpringCloudAlibaba版本號lombok : '1.18.20', // Lombok版本號junit : '5.6.3', // 配置JUnit測試工具的版本編號junitPlatformLauncher: '1.6.3', // JUnit測試工具運行平臺版本編號mybatisPlus : '3.4.3', // MyBatisPlus的版本號mysql : '8.0.25', // MySQL數據庫驅動版本druid : '1.2.6', // Druid版本號swagger : '3.0.0', // Swagger版本號nacos : '2.0.2', // Nacos版本號 ] ext.libraries = [ // 依賴庫引入配置'spring-boot-gradle-plugin' :"org.springframework.boot:spring-boot-gradle-plugin:${versions.springboot}",'spring-cloud-dependencies' :"org.springframework.cloud:spring-cloud-dependencies:${versions.springcloud}",'spring-cloud-alibaba-dependencies':"com.alibaba.cloud:spring-cloud-alibaba-dependencies:${versions.alibabacloud}",// 以下的配置為與項目用例測試有關的依賴'junit-jupiter-api' :"org.junit.jupiter:junit-jupiter-api:${versions.junit}",'junit-vintage-engine' :"org.junit.vintage:junit-vintage-engine:${versions.junit}",'junit-jupiter-engine' :"org.junit.jupiter:junit-jupiter-engine:${versions.junit}",'junit-platform-launcher' :"org.junit.platform:junit-platform-launcher:${versions.junitPlatformLauncher}",'junit-platform-engine' :"org.junit.platform:junit-platform-engine:${versions.junitPlatformLauncher}",'junit-jupiter-params' :"org.junit.jupiter:junit-jupiter-params:${versions.junit}",'junit-bom' : "org.junit:junit-bom:${versions.junit}",'junit-platform-commons' :"org.junit.platform:junit-platform-commons:${versions.junitPlatformLauncher}",// 以下的配置為Lombok組件有關的依賴'lombok' : "org.projectlombok:lombok:${versions.lombok}",// 以下的配置為數據庫開發有關的依賴'mybatis-plus-boot-starter' : "com.baomidou:mybatis-plus-boot-starter:${versions.mybatisPlus}",'mysql-connector-java' : "mysql:mysql-connector-java:${versions.mysql}",'druid' : "com.alibaba:druid:${versions.druid}",// 以下的配置為Swagger有關的依賴庫'springfox-boot-starter' : "io.springfox:springfox-boot-starter:${versions.swagger}",// 以下的配置為Nacos有關的依賴庫'nacos-client' : "com.alibaba.nacos:nacos-client:${versions.nacos}" ]build.gradle
buildscript { // 定義腳本使用資源apply from: 'dependencies.gradle' // 引入所需要的依賴庫文件repositories { // 腳本資源倉庫maven { url 'https://maven.aliyun.com/repository/public' }}dependencies { // 依賴庫classpath libraries.'spring-boot-gradle-plugin' // SpringBoot插件} } group project_group // 組織名稱 version project_version // 項目版本apply from: 'dependencies.gradle' // 導入依賴配置 def env = System.getProperty("env") ?: 'dev' // 獲取env環境屬性 subprojects { // 配置子項目apply plugin: 'java' // 子模塊插件apply plugin: 'org.springframework.boot' // 引入SpringBoot插件apply plugin: 'io.spring.dependency-management' // 版本號管理sourceCompatibility = project_jdk // 源代碼版本targetCompatibility = project_jdk // 生成類版本repositories { // 配置Gradle倉庫mavenLocal()maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }mavenCentral()jcenter()}dependencyManagement {// 版本控制插件imports {mavenBom libraries.'spring-cloud-dependencies' // SpringCloud依賴管理mavenBom libraries.'spring-cloud-alibaba-dependencies' // SpringCloudAlibaba依賴管理}}dependencies { // 公共依賴庫管理compile('org.springframework.boot:spring-boot-devtools') // 項目熱部署// 以下為測試環境的相關依賴配置testImplementation('org.springframework.boot:spring-boot-starter-test') {exclude group: 'junit', module: 'junit' // 移除Junit4}testImplementation(enforcedPlatform(libraries.'junit-bom')) // 綁定為JUnit5運行testImplementation(libraries.'junit-platform-commons') // Junit5測試組件testImplementation(libraries.'junit-platform-engine') // Junit5測試組件testImplementation(libraries.'junit-jupiter-api') // Junit5測試組件testImplementation(libraries.'junit-vintage-engine') // Junit5測試組件testImplementation(libraries.'junit-jupiter-engine') // Junit5測試組件testImplementation(libraries.'junit-platform-launcher') // Junit5測試組件// 以下為Lombok插件的相關依賴配置compileOnly(libraries.'lombok') // 編譯時生效annotationProcessor(libraries.'lombok') // 注解時生效}sourceSets { // 源代碼目錄配置main { // main及相關子目錄配置java { srcDirs = ['src/main/java'] }resources { srcDirs = ['src/main/resources', "src/main/profiles/$env"] }}test { // test及相關子目錄配置java { srcDirs = ['src/test/java'] }resources { srcDirs = ['src/test/resources'] }}}test { // 配置測試任務useJUnitPlatform() // 使用JUnit測試平臺}task sourceJar(type: Jar, dependsOn: classes) { // 源代碼的打包任務archiveClassifier = 'sources' // 設置文件的后綴from sourceSets.main.allSource // 所有源代碼的讀取路徑}task javadocTask(type: Javadoc) { // JavaDoc文檔打包任務options.encoding = 'UTF-8' // 設置文件編碼source = sourceSets.main.allJava // 定義所有的Java源代碼}task javadocJar(type: Jar, dependsOn: javadocTask) { // 先生成JavaDoc再打包archiveClassifier = 'javadoc' // 文件標記類型from javadocTask.destinationDir // 通過JavadocTask任務中找到目標路徑}tasks.withType(Javadoc) { // 文檔編碼配置options.encoding = 'UTF-8' // 定義編碼}tasks.withType(JavaCompile) { // 編譯編碼配置options.encoding = 'UTF-8' // 定義編碼}artifacts { // 最終的打包的操作任務archives sourceJar // 源代碼打包archives javadocJar // javadoc打包}gradle.taskGraph.whenReady { // 在所有的操作準備好后觸發tasks.each { task -> // 找出所有的任務if (task.name.contains('test')) { // 如果發現有test任務// 如果將enabled設置為true表示要執行測試任務,如果設置為false表示不執行測試任務task.enabled = true}}}[compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8'// 編碼配置 } project(":common-api") { // 進行子模塊的配置dependencies { // 配置模塊所需要的依賴庫compile("org.springframework.boot:spring-boot-starter-web") // SpringBoot依賴compile('org.springframework.cloud:spring-cloud-starter-openfeign')} } project(":provider-dept-8001") { // 部門微服務dependencies {implementation(project(":common-api")) // 導入公共的子模塊implementation(libraries.'mybatis-plus-boot-starter')implementation(libraries.'mysql-connector-java')implementation(libraries.'druid')implementation(libraries.'springfox-boot-starter')// 以下的依賴庫為Nacos注冊中心所需要的依賴配置implementation('com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery') {exclude group: 'com.alibaba.nacos', module: 'nacos-client' // 移除舊版本的Nacos依賴}implementation('com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config') {exclude group: 'com.alibaba.nacos', module: 'nacos-client' // 移除舊版本的Nacos依賴}implementation(libraries.'nacos-client') // 引入與當前的Nacos匹配的依賴庫} } project(":consumer-springboot-80") { // 消費端模塊dependencies {implementation(project(":common-api")) // 導入公共的子模塊implementation('com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery') {exclude group: 'com.alibaba.nacos', module: 'nacos-client' // 移除舊版本的Nacos依賴}implementation(libraries.'nacos-client') // 引入與當前的Nacos匹配的依賴庫} }本地模擬RPC調用
配置文件路徑:C:\Windows\System32\driversletc\hosts
服務提供者主機名稱: 127.0.0.1 provider-dept-8001
服務消費者主機名稱: 127.0.0.1 consumer-springboot-80
common-api子模塊
創建dto類
package com.yootk.common.dto;import lombok.Data;import java.io.Serializable; // 該類主要實現部門數據結構的映射,實現數據的遠程傳輸 @Data // Lombok注解,自動生成所需要的類結構 public class DeptDTO implements Serializable { // 定義數據傳輸類private Long deptno; // 部門編號private String dname; // 部門名稱private String loc; // 部門位置 }創建服務接口
package com.yootk.service;import com.yootk.common.dto.DeptDTO; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam;import java.util.List; import java.util.Map; @FeignClient("dept.provider") // 定義要訪問的微服務實例名稱 public interface IDeptService { // 業務接口/*** 根據部門的編號獲取部門的完整信息* @param id 要查詢的部門編號* @return 編號存在則以DTO對象的形式返回部門數據,如果不存在返回null*/@GetMapping("/provider/dept/get/{deptno}") // 遠程REST接口public DeptDTO get(@PathVariable("deptno") long id);/*** 增加部門對象* @param dto 保存要增加部門的詳細數據* @return 增加成功返回true,否則返回false*/@PostMapping("/provider/dept/add")public boolean add(DeptDTO dto);/*** 列出所有的部門數據信息* @return 全部數據的集合, 如果沒有任何的部門數據則集合為空(size() == 0)*/@GetMapping("/provider/dept/list")public List<DeptDTO> list();/*** 進行部門的分頁數據加載操作* @param currentPage 當前所在頁* @param lineSize 每頁加載的數據行數* @param column 模糊查詢的數據列* @param keyword 模糊查詢關鍵字* @return 部門集合數據以及統計數據,返回的數據項包括:* 1、key = allDepts、value = List集合(部門的全部數據對象)* 2、key = allRecorders、value = 總記錄數;* 3、key = allPages、value = 頁數。*/@GetMapping("/provider/dept/split")public Map<String, Object> split(@RequestParam("cp") int currentPage,@RequestParam("ls") int lineSize,@RequestParam("col") String column,@RequestParam("kw") String keyword); }創建一個對象拷貝的工具類
在Spring 開發框架內部提供有一個BeanUJtils工具類,這個工具類有一個最大的特點就是可以直接實現對象的數據的拷貝操作,可是這個拷貝操作不包含有集合數據的拷貝處理。
package com.yootk.common.util;import org.springframework.beans.BeanUtils;import java.util.ArrayList; import java.util.List; import java.util.function.Supplier;public class DeepBeanUtils extends BeanUtils { // 擴充已有的Bean工具類private DeepBeanUtils() {}/*** 實現List集合對象的拷貝處理* @param sources 原始對象集合* @param target 目標對象集合* @param <S> 源對象類型* @param <T> 目標對象類型* @return 拷貝后的List集合*/public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target) {List<T> list = new ArrayList<>(sources.size()); // 開辟一個新的List集合for (S source : sources) { // 集合迭代T obj = target.get(); // 獲取數據copyProperties(source, obj); // 由父類所提供的拷貝方法list.add(obj); // 增加集合數據}return list; // 返回集合} }provider-dept-8001 子模塊
bootstrap.yml
spring: # Spring配置項cloud: # SpringCloud配置項nacos: # Nacos注冊中心的配置config: # gRPC通訊配置server-addr: nacos-server:8848 # Nacos地址 代理nacos-proxy:8848namespace: 96c23d77-8d08-4648-b750-1217845607ee # 命名空間IDgroup: MICROCLOUD_GROUP # 一般建議大寫cluster-name: MuyanCluster # 配置集群名稱application.yml
server: # 服務端配置port: 8001 # 8001端口 mybatis-plus: # MyBatisPlus配置type-aliases-package: com.yootk.provider.vo # 別名配置 spring:application: # 配置應用信息name: dept.provider # 是微服務的名稱cloud: # Cloud配置nacos: # Nacos注冊中心配置discovery: # 發現服務service: ${spring.application.name} # 使用微服務的名稱作為注冊的服務名稱server-addr: nacos-server:8848 # Nacos服務地址 代理nacos-proxy:8848namespace: 96c23d77-8d08-4648-b750-1217845607ee # 命名空間IDgroup: MICROCLOUD_GROUP # 一般建議大寫cluster-name: MuyanCluster # 配置集群名稱metadata: # 根據自身的需要配置元數據version: 1.0 # 自定義元數據項company: 沐言科技 # 自定義元數據項url: www.yootk.com # 自定義元數據項author: 李興華(爆可愛的小李老師) # 自定義元數據項datasource: # 數據源配置type: com.alibaba.druid.pool.DruidDataSource # 數據源類型driver-class-name: com.mysql.cj.jdbc.Driver # 驅動程序類url: jdbc:mysql://localhost:3306/yootk8001 # 連接地址username: root # 用戶名password: mysqladmin # 連接密碼druid: # druid相關配置initial-size: 5 # 初始化連接池大小min-idle: 10 # 最小維持連接池大小max-active: 50 # 最大支持連接池大小max-wait: 60000 # 最大等待時間time-between-eviction-runs-millis: 60000 # 關閉空閑連接間隔min-evictable-idle-time-millis: 30000 # 連接最小生存時間validation-query: SELECT 1 FROM dual # 狀態檢測test-while-idle: true # 空閑時檢測連接是否有效test-on-borrow: false # 申請時檢測連接是否有效test-on-return: false # 歸還時檢測連接是否有效pool-prepared-statements: false # PSCache緩存max-pool-prepared-statement-per-connection-size: 20 # 配置PS緩存filters: stat, wall, slf4j # 開啟過濾stat-view-servlet: # 監控界面配置enabled: true # 啟用druid監控界面allow: 127.0.0.1 # 訪問白名單login-username: muyan # 用戶名login-password: yootk # 密碼reset-enable: true # 允許重置url-pattern: /druid/* # 訪問路徑web-stat-filter:enabled: true # 啟動URI監控url-pattern: /* # 跟蹤全部服務exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*" # 跟蹤排除filter:slf4j: # 日志enabled: true # 啟用SLF4j監控data-source-log-enabled: true # 啟用數據庫日志statement-executable-sql-log-enable: true # 執行日志result-set-log-enabled: true # ResultSet日志啟用stat: # SQL監控merge-sql: true # 合并統計log-slow-sql: true # 慢執行記錄slow-sql-millis: 1 # 慢SQL執行時間wall: # SQL防火墻enabled: true # SQL防火墻config: # 防火墻規則multi-statement-allow: true # 允許執行批量SQLdelete-allow: false # 禁止執行刪除語句aop-patterns: "com.yootk.provider.action.*,com.yootk.provider.service.*,com.yootk.provider.dao.*" # Spring監控logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="60 seconds" debug="false"><contextName>logback</contextName><!-- 定義控制臺輸出匹配格式 --><substitutionProperty name="logging.pattern.console"value="%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([%X{requestId}]) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%ewtpc}"/><!-- 定義日志文件輸出匹配格式 --><substitutionProperty name="logging.pattern.file"value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} %clr([%X{requestId}]) ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%ewtpc}"/><conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/><conversionRule conversionWord="wtpc" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/><conversionRule conversionWord="ewtpc" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/><appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <!-- 控制臺輸出 --><layout class="ch.qos.logback.classic.PatternLayout"> <!-- 使用layout節點 --><pattern>${logging.pattern.console}</pattern> <!-- 格式引用 --></layout></appender><!-- 將每天的日志保存在一個文件之中 --><appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"><Prudent>true</Prudent><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 設置日志保存路徑,本次按照月份創建日志目錄,而后每天的文件歸檔到一組 --><FileNamePattern>muyan-logs/%d{yyyy-MM}/yootk_%d{yyyy-MM-dd}.log</FileNamePattern><MaxHistory>365</MaxHistory><!-- 刪除超過365天的日志文件 --></rollingPolicy><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>INFO</level> <!-- 保存ERROR及以上級別的日志 --></filter><encoder><Pattern>${logging.pattern.file}</Pattern> <!-- 格式引用 --></encoder></appender><appender name="druidSqlFile" class="ch.qos.logback.core.rolling.RollingFileAppender"><Prudent>true</Prudent><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 設置日志保存路徑,本次按照月份創建日志目錄,而后每天的文件歸檔到一組 --><FileNamePattern>druid-logs/%d{yyyy-MM}/yootk_druid_slow_sql_%d{yyyy-MM-dd}.log</FileNamePattern><MaxHistory>365</MaxHistory><!-- 刪除超過365天的日志文件 --></rollingPolicy><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>ERROR</level> <!-- 保存ERROR及以上級別的日志 --></filter><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern><charset>utf-8</charset></encoder></appender><logger name="com.alibaba.druid.filter.stat.StatFilter" level="ERROR"><appender-ref ref="druidSqlFile"/></logger><logger name="com.yootk.provider.dao" level="DEBUG"/> <!-- 局部日志級別 --><root level="INFO"> <!-- 全局日志級別 --><appender-ref ref="console"/><appender-ref ref="file"/></root> </configuration>Swagger配置
package com.yootk.provider.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket;@Configuration public class SwaggerConfig { // Swagger配置類private ApiInfo getApiInfo() { // 文檔之中的頭部的信息項return new ApiInfoBuilder().title("【沐言科技】部門微服務").description("實現部門數據的統一管理,包括:增加部門信息、查詢部門信息、部門列表顯示等,此處省略5000字...").termsOfServiceUrl("https://www.yootk.com").contact(new Contact("爆可愛的小李老師", "edu.yootk.com", "784420216@qq.com")).license("沐言科技 - 授權管理").version("1.0.0").build();}@Beanpublic Docket getDocker() { // 所有的詳細描述在此類中定義return new Docket(DocumentationType.SWAGGER_2) // 使用的文檔版本類型.apiInfo(this.getApiInfo()).select() // 所有的接口一定要放在指定的包中.apis(RequestHandlerSelectors.basePackage("com.yootk.provider.action")).paths(PathSelectors.any()).build();} }swagger安全配置
雖然當前已經成功的實現了所需要的REST接口描述文檔顯示,但是這個文檔顯示本身會存在有一些設計上的缺陷,他沒有提供安全保護,只要是個人,可以訪問到你的服務器,那么就都可以進行服務調用。.
如果要想解決這種文檔的安全訪問的問題,唯一的做法就是使用SpringSecurity 來實現開發,因為這個框架是與SpringBoot深入綁定在一起的,那么使用它進行開發是最佳的做法。
父項目的build.gradle配置
project(":provider-dept-8001") { // 部門微服務dependencies {implementation(project(":common-api")) // 導入公共的子模塊implementation(libraries.'mybatis-plus-boot-starter')implementation(libraries.'mysql-connector-java')implementation(libraries.'druid')implementation(libraries.'springfox-boot-starter')implementation('org.springframework.boot:spring-boot-starter-security')// 以下的依賴庫為Nacos注冊中心所需要的依賴配置implementation('com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery') {exclude group: 'com.alibaba.nacos', module: 'nacos-client' // 移除舊版本的Nacos依賴}implementation('com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config') {exclude group: 'com.alibaba.nacos', module: 'nacos-client' // 移除舊版本的Nacos依賴}implementation(libraries.'nacos-client') // 引入與當前的Nacos匹配的依賴庫} }啟用安全配置之前需要進行密碼的加密處理,本次使用的密碼明文“yootk"
package com.yootk.test;import org.springframework.security.crypto.factory.PasswordEncoderFactories;public class TestCreatePassword {public static void main(String[] args) {String pwd = PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("yootk");System.out.println(pwd);} }SwaggerWebSecurityConfig
如果要想進行安全的啟用,肯定要配置訪問路徑以及賬戶信息。
package com.yootk.provider.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.PasswordEncoder;@Configuration public class SwaggerWebSecurityConfig extends WebSecurityConfigurerAdapter { // Swagger安全配置// 如果有其他的需要,你可以繼續進行數據庫的連接配置,具體的講解已經提供過了private static final String DEFAULT_PASSWORD ="{bcrypt}$2a$10$bvOY6ixvY5DmgiNW.Z79qeV9abQM9a6NbM1n9sejeUnB98C0kKAMu";@Beanpublic PasswordEncoder getPasswordEncoder() {return PasswordEncoderFactories.createDelegatingPasswordEncoder();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("swagger") // 默認用戶名.password(DEFAULT_PASSWORD) // 默認密碼.roles("USER", "ADMIN");}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/swagger-ui/**", "/v2/api-docs").hasRole("ADMIN").and().httpBasic().and().formLogin().permitAll().and().csrf().disable();} }Swagger所提供的地址
http://provider-dept-8001:8001/swagger-ui
創建MyBatisPlus配置類
package com.yootk.provider.config;import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@Configuration public class MyBatisPlusConfig { // MybatisPlus配置類@Beanpublic MybatisPlusInterceptor getMybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 攔截器interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 分頁處理return interceptor;} }部門 數據庫創建腳本
DROP DATABASE IF EXISTS yootk8001; CREATE DATABASE yootk8001 CHARACTER SET UTF8; USE yootk8001; CREATE TABLE dept (deptno BIGINT AUTO_INCREMENT,dname VARCHAR(50),loc VARCHAR(50),CONSTRAINT pk_deptno PRIMARY KEY(deptno) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO dept(dname,loc) VALUES ('開發部', database()); INSERT INTO dept(dname,loc) VALUES ('財務部', database()); INSERT INTO dept(dname,loc) VALUES ('市場部', database()); INSERT INTO dept(dname,loc) VALUES ('后勤部', database()); INSERT INTO dept(dname,loc) VALUES ('公關部', database()); COMMIT;創建Dept映射類
package com.yootk.provider.vo;import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data;@TableName("dept") @Data // Lombok代碼生成 public class Dept { // 這個類所需要追加MBP所需要的注解@TableId(type = IdType.AUTO) // 采用自動增長列配置private Long deptno; // 與deptno字段映射private String dname;private String loc; }創建IDeptDAO數據接口
package com.yootk.provider.dao;import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.yootk.provider.vo.Dept; import org.apache.ibatis.annotations.Mapper;@Mapper public interface IDeptDAO extends BaseMapper<Dept> { // DAO接口開發完成 }在生產端需要提供有業務接口的實現子類
package com.yootk.provider.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yootk.common.dto.DeptDTO; import com.yootk.common.util.DeepBeanUtils; import com.yootk.provider.dao.IDeptDAO; import com.yootk.provider.vo.Dept; import com.yootk.service.IDeptService; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.util.HashMap; import java.util.List; import java.util.Map;@Service public class DeptServiceImpl implements IDeptService {@Autowiredprivate IDeptDAO deptDAO;@Overridepublic DeptDTO get(long id) {DeptDTO dto = new DeptDTO(); // 實例化傳輸對象// 在本地端通過了VO類實現了數據的加載,隨后將此數據拷貝到DTO對象之中BeanUtils.copyProperties(this.deptDAO.selectById(id), dto); // 屬性拷貝return dto;}@Overridepublic boolean add(DeptDTO dto) {Dept dept = new Dept(); // 數據層最終需要的是一個VO類型BeanUtils.copyProperties(dto, dept);return this.deptDAO.insert(dept) > 0; // 更新行數大于0}@Overridepublic List<DeptDTO> list() {QueryWrapper<Dept> wrapper = new QueryWrapper<>();List<DeptDTO> allDepts = DeepBeanUtils.copyListProperties(this.deptDAO.selectList(wrapper), DeptDTO::new); // 集合數據拷貝return allDepts;}@Overridepublic Map<String, Object> split(int currentPage, int lineSize, String column, String keyword) {QueryWrapper<Dept> wrapper = new QueryWrapper<>();wrapper.like(column, keyword); // 設置模糊查詢操作int count = this.deptDAO.selectCount(wrapper); // 統計個數// 實現數據的查詢處理IPage<Dept> page = this.deptDAO.selectPage(new Page<>(currentPage, lineSize, count), wrapper);Map<String, Object> map = new HashMap<>(); // 包裝返回結果map.put("allDepts", DeepBeanUtils.copyListProperties(page.getRecords(), DeptDTO::new));map.put("allRecorders", page.getTotal());map.put("allPages", page.getPages());return map;} }啟動類
package com.yootk.provider;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class StartProviderDept8001Application {public static void main(String[] args) {SpringApplication.run(StartProviderDept8001Application.class, args);} }測試
package com.yootk.test;import com.yootk.common.dto.DeptDTO; import com.yootk.provider.StartProviderDept8001Application; import com.yootk.service.IDeptService; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.web.WebAppConfiguration;import java.util.Map;@ExtendWith(SpringExtension.class) @WebAppConfiguration @SpringBootTest(classes = StartProviderDept8001Application.class) public class TestDeptService {@Autowiredprivate IDeptService deptService; // 注入業務接口對象@Testpublic void testGet() {System.out.println(this.deptService.get(1));}@Testpublic void testList() {System.out.println(this.deptService.list());}@Testpublic void testAdd() {DeptDTO dto = new DeptDTO();dto.setDname("公益部");dto.setLoc("洛陽");System.out.println(this.deptService.add(dto));}@Testpublic void testSplit() {Map<String, Object> map = this.deptService.split(1, 2, "dname", "");System.out.println(map);} }controller
package com.yootk.provider.action;import com.yootk.common.dto.DeptDTO; import com.yootk.service.IDeptService; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest; import java.util.Enumeration;@RestController @RequestMapping("/provider/dept/*") // 微服務提供者父路徑 @Slf4j // 使用一個注解 public class DeptAction {@Autowiredprivate IDeptService deptService;@ApiOperation(value="部門查詢", notes = "根據部門編號查詢部門詳細信息")@GetMapping("get/{id}")public Object get(@PathVariable("id") long id) {return this.deptService.get(id);}@ApiOperation(value="部門增加", notes = "增加新的部門信息")@ApiImplicitParams({@ApiImplicitParam(name = "deptDTO", required = true,dataType = "DeptDTO", value = "部門傳輸對象實例")})@PostMapping("add")public Object add(@RequestBody DeptDTO deptDTO) { // 后面會修改參數模式為JSONreturn this.deptService.add(deptDTO);}@ApiOperation(value="部門列表", notes = "查詢部門的完整信息")@GetMapping("list")public Object list() {return this.deptService.list();}@ApiOperation(value="部門分頁查詢", notes = "根據指定的數據庫參數實現部門數據的分頁加載")@ApiImplicitParams({@ApiImplicitParam(name="cp", value = "當前所在頁", required = true, dataType = "int"),@ApiImplicitParam(name="ls", value = "每頁顯示的數據行數", required = true, dataType = "int"),@ApiImplicitParam(name="col", value = "模糊查詢列", required = true, dataType = "String"),@ApiImplicitParam(name="kw", value = "模糊查詢關鍵字", required = true, dataType = "String")})@GetMapping("split")public Object split(int cp, int ls, String col, String kw) {return this.deptService.split(cp, ls, col, kw);} }common-api子模塊修改
由于該模塊需要被其他子模塊所使用,那么這個時候就需要對代碼進行編譯.
build.gradle:
jar { enabled = true} // 允許打包為jar文件 bootJar { enabled = false } // 不允許打包為Boot執行文件 javadocTask { enabled = false } // 不需要打包為doc文件Gradle編譯:
gradle build【provider-dept-8001子模塊】啟動當前的部門微服務測試
consumer-springboot-80 子模塊
application.yml
server: # 服務端配置port: 80 # 這個接口可以隨意,反正最終都是由前端提供服務 spring:application: # 配置應用信息name: consumer # 是微服務的名稱cloud: # Cloud配置nacos: # Nacos注冊中心配置discovery: # 發現服務server-addr: nacos-server:8848 # Nacos服務地址 代理nacos-proxy:8848 namespace: 96c23d77-8d08-4648-b750-1217845607ee # 命名空間IDgroup: MICROCLOUD_GROUP # 一般建議大寫cluster-name: MuyanCluster # 配置集群名稱register-enabled: false # 消費端不注冊controller
package com.yootk.consumer.action;import com.yootk.common.dto.DeptDTO; import com.yootk.service.IDeptService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping("/consumer/dept/*") // 兩個不同的服務路徑 public class DeptConsumerAction { // 消費端Action@Autowired // 由容器幫助用戶自動實例化接口對象private IDeptService deptService;@GetMapping("add") // 消費端接口名稱public Object addDept(DeptDTO dto) {return this.deptService.add(dto);}@GetMapping("get")public Object get(Long deptno) {return this.deptService.get(deptno);}@GetMapping("list")public Object list() {return this.deptService.list();}@GetMapping("split")public Object split(int cp, int ls, String col, String kw) {return this.deptService.split(cp, ls, col, kw);} }啟動類
package com.yootk.consumer;import muyan.yootk.config.ribbon.DeptProviderRibbonConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients("com.yootk.service") // Feign掃描包 public class StartConsumerApplication {public static void main(String[] args) {SpringApplication.run(StartConsumerApplication.class, args);} }總結
以上是生活随笔為你收集整理的构建SpringCloud项目基础框架的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 刺客信条最低配置多少啊?
- 下一篇: 刺客信条7配置?