一 开源项目地址

https://gitee.com/wells2333/spring-microservice-exam

二 前端运行方法

1 在F:\springcloud\spring-microservice-exam\frontend\spring-microservice-exam-ui目录下运行命令

cnpm install

2 在F:\springcloud\spring-microservice-exam\frontend\spring-microservice-exam-ui目录下运行命令

cnpm run dev

3 测试是否正常运行

三  consul简介

因为项目涉及consul,所以简单介绍一下,参考下面链接。

参考: https://blog.csdn.net/chengqiuming/article/details/102990022

四 Redis简介

因为项目涉及Redis,所以简单介绍一下,参考下面链接。

参考: https://blog.csdn.net/chengqiuming/article/details/102990197

五 Mysql数据库

需要建立4个数据库

  • microservice-user

  • microservice-exam

  • microservice-auth

  • microservice-gateway

建立完数据库后,导入相关脚本,脚本从开源项目获取。

六 在启动服务前,先确保下面4个服务能正常运行

consul、MySQL、redis、rabbitMq

七 修改配置文件

主要涉及consul、MySQL、redis、rabbitMq中间件的IP和端口信息

如果这些中间件都安装在本地,不用修改。

八 启动顺序

1 config-service

2 auth-service

3 user-service

4 exam-service

5 gateway-service

需要监控功能再启动:

6 monitor-service

7 msc-service

内存不足的可以限制每个服务的内存:config-service可以分配64M(-Xmx64m -Xms64m)、其它服务分配128M(-Xmx128m -Xms128m)

配置方法见下面链接:

https://blog.csdn.net/chengqiuming/article/details/81429641

如果阿里的Maven镜像仓库有问题,可用华为的Maven镜像仓库。

配置方法见下面链接:

https://blog.csdn.net/anqi114179/article/details/80031148

九 先不急于分析代码,先分析pom中的依赖,可以了解项目用到哪些技术,做到心中有数

已将相关依赖进行总结。参考下面文档

https://blog.csdn.net/chengqiuming/article/details/102963298

十 按照文件粒度进行代码分析

文件名

相关技术说明

CustomGlobalExceptionHandler.java

该文件是全局异常处理,需要注意@ControllerAdvice和@ExceptionHandler(CommonException.class)注解的用法。

具体用法请参考: https://blog.csdn.net/chengqiuming/article/details/81711751

SwaggerConfig.java

该文件主要是Swagger配置,需要关注WebMvcConfigurer,具体用法参考:https://yq.aliyun.com/articles/617307

该文件还大量用到stream流操作。

关于Docket的用法,可参考: https://www.jianshu.com/p/6c2d416bdf10和 https://github.com/rocknsm/docket

关于Swagger2的用法,可参考 https://www.cnblogs.com/jtlgb/p/8532433.html

CustomRedisCacheWriter.java

重写了RedisCacheWriter接口,在RedisConfig中会用到该类,RedisCacheManager会用到此类。

MultitenantCacheManager.java

@Slf4j:用法参考: https://www.jianshu.com/p/6e137ee836a1

该文件作用:扩展CacheManager支持多租户

AppStartupRunner.java

@AllArgsConstructor:用法参考:https://www.cnblogs.com/huey/p/4693484.html

@Component:把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>)

用法参考: https://www.cnblogs.com/lyjing/p/8427832.html

RedisConfig.java

Redis的配置类。

@Configuration:相对于Spring配置文件中的<beans> </beans>

@Bean:相对于Spring配置文件中的<bean></bean>

@EnableCaching:参考 https://segmentfault.com/a/1190000011069802

SnowFlake

该类是ID生成配置类

@Autowired:用在JavaBean中的注解,通过byType形式,用来给指定的字段或方法注入所需的外部资源。简言之:给类的属性或方法参数注入值,值来自Javabean,是通过byType匹配的。

https://blog.csdn.net/horacehe16/article/details/79811763

CommonConstant

项目的一些公共常量

MqConstant

关于Rabbitmq的一些常量

ServiceConstant

关于服务的一些常量,常量定义格式稍微注意下:  public static final String USER_SERVICE = "user-service";

SysConfigDto

它是系统配置的数据传输单元,会返回给前端。

@Data:具体用法参考: https://blog.csdn.net/qq_37433657/article/details/83275051

LoginType

这是一个枚举类,但因为使用了lombok插件,所以看上去比较的简洁。

枚举类比较传统的用法参考: https://blog.csdn.net/lihaogn/article/details/90290084

