构建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=11

dependencies.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);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/324180.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx中如何配置中文域名?

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注公众号【雄雄的小课堂】。最近我的个人站上线了&#xff0c;一直在优化中&#xff0c;目前优化最多的就是后台&#xff0c;将主页面的色彩重新搭配了下&#xff0c;稍微好看点儿了&#xff0c;以下是后台界面&#xff1a;前台界…

JavaFX图表(九)之堆积面积图

翻译自 JavaFX - 堆积面积图 StackedArea Chart是区域图的变体&#xff0c;显示每个值的贡献趋势&#xff08;例如 - 加班&#xff09;。堆叠区域使每个系列相邻&#xff0c;但不与前面的系列重叠。这与区域图表形成对比&#xff0c;其中每个系列覆盖前面的系列。 以下是描绘…

ASP.NET Core MVC – 自定义 Tag Helpers

介绍 在之前的内容中&#xff0c;我们谈到了Tag Helpers&#xff0c;我们还谈到了 caching Tag Helpers和form Tag Helpers。 通过创建自定义Tag Helpers&#xff0c;我们可以扩展现有元素或创建我们自己的元素。 Tag Helper是实现ITagHelper接口类的统称。MVC为我们提供了该…

sqlserver建库建表建约束,删库删表删约束的示例总结

1.创建一个数据库catedb,保存在本地D盘下面的DB中&#xff0c;主数据文件的初始大小为5MB&#xff0c;最大为200MB&#xff0c;增长率为10%&#xff0c;日志文件的初始大小为3MB&#xff0c;无限制增长&#xff0c;其增长率为2MB&#xff0c;请使用sql语句检测master数据库中是…

JFreeChart(二)之饼图

转载自 JFreeChart饼图 在饼图中&#xff0c;每个扇区的弧长成正比它代表的数量。本章演示了如何使用JFreeChart 从一个给定的业务数据创建饼图。 业务数据 下面的例子描述了移动销售饼图。以下是不同移动品牌和销售(每天单位)列表。 S.N.手机品牌销售(天)1Iphone 5S202Sam…

mysql中如何将默认用户名root改成其他?

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注公众号【雄雄的小课堂】。最近&#xff0c;我的个人站上线啦&#xff0c;大家可以直接在浏览器的地址栏中输入&#xff1a;穆雄雄.com&#xff0c;轻轻敲击回车&#xff0c;即可直接进入……欢迎大家多多关注&#xff0c;多多留…

ASP.NET Core - Razor 页面介绍

简介 随着ASP.NET Core 2 即将来临&#xff0c;最热门的新事物是Razor页面。在之前的一篇文章中&#xff0c;我们简要介绍了ASP.NET Core Razor 页面。 Razor页面是ASP.NET Core的一个新功能&#xff0c;可以使基于页面的编程方式更容易&#xff0c;更高效。 大众的初步印象是…

P2153-晨跑【费用流,网络流,拆点】

前言 这是评测记录 正题 AC评测记录链接&#xff1a; https://www.luogu.org/record/show?rid7945350 大意 一个图&#xff0c;没错要求不能走重复的边和点。求走最多次的情况下路最短。 解题思路 每次行走就是一个流量在流&#xff0c;然后将边权设为1就可以保证边只能走…

从试卷中悟出的道理……

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注公众号【雄雄的小课堂】。最近&#xff0c;我的个人站上线啦&#xff0c;大家可以直接在浏览器的地址栏中输入&#xff1a;穆雄雄.com&#xff0c;轻轻敲击回车&#xff0c;即可直接进入……不管是三班还是四班&#xff0c;一听…

JFreeChart(三)之条形图

转载自 JFreeChart条形图 本章演示了如何使用JFreeChart从一个给定的业务数据创建条形图。 条形图使用不同的方位(水平或垂直)条&#xff0c;以显示不同类别的比较。图表中的一个轴(域轴)示出了特定的域进行比较&#xff0c;并在另一个轴(范围轴)表示的离散值。 业务数据 …

