常见框架总结

1

参考

1
2
3
4
https://www.nowcoder.com/discuss/5683?type=all&order=time&pos=&page=1&channel
=-1&source_id=search_all_nctrack
https://www.cnblogs.com/yanggb/p/11004887.html
https://www.zhihu.com/question/20794107

SpringMVC

什么是SpringMVC

SpringMVC 是一个MVC 框架,在实际开发中,接收浏览器的请求响应,对
数据进行处理,然后返回页面进行显示

MVC三个字母分别代表什么意思

  1. M 代表 模型(Model)模型就是数据,就是 dao,bean
  2. V 代表 视图(View) 就是网页, JSP,用来展示模型中的数据
  3. C 代表 控制器(controller) 控控制器的作用就是把不同的数据(Model),
    显示在不同的视图(View)上,Servlet 扮演的就是这样的角色

SpringMVC工作原理

  1. 客户端(浏览器)发送请求,直接请求到前端控制器DispatcherServlet,
    接收用户的请求和响应
  2. DispatcherServlet 根据请求信息调用处理映射器 HandlerMapping
  3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器
    拦截器(如果有则生成)并一起返回给DispatcherServlet
  4. DispatcherServlet通过处理器适配器(HandlerAdapter)调用处理器
  5. 执行处理器(Controller,也叫后端控制器)
  6. Controller执行完成后返回ModelAndView,Model 是返回的数据对象
    ,View 是个逻辑上的View
  7. HandlerAdapter将Controller执行结果(即ModelAndView)返回给
    DispatcherServlet
  8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器
  9. ViewReslover解析后返回具体View
  10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
  11. 最后DispatcherServlet响应给用户

SpringMVC与Struts2的不同

  1. SpringMVC的入口是一个Servlet(即前端控制器),而Struts2的入口是
    一个Filter(即过虑器)
  2. SpringMVC是基于方法开发(一个请求url对应一个方法),请求参数可以
    传递到方法的形参中,而且可以设计为单例或多例(建议单例),Struts2是
    基于类开发的,传递参数是通过类的属性,所以只能设计为多例
  3. Struts2 采用值栈存储请求和响应的数据,通过OGNL 表达式存取数据,
    SpringMVC通过参数解析器将request请求内容解析,并给方法形参赋值,将
    数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数
    据通过request域传输到页面。jsp视图解析器默认使用JSTL。

Restful风格

Restful就是一个资源定位及资源操作的风格,不是标准也不是协议,只是一
种风格,是对http协议的诠释

  1. 资源定位:互联网所有的事物都可以抽象为资源,Restful风格的请求url
    中没有动词,只有名词,也没有参数
  2. 资源操作:使用put、delete、post、get等不同方法对资源进行操作,分
    别对应添加、删除、修改以及查询。一般使用时还是以post和get为主,put和
    delete几乎使用不到

有状态对象和无状态对象

  1. 有状态对象 有状态对象指的是有数据存储功能的类的对象,就是有实例
    变量的对象,可以保存数据,是非线程安全的,在不同的方法调用期间不会
    保留任何的状态。一般是prototype scope。
  2. 无状态对象 没有实例变量的对象,不能保存数据,是不可变类,是线程
    安全的对象。一般是singleton scope。

Servlet是单例模式吗

Servlet体系结构是建立在Java多线程机制上的,他的生命周期是由Web容器
负责的,一个Servlet类在Application中只有一个实例存在,也就是说有
多个线程都在使用这个实例。这是单例模式的应用。无状态的单例模式是线
程安全的,但是如果我们在Servlet中使用了实例变量,那么就变成了有
状态的,就变成了singleton+有状态,这个就是非线程安全的

SpringMVC 如何解决并发