@Getter:具体用法参考: https://blog.csdn.net/qq_37433657/article/details/83275051

excpeptions

该文件夹下定义了一个公共异常类和由该公共异常类派生出的5个特殊异常类。我们写异常类可以参考这种写法。

Log

日志定义

@NotBlank(message = "日志标题不能为空")的用法参考: https://blog.csdn.net/qq_39964694/article/details/81183701

ResponseBean

该类是返回前端的响应数据,并且用到泛型类,这种用法我们可以借鉴。

BaseEntity

实体类的基类,该类定义了子类的共同属性,是定义实体类的一种常用手法。注意该类是个泛型类。

BaseMapper

Dao的基类接口

CrudMapper

继承BaseMapper,也是一个泛型类,提供了基本的增、删、查、改操作。提供的接口有:获取单条数据、获取列表数据、获取全部列表数据、根据id获取列表数据、插入单条数据、更新单条数据、删除单条数据、批量删除

TreeEntity

树形实体(节点),继承BaseEntity,它是一个泛型类,关键属性有:code、父节点、父节点id、排序号,子节点列表

SnowflakeProperties

Snowflake的配置属性,属性值从各微服务配置文件中获取。

SysProperties

系统配置属性,属性值从各微服务配置文件中获取。

BaseService

Service基类,它是一个抽象类。

CrudService

基本的增删查改服务,它继承自BaseService,也是一个抽象类。还用到了定义类型形参时设定上限语法。

该类实现基本的增删查改服务,提供的服务包含:根据id获取、获取单条数据、查询列表、查询分页、插入或更新、删除、批量删除、插入数据、更新数据

@Transactional:一般加在Service层的增、删、改方法上。

其中get方法用到反射技术,findPage用到分页技术,这两个函数可以仔细研究下。

LogInterceptor

定义了okhttp的日志拦截器,该拦截器最终会被配置到OkHttpClient中。

具体用法可参考: https://blog.csdn.net/bunny1024/article/details/53504556

OkHttpRequestBodyUtil

该类用于OKHttp,它是一个工具类,用于生成RequestBody。

该类只提供了一个方法create,它用来生成RequestBody,RequestBody是一个抽象类。此处用到了匿名内部类。具体用法参考:

https://blog.csdn.net/hellocsz/article/details/81974251

匿名内部类会立即创建一个该类的实例,类体部分实现了RequestBody的接口:contentType、writeTo、contentLength

OkHttpUtil

okHttp工具类封装,该类是一个单例对象,封装了OkHttpClient,在构造函数中,根据配置并定制了OkHttpClient。

该工具对提供了一系列的OkHttp的操作,包括:get请求、get请求获取响应体、post请求、用于上传文件的put请求、上传字节数组、上传流、patch请求、删除请求、Map转JSONObject对象。

具体使用请参考: https://blog.csdn.net/fxjzzyo/article/details/78761373

SSLSocketClient

该类用于配置OkHttpClient的SSL特性。

该类的SSLSocketClientSSLContext用到了单例模式

X509TrustManager是一个匿名内部类,实现了TrustManager接口的三个方法。

getHostnameVerifier方法用到了lamada表达式,实现了HostnameVerifier接口。

Assert

实现了对象的非空校验。

ClassUtils

类工具类,该类用到反射机制,主要实现:获取构造函数的方法参数信息,获取一般方法的方法参数信息

DateUtils

日期工具类,DateTimeFormatter用于格式化日期时间。实现以下功能:日期转String、LocalDate转Date、LocalDateTime转Date、Date转LocalDate、Date转LocalDateTime、两个时间之差。

ExcelToolUtil

Excle工具类,主要实现:根据数据和标题导出为Excle表格、设置表格样式、将Excle数据导入到系统,并保存到List<Map<String, Object>>中、数据格式转换。

FileUtil

文件工具类,获得文件的扩展名。

IdGen

id生成工具类,提供了两个生成器,一个是改良版的UUID生成器,一个是基于snowflake算法生成ID。

JsonMapper

将Json字符串转换为对象,将对象转换为Json字符串。

关于JSON的用法,请参考: https://blog.csdn.net/xingfei_work/article/details/76572550

MapUtil

Map工具类,主要实现如下功能:获取map中key对应的值,并根据需求和实际,可转换为字符串、Date、Double类型、布尔类型、JavaBean集合对象。该类还实现了将Map对象转化成 JavaBean对象,将JavaBean集合对象转化成Map集合对象,以及将JavaBean对象转化成Map对象。