ASP.NET Core 快速入门(实战篇)

上篇讲了《asp.net core在linux上的环境部署》。今天我们将做几个小玩意实战一下。用到的技术和工具有mysql、websocket、AngleSharp&#xff08;爬虫html解析&#xff09;、nginx多站点部署。 NO1 留言板&#xff08;mysql的使用&#xff09; 演示&#xff1a;http://haojim…

P2053-修车【网络流,费用流】

前言 n和m搞反调半天系列 正题 AC记录链接&#xff1a; https://www.luogu.org/record/show?rid7949136 大意 又m个员工&#xff0c;n辆车&#xff0c;第j个员工修第i辆车需要T[i][j]的时间&#xff0c;求分配让顾客平均等待时间最短。 解题思路 首先先假设一个修车工要修…

走的走的居然飞起来了……

第一次坐飞机&#xff0c;终于满足了我的一个愿望了。记得之前在老家的山头上放羊时&#xff0c;远远的听到飞机想&#xff0c;我和我弟弟能把飞机目送到只剩下一条白线。。。。。一直在定睛观察飞机到底长啥样&#xff0c;那时候对于我们来说&#xff0c;能看见飞机的全面目就…

JFreeChart(四)之线型图

转载自 JFreeChart线型图 线图或折线图来显示信息为一系列由直线段连接的数据点(标记)。线图显示数据在相同的时间频率如何变化。本章从一个给定的业务数据演示如何使用JFreeChart创建线型图。 业务数据 下面的示例绘制折线图显示从1970年开始学校在不同年份开通数量。 给…

如何在Linux上使用VIM进行.Net Core开发

对于在Linux上开发.Net Core的程序员来说, 似乎都缺少一个好的IDE.Windows上有Visual Studio, Mac上有Visual Studio for Mac, 难道Linux只有Visual Studio Code了吗?Linux上有两个最好的编辑器: VIM和Emacs, 哪个更好不是这一篇的主题, 这一篇的主题是如何在Linux上简单的构建…

P2517-订货【网络流,费用流】

正题 AC链接&#xff1a; https://www.luogu.org/record/show?rid7949532 大意 有n个月&#xff0c;每个月商品价格di&#xff0c;需求量Ui。有容量为S的仓库&#xff0c;一个商品汇存一个月要m。求最低成本 解题思路 首先是月份做为点&#xff0c;成本作为费用&#xff0…

教学交流研讨会总结(一)

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注公众号【雄雄的小课堂】。最近&#xff0c;我的个人站上线啦&#xff0c;大家可以直接在浏览器的地址栏中输入&#xff1a;穆雄雄.com&#xff0c;轻轻敲击回车&#xff0c;即可直接进入……

JFreeChart(五)之XY图

转载自 JFreeChart XY图 在xy图(散点图)是根据一个数据系列组成的x和y值的列表。每个值对(x&#xff0c;y)是坐标系中的一个点。这里1值确定水平(X)位置&#xff0c;而另一个确定垂直(Y)位置。本章演示了如何使用JFreeChart从一个给定的业务数据创建XY图表。 业务数据 考虑…

服务环境搭建

文章目录Nacos服务搭建一、nacos-server 环境搭建二、nacos-mysql 环境搭建三、建 领域模型REST访问配置&#xff08;给其他语言使用&#xff09;四、nacos-server 集群搭建Nacos服务搭建 一、nacos-server 环境搭建 1、 [nacos-server主机]&#xff08;考虑到后续开发的问题…

p2762-太空飞行计划问题【网络流,最大权闭合图,最小割】

正题 AC评测记录链接&#xff1a; https://www.luogu.org/record/show?rid7965757 大意 有nn个实验,有m" role="presentation">mm个实验器材的集合GG。完成第i" role="presentation">ii个实验可以获得cici元&#xff0c;第ii个实验需…