springMVC中,一般Controller、service、DAO层的scope均是singleton
,每个请求都是单独的线程,即使同时访问同一个Controller对象,因为并
没有修改Controller对象,相当于针对Controller对象而言,只是读操作
,没有写操作,不需要做同步处理,如果存在实例变量就有可能产生并发
问题,解决方式如下

  1. 在控制器中不使用实例变量
  2. 将控制器的作用域从单例改为原型,即在spring配置文件Controller中
    声明 scope=”prototype”,每次都创建新的controller
  3. 在Controller中使用ThreadLocal变量

@Controller的作用

请求的URL到我们这里所编写的Handler类的某个方法进行一些业务逻辑处理。
使用@Controller注解表示这个类是一个Handler

@RequestMapping

注解括号里面的表示访问的URL,也可以放在类上面,页面跳转时默认是请求转
发。RequestMapping中可以写多个属性,method中指定拦截什么类型的请求
,params指定请求必须有指定的name,并且必须有zs值,age可以没有,不
能有height参数,约定headers请求头信息,必须符合要求的头信息才可以
接收

  • RequestMethod.GET
  • RequestMethod.POST
  • RequestMethod.DELETE
  • RequestMethod.PUT
1
2
3
4
@RequestMapping(value="Spring/**/Mvc/*/Han",method="RequestMethod.POST",
params={"name=zs","age!=23""!height"},headers={
"Accept=text.....","Accept-Encoding.."
})

@PathVariable的作用?

获取动态参数

1
2
3
4
5
6
7
8
9
   @Controller //使类变为控制器
//SpringMvcHan/welcome/abc
@RequestMapping("Spring") //映射路径
public class SpringMvcHandler{
@RequestMapping("welcome/{name}")
public String welcome(@PathVariable("name") String name){
return "success";
}
}

@RequestParam的作用?

该注解有三个变量:value、required、defaultvalue

  • value :指定 name 属性的名称是什么,value 属性都可以默认不写
  • required :是否必须要有该参数,可以设置为【true】或者【false】
  • defaultvalue :设置默认值
1
2
3
4
5
6
7
8
9
@Controller //使类变为控制器
//SpringMvcHan/welcome/name=fd
@RequestMapping("Spring") //映射路径
public class SpringMvcHandler{
@RequestMapping("/welcome")
public String welcome(@RequestParam("name") String name){
return "success";
}
}

PathVariable和RequestParam

PathVariable只能用于接收url路径上的参数,而RequestParam只能
用于接收请求带的params

getAttribute与getParame的区别

  1. getAttribute表示从request范围取得设置的属性,必须要先setAttribute
    设置属性,才能通过getAttribute 来取得,设置与取得的为Object对象类型
  2. getParameter 表示接收参数,参数为页面提交的参数,包括:表单提交的
    参数、URL重写(就是xxx?id=1中的id )传的参数等,因此这个并没有设置参
    数的方法(没有setParameter),接收参数返回的不是Object,而是String
    类型

@ResponseBody的作用

把后台pojo转换json对象,返回到页面

@RequestBody的作用

接受前台json数据,把json数据自动封装pojo

1
2
3
4
5
@ResponseBody
public User requestJson(@RequestBody User user) throws Exception{
System.out.println(user);
return user;//由于@ResponseBody注解,将user转成json格式返回
}

SpringMVC中拦截器如何使用

  1. 定义拦截器,实现HandlerInterceptor接口。接口中提供三个方法。
  • preHandle :进入 Handler方法之前执行,用于身份认证、身份授权,
    比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不
    再向下执行
  • postHandle:进入Handler方法之后,返回modelAndView之前执行,应用
    场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视
    图,也可以在这里统一指定视图
  • afterCompletion:执行Handler完成执行此方法,应用场景:统一异常
    处理,统一日志处理
  1. 拦截器配置:
  • 针对HandlerMapping配置(不推荐):springMVC拦截器针对HandlerMapping
    进行拦截设置,如果在某个HandlerMapping配置拦截,经过该HandlerMapping
    映射成功的handler最终使用该 拦截器。(一般不推荐使用)
  • 类似全局的拦截器:springmvc配置类似全局的拦截器,springmvc框架将配
    置的类似全局的拦截器注入到每个HandlerMapping中