ObjectUtil

将字符串转换为double,如果字符串为空或者null,则自动转换为0.0。

PageUtil

分页查询工具类

ReflectionUtil

反射工具类:实现如下功能:返回某个类的第index个泛型类型,直接读取对象属性值、根据属性字符串获得某个对象对应的属性,改变private/protected的成员变量为public,直接设置对象属性值。

getSuperclass的用法参考:https://www.cnblogs.com/xiohao/p/4269704.html

getDeclaringClass的用法参考:https://www.yiibai.com/javareflect/javareflect_field_getdeclaringclass.html

for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass())对这个循环的理解:可以理解为传进来的Object为水果类,obj实际为苹果,水果类有一个属性重量。依照这个思路去理解循环中的内容。

ResponseUtil

Response工具类:根据ResponseBean内容,判断响应是否成功。

Servlet

Servlet工具类:获取在不同浏览器下的下载文件名的转码规则。

String downloadName = URLEncoder.encode(fileName, "UTF-8");

当fileName = 中国

downloadName = %E4%B8%AD%E5%9B%BD

SnowflakeIdWorker

Snowflake的ID生成器算法

/**

* Twitter_Snowflake<br>

* SnowFlake的结构如下(每部分用-分开):<br>

* 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>

* 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>

* 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)

* 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>

* 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>

* 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>

* 加起来刚好64位,为一个Long型。<br>

* SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。

*/

SpringContextHolder

具体说明参考:https://www.cnblogs.com/cuijiade/p/9664789.html

SysUtil

系统工具类,主要实现以下功能:

获取当前登录的用户名

获取系统编号

获取租户编号

AES解密

buildTree

两层循环实现建树,参数传入的是根和树实体列表,此时的各实体不包含孩子节点,建立完后包含孩子节点。

vo(AttachmentVo、DeptVo、LogVo、MenuVo、RoleVo、UserVo)

vo、po、dto、bo、pojo、entity、mode的区分,请参考: https://blog.csdn.net/qq_41604862/article/details/79675223

BaseController

控制器基类,被具体控制器继承。

CustomFeignConfig

服务间调用携带Authorization、Tenant-Code请求头。

FeignOkHttpConfig

功能点: 创建一个Builder对象,并对OkHttpClient的相关属性初始化。

技术点:

@ConditionalOnClass:当给定的类名在类路径上存在,则实例化当前Bean。参考: https://www.cnblogs.com/qdhxhz/p/11027546.html

@AutoConfigureBefore:说明FeignOkHttpConfig在FeignAutoConfiguration之前加载,参考: https://blog.csdn.net/yangchao1125/article/details/100934881

用到了builder模式,具体参考: https://www.jdon.com/51691

RestTemplateConfig

技术点:配置类,在spring容器中注入一个RestTemplate对象restTemplate

LogInterceptor

技术点:

okhttp自定义日志拦截器:https://blog.csdn.net/weixin_43807869/article/details/86489494

拦截器的使用:  https://blog.csdn.net/stven_king/article/details/84500778

SpringCloudHystrixConcurrencyStrategy

技术点:并发策略定义

参考《重新定义Spring cloud实战》的P141

Log

定义了一个日志注解,注解了@Log的方法会打印日志

LogAspect

功能点:

日志切面,异步记录日志,不仅打印了日志,还通过异步的方法,将日志存到数据库中。

SpringContextHolder.publishEvent(new LogEvent(logVo));发布一个事件

技术点:

@Around("@annotation(log)")   //这里的log指的是下面定义中的log,整个意思是在@Log的方法处会切入打印