MyBatis

JDBC编程步骤

  1. 加载数据库驱动
  2. 创建并获取数据库连接
  3. 创建Statement对象
  4. 设置SQL语句
  5. 设置SQL语句中的参数
  6. 通过Statement执行SQL并获取结果
  7. 对SQL执行结果进行解析处理
  8. 释放资源
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public class JdbcTest {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
// 加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 通过驱动管理类获取数据库链接
connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8",
"root", "liayun");
// 定义sql语句 ?表示占位符
String sql = "select * from user where username = ?";
// 获取预处理statement
preparedStatement = connection.prepareStatement(sql);
//设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
preparedStatement.setString(1, "王五");
// 向数据库发出sql执行查询,查询出结果集
resultSet = preparedStatement.executeQuery();
// 遍历查询结果集
while (resultSet.next()) {
System.out.println(resultSet.getString("id") + " " +
resultSet.getString("username"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 释放资源
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

传统JDBC存在的问题

  1. 数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能,如果
    使用数据库连接池那么可解决此问题
  2. 在代码中硬编码,造成代码不易维护,实际应用中SQL语句变化的可能较
    大,如果SQL语句一旦变动,那么就需要改变Java代码了

MyBatis

MyBatis是一个优秀的持久层框架,它对JDBC 的操作数据库的过程进行了封装
,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动、创建
Connection、创建Statement、手动设置参数、结果集检索等JDBC繁杂的过程
代码了。
MyBatis通过xml或注解的方式将要执行的各种Statement配置起来,并通过Java
对象和Statement中的SQL进行映射生成最终执行的SQL语句,最后由MyBatis框
架执行SQL语句并将结果映射成Java对象并返回

如何将对象与表联系起来

  1. 先创建一张表person,然后创建对应实体类
  2. 通过mapper.xml文件创建表和类的映射关系,通过id标识SQL语句,
    resultType 是查询结果的数据类型,namespace 放映射文件的路径,
    parameterType是动态传入的参数类型
  3. 约定优于配置。使用statement+id太麻烦可以简化。在mapper包下创建
    Permapper接口,要使接口与mapper.xml文件一一对应,修改mapper文件
    的namspace改为接口路径。根据接口名找到mapper.xml文件,根据接口的
    方法名找到sql标签。一般将mapper.xml文件和接口放在一个包中,接口
    不需要实现类

两种取值符号的区别

  1. #{}表示一个占位符号,可以很好地去避免SQL注入。其原理是将占位符位
    置的整个参数和SQL语句两部分提交给数据库,数据库去执行SQL语句,去表
    中匹配所有的记录是否和整个参数一致。如果入参是普通类型,那么{}里的
    内容就可以随便写
  2. ${}表示一个SQL拼接符号,其原理是在向数据库发出SQL语句之前去拼接
    好SQL语句再提交给数据库执行。如果是取简单数据类型的参数,括号中的值
    必须为value
  3. 模糊查询时#{}必须存入参数时就写%%,而${}可以写为’%${name}%’,传
    入参数不用写%%
  4. 输入参数是对象类型,#{属性名} ${属性名}

一般情况下建议使用#{},只有在特殊情况下才必须要用到${}

  1. 动态拼接SQL中动态组成排序字段,要通过${}将排序字段传入SQL中
  2. 动态拼接SQL中动态组成表名,要通过${}将表名传入SQL中
  3. #{}会自动给string类型加上’’,使用#自动加’’相当于常量排序实际无效
    ,排序根据的是字段
  4. ${}原样输出,也就是说如果参数是string要写为’${value}’,但是$适合
    动态排序

静态排序

1
select * from pperson order by name desc

动态排序

1
select * from pperson order by ${value} desc

parameterType和resultType和resultMap

  1. parameterType 指定参数类型,MyBatis通过OGNL从输入对象中获取参数
    值并拼接再SQL中
  2. resultType 指定输出结果类型,MyBatis将SQL查询结果的一行记录数据
    映射为resultType指定类型的对象
  3. 如果类中的属性和表中的字段类型能够识别可以使用resultType,如果不
    能则需要使用resultMap,如果类型属性名和表中字段名一样则用resultType
    ,否则使用resultMap,resultMap与id对应

MyBatis的优点

  1. 配置数据库连接池,使用连接池管理数据库连接
  2. 将SQL语句配置在映射文件中与Java代码分离
  3. MyBatis可以自动将SQL语句的执行结果映射至Java对象,通过Statement
    中的resultType定义输出结果的类型

ORM是什么

ORM(Object Relational Mapping),对象关系映射,是一种为了解决关系
型数据库数据与简单Java对象(POJO)的映射关系的技术。简单的说,ORM是
通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化
到关系型数据库中

为什么说Mybatis是半自动ORM映射工具

Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集
合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以
称之为半自动ORM 映射工具。不过MyBatis可以通过XML或注解方式灵活配置要
运行的SQL语句,并将Java 对象和SQL 语句映射生成最终执行的SQL,最后将
SQL执行的结果再映射生成Java对象

Mybatis如何防止sql注入

  1. MyBatis启用了预编译功能,在SQL执行前,会先将SQL发送给数据库进
    行编译,执行时,直接使用编译好的SQL,替换占位符“?”就可以了。因为
    SQL注入只能对编译过程起作用,所以这样的方式就很好地避免了SQL注
    入的问题
  2. 底层实现原理是JDBC 中的PreparedStatement 类在起作用,该类是
    Statement 的子类,它的对象包含了编译好的SQL语句。这种“准备好”的
    方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。
    原因是SQL已编译好,再次执行时无需再编译
  3. ${xxx}
  • 缺点: 直接参与SQL编译,不能避免注入攻击
  • 优点:及到动态表名和列名时,只能使用“${xxx}”这样的参数格式
  • 注意: 这样的参数需要我们在代码中手工进行处理来防止注入
  1. #{xxx}
  • 相当于JDBC中的PreparedStatement
  • ${}:是输出变量的值
  • 优点:#{}是经过预编译的,是安全的

SpringBoot

什么是SpringBoot

Spring Boot其实就是一个整合一系列技术栈的框架,不用关心我们以前
Spring要整合各种框架时的各种配置,直接使用Spring Boot就能将这
些框架快速地使用起来
Spring Boot 是 Spring 开源组织下的子项目,是Spring组件一站式解决
方案,主要是简化了使用Spring的难度,简省了繁重的配置,提供了各种启
动器,开发者能快速上手

SpringBoot的优点

  1. 创建独立Spring应用
  2. 内嵌Web服务器 使用嵌入式servlet容器不需要打成war包,去除大量配
    置,springboot最终打成的jar包是可执行的jar包,不能作为普通的jar包
    被其他项目依赖,即使依赖也无法使用其中的类
  3. 自动starter依赖,简化构建配置,starters自动依赖于版本控制
  4. Spring 引导应用程序可以很容易地与 Spring 生态系统集成,如 Spring
    JDBC、Spring ORM、Spring Data、Spring Security 等
  5. 提供生产级别的监控、健康检查及外部化配置
  6. 无代码生成、无需编写XML

什么是微服务

把每一个功能变成一个小项目,小项目之间通过网络协议进行互通。每一个子模块
就是一个微服务所有模块连接起来就是一个项目。可更新可替代性强。springboot
可以快速开发一个微服务

  • springboot 独立的小功能
  • springcloud 功能之间的合作
  • springclouddata 功能之间并行计算

@SpringBootApplication注解

核心注解是@SpringBootApplication,标注在某个类上就说明该类是主配置
类,运行该类main方法启动应用,由三个注解组成

  1. @SpringBootConfiguration:组合了@Configuration注解,是spring
    定义的注解,标注这是一个配置类,相当于配置文件,允许在上下文中注册额
    外的 bean 或导入其他配置类
  2. @EnableAutoConfiguration:打开自动配置的功能,该注解开启自动
    配置功能,以前需要配置的东西比如spring和springmvc而springboot自
    动配置
  3. @ComponentScan:Spring组件扫描,完成包扫描,主程序类所在的包及
    其下面的所有子包里面的组件都会被默认扫描进来

@EnableAutoConfiguration注解

@EnableAutoConfiguration是合成注解由@AutoConfigurationPackage和
@Import({AutoConfigurationImportSelector.class})合成

  1. @AutoConfigurationPackage 自动配置包,该注解上面又标注了一个
    @Import({Registrar.class})注解,该注解用于给容器中导入一个组件。
    调用Registrar类型组件的registerBeanDefinitions方法来批量注册组
    件,也就是导入指定包的所有组件。所以默认扫描的包路径是主程序类所在
    的包
  2. @Import({AutoConfigurationImportSelector.class}) 批量导入
    META-INF/spring.factories 里定义的自动配置类

什么是JavaConfig?

它提供了配置Spring IoC容器的纯Java方法。因此它有助于避免使用XML配置

  1. 面向对象的配置。由于配置被定义为 JavaConfig 中的类,因此用户可以
    充分利用 Java 中的面向对象功能。一个配置类可以继承另一个,重写它的
    @Bean方法等
  2. 减少或消除XML配置
  3. 类型安全和重构友好。JavaConfig 提供了一种类型安全的方法来配置
    Spring容器

SpringBoot自动配置原理

  1. @EnableAutoConfiguration 就是用来开启自动配置
  2. 关键功能由@Import提供,其导入的AutoConfigurationImportSelector
    的selectImports()方法通过SpringFactoriesLoader.loadFactoryNames()
    扫描所有具有META-INF/spring.factories的jar包

@EnableAutoConfiguration, @Configuration, @ConditionalOnClass
就是自动配置的核心,@EnableAutoConfiguration 给容器导入META-INF
/spring.factories 里定义的自动配置类。筛选有效的自动配置类。每一个
自动配置类结合对应的xxxProperties.java读取配置文件进行自动配置功能

如何理解SpringBoot配置加载顺序?

  1. properties文件
  2. YAML文件
  3. 系统环境变量
  4. 命令行参数

什么是YML?

YAML 是一种人类可读的数据序列化语言。它通常用于配置文件,YAML文件更
加结构化,具有分层配置数据的功能,YAML配置和传统的properties配置
相比优势如下

  1. 配置有序,在一些特殊的场景下,配置有序很关键
  2. 支持数组,数组中的元素可以是基本数据类型也可以是对象
  3. 简洁

SpringBoot核心配置文件是什么?

application.properties和application.yml。YAML是以数据为中心比
json/xml更适合做配置文件,spring-boot-starter-parent默认使用
Tomcat作为web容器,如果需要对Tomcat进一步配置可以在配置文件中
配置

1
2
server.port=8081
server.servlet.context-path=/springboot
1
2
server: 
port: 8081

SpringBoot目录结构?

  • src/main/java 程序开发以及主程序入口
  • src/main/resources/application.yml 配置文件,可以修改默认配置
  • src/main/resources/static 放静态资源
  • src/test 测试程序

SpringBoot如何测试?

springboot单元测试。@SpringBootTest 标明是单元测试。可以在测试期
间很方便的类似编码一样进行自动注入等容器的功能

SpringBoot配置文件加载的位置?

springboot 启动会扫描以下位置的application.properties或者
application.yml文件作为Spring boot的默认配置文件

SpringBoot中如何解决跨域问题?

跨域可以在前端通过 JSONP 来解决,但是JSONP只可以发送GET请求,无法
发送其他类型的请求,在 RESTful 风格的应用中,就显得非常鸡肋,因此
我们推荐在后端通过(CORS,Cross-origin resource sharing)来解决
跨域问题。现在可以通过实现WebMvcConfigurer接口然后重写
addCorsMappings方法解决跨域问题

1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.maxAge(3600);
}

}

依赖管理

每一个Spring Boot工程,它里面都会有spring-boot-starter-parent这
么一个父项目,几乎声明了我们开发中所有常用的jar 包的版本号,这样我
们在子项目里面引入依赖时就不需要再写版本号了,也称为Spring Boot的
自动版本仲裁机制。本质是spring-boot-dependencies父项目里面已经声
明过了依赖的版本号

场景启动器

starter是一组依赖的集合描述,也就是说我们一般只要引入一个starter即
可,这样它的整个完整开发场景就被全部引入了,即这个场景里面所有的依
赖全部都引入进来了。starter的命名方式是spring-boot-starter-*,
其中的*代表的就是当前的某种场景

自动配置

SpringBoot中的starter到底是什么?

首先它提供了一个自动化配置类,一般命名为XXXAutoConfiguration,在
这个配置类中通过条件注解来决定一个配置是否生效(条件注解就是Spring
中原本就有的),然后它还会提供一系列的默认配置,也允许开发者根据实
际情况自定义相关配置,然后通过类型安全的属性注入将这些配置属性注入
进来,新注入的属性会代替掉默认属性

SpringBoot打成的jar和普通的jar有什么区别?

Spring Boot 项目最终打包成的 jar 是可执行jar ,这种 jar 可以直接通过
java -jar xxx.jar命令来运行,这种 jar 不可以作为普通的jar被其他项目
依赖,即使依赖了也无法使用其中的类。如果非要引用,可以在pom.xml文件中
增加配置,将SpringBoot项目打包成两个jar ,一个可执行,一个可引用

为什么使用EnableAutoConfiguration 注解?

SpringBoot 启动流程?

  1. 启动类可以分解为两部分:@SpringBootApplication注解和一个main()
    方法,里面调用SpringApplication.run()方法
  2. @SpringBootApplication由三个注解组合而成
  • @ComponentScan 这个注解的作用是告诉Spring扫描哪个包下面类,加载
    符合条件的组件(比如贴有@Component和@Repository等的类)或者bean 的
    定义,默认从声明@ComponentScan所在类的package进行扫描
  • @EnableAutoConfiguration 开启自动配置,自动配置主要则依靠这种加
    载方式来实现
  • @SpringBootConfiguration 标注当前类是配置,并会将当前类内声明的
    一个或多个以@Bean 注解标记的方法的实例纳入到spring容器中,并且实例
    名就是方法名
  1. run()方法是一个实例方法,首先创建SpringApplication实例,创建了
    SpringApplication实例之后,就完成了SpringApplication 类的初始化
    工作,这个实例里包括监听器、初始化器,项目应用类型,启动类集合,类
    加载器
  2. 接下来调用run()方法,创建计时器开始计时,创建应用上下文,打印
    日志等

过滤器

Filter 过滤器主要是用来过滤用户请求的,它允许我们对用户请求进行前置处
理和后置处理,比如实现 URL 级别的权限控制、过滤非法请求等等。Filter 过
滤器是面向切面编程——AOP 的具体实现。
如果我们需要自定义Filter 的话非常简单,只需要实现javax.Servlet.Filter
接口,然后重写里面的 3 个方法即可

1
2
3
4
5
6
7
8
9
10
11
public interface Filter {
//初始化过滤器后执行的操作
default void init(FilterConfig filterConfig) throws ServletException {
}
// 对请求进行过滤
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3)
throws IOException, ServletException;
// 销毁过滤器后执行的操作,主要用户对某些资源的回收
default void destroy() {
}
}

Filter是如何实现拦截的

Filter接口中有一个叫做 doFilter 的方法,这个方法实现了对用户请求的过
滤。具体流程大体是这样的

  1. 用户发送请求到 web 服务器,请求会先到过滤器
  2. 过滤器会对请求进行一些处理比如过滤请求的参数、修改返回给客户端的response
    的内容、判断是否让用户访问该接口等等
  3. 用户请求响应完毕
  4. 进行一些自己想要的其他操作

拦截器

拦截器同 Filter 过滤器一样,它俩都是面向切面编程——AOP 的具体实现。
你可以使用Interceptor 来执行某些任务,例如在Controller 处理请求之前
编写日志,添加或更新配置。在 Spring中当请求发送到Controller 时,在被
Controller处理之前,它必须经过拦截器。
自定义Interceptor 的话必须实现HandlerInterceptor接口或继承
HandlerInterceptorAdapter类,并且需要重写下面下面3个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//preHandle方法返回true或false。如果返回true,则意味着请求将继续到达Controller 被处理
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler)

public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView)

public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex)

过滤器和拦截器的区别

  1. 过滤器:当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定
    义这些要求的工具,就是过滤器
  2. 拦截器:在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进
    行,这是拦截器做的事情

BeanUtils

  1. 使用org.apache.commons.beanutils.BeanUtils对复杂对象的复制是引用
    ,这是一种浅拷贝
  2. 使用spring的BeanUtils进行对象拷贝