public Object around(ProceedingJoinPoint point, Log log) throws Throwable {

用到了AOP面向切面编程,可参考下面文章

https://blog.csdn.net/qq_41981107/article/details/85260765

https://www.cnblogs.com/ssslinppp/p/5845659.html

https://zhidao.baidu.com/question/1306182545009100499.html

LogEvent

功能点:

定义日志事件

技术点:

日志事件是继承ApplicationEvent这个类的

LogListener

功能点:

异步监听日志事件,当有日志事件发布时候,此类会监听到。

技术点:

@Async:基于@Async标注的方法,称之为异步方法;这些方法将在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。

参考 https://www.cnblogs.com/jpfss/p/10273129.html

@Order:参考 https://blog.csdn.net/Thinkingcao/article/details/84801093

@EventListener(LogEvent.class):参考 https://www.jianshu.com/p/e2d257ce410d?from=timeline&isappinstalled=0

LogUtil

功能点:

日志工具类,初始化日志基本信息。

技术点:

LogUtilRequestContextHolder的用法:

https://www.cnblogs.com/panbin/p/11386022.html

SecurityContextHolder的用法:

https://www.cnblogs.com/longfurcat/p/9417912.html

LogAutoConfiguration

功能点:

日志功能自动化配置,注入日志监听器和日志切面类。

技术点:

@EnableAsync:

https://blog.csdn.net/qq_39385706/article/details/79365849

@ConditionalOnWebApplication:如果是web应用

https://www.cnblogs.com/zhixiang-org-cn/p/9703736.html

CustomResourceServerConfig

功能点:

资源服务器配置,注入了开发权限的URL、手机登录配置、微信登录配置等信息。

该自定义类主要是对ResourceServerSecurityConfigurer和HttpSecurity所对应的bean进行配置

技术点:

ResourceServerConfigurerAdapter: https://www.jianshu.com/p/fe1194ca8ecd

MobileLoginConfig

功能点:手机登录配置

主要是注入:MobileSecurityConfigurer和AuthenticationSuccessHandler这两个Bean。

其中AuthenticationSuccessHandler用到了Builder模式。

WxLoginConfig

功能点:微信登录配置

主要是注入:WxSecurityConfigurer和AuthenticationSuccessHandler这两个Bean。

其中WxLoginSuccessHandler用到了Builder模式。

SecurityConstant

功能点:跟安全相关的常量定义

ClientDetailsServiceImpl

功能点:jdbc客户端service

技术点:该类主要是继承JdbcClientDetailsService这个类,重写了loadClientByClientId方法,实际上还是调用基本的方法。

JdbcClientDetailsService关于该类的说明: https://cloud.tencent.com/developer/article/1413422

CustomUserDetailsService

定义查询用户信息接口,包括下面三个接口

根据用户名和租户标识查询

根据社交账号和租户标识查询

根据微信openId和租户标识查询

GrantedAuthorityImpl

GrantedAuthority接口的封装,实现了getAuthority这个接口方法,从方法实现来看说明权限是通过角色类体现的。

UserDetailsImpl

实现UserDetails(用户详细信息)接口,通过权限、密码、用户名、启动禁用状态和租户标识来体现用户详情。并实现了相关接口。

CustomOauthException

定制OAuth2Exception,注意如果该类如果序列化,需要使用CustomOauthExceptionSerializer类的serialize方法进行序列化。

TenantTokenFilter

获取请求头里的租户code,并将它保存到线程变量TenantContextHolder中。

关于过滤器中的@Order注解,参考下面文章。

https://www.cnblogs.com/zxf330301/p/8579507.html

MobileAuthenticationFilter

关于密码认证,请参考:http://www.spring4all.com/article/420,从这篇文章可以很好的理解MobileAuthenticationFilter

MobileAuthenticationFilter类继承AbstractAuthenticationProcessingFilter

UsernamePasswordAuthenticationFilter类也是继承AbstractAuthenticationProcessingFilter

两个实现类的写法有同工异曲之妙。可以对比MobileAuthenticationFilter和UsernamePasswordAuthenticationFilter这两个类一起学习。

AntPathRequestMatcher关于这个类的用法,请参考 https://blog.csdn.net/qq_35809876/article/details/102743762

关键代码:authResult = this.getAuthenticationManager().authenticate(mobileAuthenticationToken); 认证就是通过这行代码完成的。

MobileAuthenticationProvider

请看看 http://www.spring4all.com/article/420 这篇文章,里面提到了AbstractUserDetailsAuthenticationProvider这个类,它实现了AuthenticationProvider这个接口中的authenticate方法,类似MobileAuthenticationProvider也实现了AuthenticationProvider这个接口中的authenticate方法,所以这两个类可以类别学习。这个类中的authenticate方法主要就是验证手机用户是否合法。

它被上面这个类的authResult = this.getAuthenticationManager().authenticate(mobileAuthenticationToken);所调用。

未完待续......

开源项目分析解读——基于Spring Cloud的在线考试系统相关推荐

  1. 基于 Spring Boot 的在线考试系统

    点击上方「蓝字」关注我们 今天推荐一款非常不错的,基于Spring Boot与Vue的前后端分离的在线考试系统.仓库地址: https://github.com/19920625lsg/spring- ...

  2. 一个基于 Spring Boot 的在线考试系统

    今天推荐一款超级美观的在线考试系统,感兴趣可以先去预览地址看看该项目. 在线 Demo预览,http://129.211.88.191 ,账户分别是admin.teacher.student,密码是a ...

  3. 基于Java Web的在线考试系统的实现

    摘  要 随着互联网的发展,教育的方式逐渐步入信息化.智能化,网络教育逐渐成为教育未来发展的重要趋势,在线考试系统成为教育成果考察的主流方向.在线考试充分利用现代信息化技术的优势,使考试更方便.更高效 ...

  4. 基于java web的在线考试系统(源码+论文)

    今天介绍的一个项目是, 基于java web的在线考试系统 1 设计内容及要求 1.1 在线考试系统概述 基于Java web开发的在线考试系统不仅可以充分利用校园内各种资源,对学校的各种教学资源进行 ...

  5. 基于SSM实现的在线考试系统【附源码】(毕设)

    一.项目简介 本项目是一套基于SSM实现的在线考试系统 或 网络考试系统 或 考试管理系统 或 在线考试平台,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者. 详细介绍了该 ...

  6. 基于PHP+MySQL实现在线考试系统【100010717】

    在线考试系统 摘 要 随着科技的发展,网络技术已经深入到人们的日常生活中,同时带来了教育方式的一次变革.而网络考试则是一个很重要的方向.基于 Web 技术的网络考试系统可以借助于遍布全球的 Inter ...

  7. 毕业设计 - 基于java web的在线考试系统【源码+论文】

    文章目录 前言 一.项目设计 1. 模块设计 2. 基本功能 2.1 登录功能 2.2 系统答题 2.3 答题得分 2.4 错题解析 3. 实现效果 二.部分源码 项目源码 前言 今天学长向大家分享一 ...

  8. python 模拟考试系统_Project-OTS: Online Exam System written on Python 3. 基于Python 3的在线考试系统。...

    Project-OTS Online Exam System written on Python 3. Your can first try it on ots.icystal.top. 基于Pyth ...

  9. 基于J2EE架构的在线考试系统-Java(报告+源码+PPT

    目前国内基于B/S.C/S结构的在线考试系统产品已经有许多,本文首先介绍了这些考试系统的形成和发展过程,大致结构.然后通过仔细分析,提出了目前的这些系统还存有系统更新和维护等种种弊端,仍不够成熟.基于 ...

最新文章

  1. python变量详解_Python 变量详解[学习 Python 必备基础知识][看此一篇就够了]
  2. HDU 2955 Robberies
  3. nginx实现301(加密)跳转和200跳转
  4. 云服务器cvm系统,云服务器 cvm 自带系统
  5. adb push命令传文件到手机_Android调试桥(adb)
  6. 使用C#和Excel进行报表开发(5)
  7. mdb java_Java生成mdb文件(MS Access文件)
  8. 三转CHM文件故障解决
  9. 简单3小步,轻松搞定PS证件照换底色(有手就行)
  10. linux网桥内核实现分析,Linux网桥实现分析
  11. 2019年系统架构设计师考试--从备考到拿证
  12. PHP自学笔记 ---李炎恢老师PHP第一季 TestGuest0.4
  13. vue生成证书模板 并支持图片和PDF格式下载的小demo
  14. 图像搜索引擎 - 原理篇
  15. Ubuntu 远程控制(使用自带远程工具)
  16. MGC TOKEN—必将超越PlusToken的搬砖套利项目!
  17. Flask-中session的工作机制和session操作
  18. 树莓派安装成功后,搜索不到自己的WIFI
  19. C++学习——基于binance的AS做市模型
  20. TCP的三次握手与四次挥手理解及面试题(很全面)

热门文章

  1. 面试了几十家软件测试公司全是这个“套路”
  2. 弘辽科技:拼多多批发单算销量吗?拼多多刚开店怎么有销量
  3. matlab求心率变异性的程序,心率变异性及其相关算法的实现
  4. 中医-常用药食同源的食物功效作用
  5. Comic Life 3 for Mac(漫画创作软件)内附安装教程需要 macOS 11.x系统
  6. java:判断字符串的开始或结尾
  7. PHP根据键值,对二维数组重新进行分组
  8. Win7中双击bat文件变成打开文本编辑器后如何恢复
  9. 网站被降权了怎么办?
  10. 点击进入我的QQ空间