Spring Schedule 实现定时任务

在SpringBoot 中我们只需要在启动类上加上@EnableScheduling便可以启动定
时任务了。我们使用@Scheduled 注解就能很方便地创建一个定时任务

SpringBoot 异步编程

  1. @EnableAsync:通过在配置类或者Main类上加@EnableAsync开启对异步方法
    的支持
  2. @Async 可以作用在类上或者方法上,作用在类上代表这个类的所有方法都是
    异步方法

Maven

Maven是什么

是一个项目管理工具(即用来管理Java项目),使用maven可以对Java项目进行
构建、依赖管理

依赖管理

一个Java项目可能要使用一些第三方的jar包才可以运行,那么我们说这个Java
项目依赖了这些第三方的jar包。依赖管理就是对项目所有依赖的jar包进行规范
化管理。
maven项目管理所依赖的jar包不需要手动向工程添加jar包,只需要在pom.xml
(maven工程的配置文件)添加jar包的坐标即可,这样就会自动从maven 仓库
中下载jar包了,最后就能运行了。好处如下

  1. 通过pom.xml文件对jar包的版本进行统一管理,可避免版本冲突
  2. maven团队维护了一个非常全的maven仓库,里边包括了当前使用的jar包,
    maven工程可以自动从maven仓库下载jar包,非常方便

如何寻找jar包

  1. 项目所需jar包先找本地仓库
  2. 本地找不到联网中央仓库一定有,镜像仓库是对中央仓库进行分流,缓解
    中央仓库压力

项目构建

项目构建是一个项目从编写源代码到编译、测试、运行、打包、部署、运行的过程。
传统的构建过程如下:

  1. 创建Java Web工程
  2. 在工程中编写源代码及配置文件等
  3. 对源代码进行编译,java文件编译成class文件
  4. 执行Junit单元测试
  5. 将工程打成war包部署至Tomcat服务器中运行

maven将项目构建的过程进行了标准化,每个阶段使用一个命令来完成

  • 清理 mvn clean:删除target目录及其目录下的所有内容
  • 编译 mvn compile:将src/main/java下的java源文件编译为class文件
    并输出到target下的classes目录下
  • 测试 mvn test:运行该命令会执行src/test/java下的单元测试类
  • 打包 mvn package:把Java工程打成jar包,把Web工程打成war包
  • 安装 mvn install:会将maven工程打成jar包或war包并发布到本地仓库
  • 部署 放到服务区准备运行

maven工程构建的优点有以下两点:

  1. 一个命令完成构建、运行,方便快捷
  2. maven对每个构建阶段进行规范,非常有利于大型团队协作开发

maven的生命周期

生命周期包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署
和站点生成等几乎所有构建步骤,maven对项目构建过程分为三套相互独立的
生命周期,每套生命周期都由一组阶段(Phase)组成的,这些阶段是有顺序
的,并且后面的阶段依赖于前面的阶段

  1. Clean Lifecycle(项目清理)在进行真正的构建之前进行一些清理工作
  2. Default Lifecycle(默认构建)包括编译、测试、打包、部署
  3. Site Lifecycle 建立和发布项目站点,maven能够基于POM所包含的信
    息,自动生成一个友好的站点,方便团队交流和发布项目信息

Vue

什么是vue

Vue是一个渐进式的框架,渐进式意味着你可以将Vue作为你应用的一部分嵌入
其中,带来更丰富的交互体验,或者如果你希望将更多的业务逻辑使用Vue实
现,那么Vue的核心库以及其生态系统。比如Core+Vue-router+Vuex,也可
以满足你各种各样的需求

什么是组件化开发

如果将一个复杂的问题,拆分成很多个可以处理的小问题,再将其放在整体
当中,你会发现大的问题也会迎刃而解。组件化也是类似的思想如果我们将
一个页面中所有的处理逻辑全部放在一起,处理起来就会变得非常复杂,
而且不利于后续的管理以及扩展。但如果,我们讲一个页面拆分成一个
个小的功能块,每个功能块完成属于自己这部分独立的功能,那么之后
整个页面的管理和维护就变得非常容易了

单页面应用和多页面应用的区别

  1. 整个网页只有一个html页面,静态资源服务器中可能只有一个html文件
    一个css文件,一个javascript文件,url和页面组件的映射关系是由
    前端路由管理url发生改变时会抽取相应的组件,整个页面并没有刷新
    在用户与应用程序交互时动态更新该页面的Web应用程序,不过首次加
    载页面时需要加载大量的静态资源
  2. 一个应用有多个页面,页面跳转是整页刷新

Swagger

Swagger 就是一套基于 OpenAPI 规范构建的开源工具,可以帮助我们设计
、构建、记录以及使用 Rest API。
前后端分离的情况下,一份Rest API文档将会极大的提高我们的工作效率。前
端小伙伴只需要对照着Rest API 文档就可以搞清楚一个接口需要的参数以及
返回值。通过 Swagger 我们只需要少量注解即可生成一份自带 UI 界面的
Rest API 文档,不需要我们后端手动编写。并且,通过 UI 界面,我们还
可以直接对相应的 API 进行调试,省去了准备复杂的调用参数的过程。
添加一个jar 包即可

1
2
3
4
5
6
<!-- swagger 直接在浏览器中访问:http://ip:port/swagger-ui/-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>

kafka

Kafka 相比其他消息队列主要的优势如下:

  1. 极致的性能 :基于 Scala 和 Java 语言开发,设计中大量使用了批量处理
    和异步的思想,最高可以每秒处理千万级别的消息
  2. 生态系统兼容性无可匹敌 :Kafka 与周边生态系统的兼容性是最好的没有之
    一,尤其在大数据和流计算领域

Kafka 是一个分布式流式处理平台,流平台具有三个关键功能:

  1. 消息队列:发布和订阅消息流,这个功能类似于消息队列,这也是Kafka 也被
    归类为消息队列的原因
  2. 容错的持久方式存储记录消息流: Kafka 会把消息持久化到磁盘,有效避免
    了消息丢失的风险
  3. 流式处理平台: 在消息发布的时候进行处理,Kafka 提供了一个完整的流式
    处理类库
Author: 高明
Link: https://skysea-gaoming.github.io/2021/02/24/%E6%A1%86%E6%9E%B6%E6%8A%80%E6%9C%AF%E6%80%BB%E7%BB%93/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.