SpringBoot
//第一章:第一个 SpringBoot
1.启动方式:
(1):直接运行main方法
(2):mvn spring-boot:run ctrl+c停止
(3):mvn install
java -jar springbootdemo.jar
ctrl+c停止
项目根目录执行
mvn install -DskipTests
mvn install -Dmaven.test.skip=true
//注解
@RestController = @Controller + @ResponseBody默认直接返回json
2.需要修改默认端口号时及上下文路径时,只需要在:application.properties设置以下属性:
# 端口号
server.port=8888
# 应用上下文路径
setver.server.context-path=/chapter1
//第三章:springboot配置详解
1.springboot默认的全局配置文件名
application.properties
blog.address=https://blog.lqdev.cn
blog.author=oKong
支持自定义属性:通过@Value("${blog.author}") 取值
在配置文件中,各个属性参数可进行引用的
blog.desc = ${blog.author},${blog.address}
application.yml--spring官方推荐使用的格式是.yml格式目前官网都是实例都是使用yml格式进行配置讲解的
应用程序启动时,会自动加载配置文件,除此之外还有一个bootstrap文件,它的加载顺序在配置文件之前,主要用于应用程序上下文的引导。
springCloudConfig主要利用bootstrap进行配置文件的动态修改。
通常情况下:bootstrap和application是没有区别的。
springBoot的配置文件可以通过${random.int}此种方式来产生int值,long值或String字符串。
注意:
springboot在读取properties文件时,使用的是PropertiesPropertySourceLoader类进行读取,默认读取的编码是ISO 8859-1,
故在默认的配置文件中使用中文时,会出现乱码,此时可以将中文转成Unicode编码或者使用yml配置格式(默认就支持utf-8),
再不济可以将作为配置写入到一个自定义配置文件,利用@PropertySource注解的encoding属性指定编码
2.属性原文件,建议放在META-INF路径下
additional-spring-configuration-metadata.json属性元文件
//第四章:日志配置
1.spring默认配置了error,warn和info级别的日志输出到控制台。
2.切换日志级别为debug
(1):运行命令后加--debug标志,如:java -jar myapp.jar --debug;
(2):application.properties中配置debug=true,核心Logger(包含嵌入式容器,hibernate,spring)会输出更多的内容,
但是你自己应用的日志不会输出为debug级别。
3.日志的文件输出
springBoot默认只会将日志输出到控制台,但是生产环境一般日志都以文件的方式输出。
文件输出:application.properties中配置logging.file或logging.path属性。
logging.file:设置文件,可以是决定路径,也可以是相对路径。如:logging.file=my.log
logging.path:设置目录,会在该目录下创建spring.log,并写入日志内容,如:logging.path=/var/log
4.自定义日志配置
由于日志服务一般都在ApplicationContext创建前就初始化了,它并不是必须通过Spring的配置文件控制。
因此通过系统属性和传统的Spring Boot外部配置文件依然可以很好的支持日志控制和管理。
根据不同的日志系统,你可以按如下规则组织配置文件名,就能被正确加载:
Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
Log4j:log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
Log4j2:log4j2-spring.xml, log4j2.xml
JDK (Java Util Logging):logging.properties
//第五章:多环境配置
1.profile是spring针对不同环境不同配置的支持。需要满足application-{profile}.properties,{profile}对应环境标识。
application-dev.properties--开发环境
application-test.properties--测试环境
(1):使用哪个配置文件只需要在application.properties中配置spring.profiles.active为对应的{profile}的值。
#指定环境为dev
spring.profiles.active=dev
(2):也可以在命令行直接激活属性配置
java -jar xxx.jar --spring.profiles.active=test
//注解
@@SpringBootApplication:特别注意:因为包扫描的好像只是入口类所在的包,或者入口类所在包的下级,
指定要扫描的包:@SpringBootApplication(scanBasePackages="com.anjunshuang")
或者: @SpringBootApplication
@ComponentScan(basePackages = {"com.anjunshuang.bean","com.anjunshuang.demo"})
//第六章:常用注解的介绍及使用
@SpringBootApplication:组合注解
@SpringBootConfiguration:继承于@Configuration,会将当前类中声明的以@Bean注解标记的方法的实例纳入到spring容器中。实例名就是方法名。
@EnableAutoConfiguration:springBoot能实现自动配置的关键,通过该注解,能将所有符合自动配置条件的bean的定义加载到spring容器中,
例如:根据spring-boot-starter-web判断你的项目是否添加了webMvc和tomcat,就会自动的帮你配置web项目中所需要的默认配置
@CompantScan:扫描当前包及其子包下被@Component、@Controller、@Service、@Responsitory等注解标注的类并纳入到spring容器中。
@ResquestMapping
处理请求地址映射:应用于类或方法上,应用类上的话标识所有的方法都以它作为父路径。
@GetMapping:
@PostMapping:
@PutMapping:
@DeleteMapping:
@PatchMapping:
@RequestBody和@ResponseBody
@RequestBody注解允许request的参数在reqeust体中,常常结合前端POST请求,进行前后端交互。
@ResponseBody注解支持将的参数在reqeust体中,通常返回json格式给前端。
简单理解:RequestBody将json格式或其他格式数据转换成pojo对象
ResponseBody将pojo对象转换成json或者其他格式数据返回给前端。
***例如:以前遇到json格式转对象失败的,需要添加RequestBody注解***
@PathVariable、@RequestParam、@RequestAttribute
@PathVariable用来接收参数,如/path/001,可接收001作为参数
@RequestParam 用来接收URL中的参数,如/param?id=001,可接收001作为参数
@RequestAttribute用于访问由过滤器或拦截器创建的、预先存在的请求属性,效果等同与request.getAttrbute()
@Component、@Service、@Repository
这三者都是申明一个单例的bean类并纳入spring容器中,后两者其实都是继承于@Component。
//第七章:过滤器、监听器、拦截器
过滤器:
Filter:拦截请求。例如:通过session判断用户是否登录、判断访问的URL是否有访问权限。
1.WebFilter
Servlet3.0新增的注解。以前实现过滤器,需要在web.xml进行配置。
通过此注解,项目启动时会自动扫描自动注册。
2.启动类上加上@ServletComponentScan注解即可。
@ServletComponentScan:指定扫描路径,此类通过setOrder方法,可以为filter设置排序值,使spring注册Web filter之前排序后依次排序。
上述两步过滤器已经生效了,但当存在多个过滤器时,无法指定过滤器的加载顺序,需要配合@Order使用。
下面介绍FilterRegistrationBean进行过滤器的注册。设置排序顺序。
(1):通过过滤器的java类名称,进行顺序的约定,比如LogFilter和AuthFilter,此时AuthFilter就会比LogFilter先执行,因为首字母A比L前面。
***使用过滤器注册排序,过滤器就不需要@WebFilter注解了,不然过滤器会执行两遍。
过滤器Filter,是Servlet的的一个实用技术了。可通过过滤器,对请求进行拦截,比如读取**session判断用户是否登录**、
判断访问的**请求URL是否有访问权限(黑白名单)**等。
主要还是可对请求进行预处理。接下来介绍下,在springboot如何实现过滤器功能。
监听器:
Listener是servlet规范中定义的一种特殊类。用于监听servletContext、HttpSession和servletRequest等域对象的创建和销毁事件。
监听域对象的属性发生修改的事件。用于在事件发生前、发生后做一些必要的处理。一般是获取在线人数等业务需求。
拦截器:
以上的过滤器、监听器都属于Servlet的api,我们在开发中处理利用以上的进行过滤web请求时,还可以使用Spring提供的拦截器(HandlerInterceptor)进行更加精细的控制。
@controller 控制器(注入服务)
@service 服务(注入dao)
@repository dao(实现dao访问)
@component (把普通pojo实例化到spring容器中,相当于配置文件中的
//第八章:统一异常、数据校验处理
默认的异常显示无论对于开发者和调用者来说都是不够友好的。
1.创建全局的统一异常处理类:
@ControllerAdvice和@ExceptionHandler定义一个统一异常处理类。
@ControllerAdvice:控制器增加,使@ExceptionHandler、@InitBinder、@ModelAttribute注解的方式应用到所有的@ResquestMapping注解的方法。
@ExceptionHandler:异常处理器,此注解的作用是当出现其定义的异常时,进行处理的方法。
***spring 对于 RuntimeException 异常才会进行事务回滚。
***freemarker引入一个依赖即可,不需要任何配置
@Param:用来在DAO层中声明参数
当你使用了使用@Param注解来声明参数时,使用 #{} 或 ${} 的方式都可以。
当你不使用@Param注解来声明参数时,必须使用使用 #{}方式。如果使用 ${} 的方式,会报错。
2,不使用@Param注解
不使用@Param注解时,参数只能有一个,并且是Javabean。在SQL语句里可以引用JavaBean的属性,而且只能引用JavaBean的属性。
//第九章:整合mybatis
//第十章:Swagger2的集成和使用
Swagger2是一款RESTful接口文档在线自动生成、功能测试功能框架。一个规范和完整的框架,用于生成、描述、调用和可视化RESTful风格的web服务,
加上swagger-ui,可以有很好的呈现。
<%@ page pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
http://127.0.0.1:8080/swagger-ui.html
1.No mapping found for HTTP request with URI [/swagger-ui.html] in DispatcherS
拦截器中添加拦截代码,将jar包总的swagger-ui.html拦截到springBoot的resource中。
2.Unable to infer base url. This is common when using dynamic servlet registration or when the API is
@EnableSwagger2注解添加到springBoot的启动类中。
//第十一章:Redis的集成和简单使用
Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
配置自动加载类为:org.springframework.boot.autoconfigure.data.redis.RedisProperties,
可在属性文件中点击某属性快捷跳转。注意到其启动类为org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration。这里就不介绍了,
后面会写一篇关于Springboot自动加载配置的文章。
(1):redis下载地址:https://github.com/dmajkic/redis/downloads
(2):redis服务器端启动:redis-server.exe redis.conf
(3):redis客户端连接:redis-cli.exe -h 127.0.0.1 -p 6379 -a 123456,其中 127.0.0.1是本地ip,6379是redis服务端的默认端口,123456是redis密码
(4):中文乱码: --raw
(5):常用命令:
查看所有:keys * 清空所有:flushall
Spring Cache是Spring框架提供的对缓存使用的抽象类,支持多种缓存,比如Redis、EHCache等,集成很方便。同时提供了多种注解来简化缓存的使用,可对方法进行缓存
//第十二章:RabbitMQ的集成和使用
RabbitMQ service is already present - only updating service parameters
"WARNING: Using RABBITMQ_ADVANCED_CONFIG_FILE: C:\Users\admin\AppData\Roaming\RabbitMQ\advanced.config"
ERROR: node with name "rabbit" already running on "DESKTOP-G1NII5E"
****>rabbitmqctl stop
//第十四章:基于Docker的简单部署
Docker,是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,
也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
//第十七章:web应用开发之文件上传
Current request is not a multipart request
压根就没有选择文件
Required request part 'file' is not present
多了配置
spring.http.multipart.enabled默认是true,所以加载类MultipartAutoConfiguration会自动加载,这样fileUpload就会异常了。
所以正常有两种方式:在启动类下将此配置类不进行自动加载
//SpringBoot | 第十八章:web应用开发之WebJars使用
SpringBoot单独整合Jsp和Thymeleaf都还好,没出现什么问题。但是在一起之后,就有了改变,因为SpringBoot默认的模板引擎是Thymeleaf,
加上JSP之后,JSP的模板引擎并不会生效。但是如果想用JSP模板,此时的禁用到Thymeleaf,虽然可以通过多态更改配置实现,但是感觉太过麻烦了。于是研究了一下,找到了共存的方法。
共存方法:通过添加配置,指定路径。
http://127.0.0.1:8080/webjars/springBoot.jpg
//番外:小技巧合集
跨域问题是可以通过nginx来解决的,或者通过jsonp(只支持get请求)来解决。而SpringBoot中也提供了配置方法。
0.利用@CrossOrigin注解,可放至在类上或者方法上。类上代表整个控制层所有的映射方法都支持跨域请求。
@CrossOrigin(origins = "http://blog.lqdev.cn", maxAge = 3600)
@RestController
public class demoController{
@GetMapper("/")
public String index(){
return "hello,CORS";
}
}
1.配置全局CORS配置。官网也有给出实例
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**").allowedOrigins("https://blog.lqdev.cn");
}
};
}
}
//第十九章:web应用开发之WebSocket
后端关于WebSocket的实现是基于JSR356标准的。该标准的出现,统一了 WebSocket的代码写法。只要支持web容器支持JSR356标准,那么实现方式是一致的。
而目前实现方式有两种,一种是注解方式,另一种就是继承(继承javax.websocket.Endpoint)类了。
@WebSocketEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端。注解的值将被用于监听用户连接的终端访问URL地址。
@onOpen 打开一个新连接,即有新连接时,会调用被此注解的方法。
@onClose 关闭连接时调用。
@onMessage 当服务器接收到客户端发送的消息时所调用的方法。
@PathParam 接收uri参数的,与@PathVariable功能差不多,可通过url获取对应值
//第二十章:异步开发之异步请求
servlet3.0之前,servlet一直采用Thread-pre-Request的方式处理请求,即每一次http请求从头到尾都由一个线程处理。
servlet3.0之后,我们可以从HttpServletRequest中获取一个**AsyncContext**对象,该对象构成了异步处理的上下文,request和response对象都可以从中获取。
AsyncContext可以从当前线程传给另一个线程,并在新的线程中完成处理并返回结果给客户端。
//第二十一章:异步开发之异步调用
开发过程中,会遇到一个方法和实际业务无关,没有紧密性的,例如日志信息等业务。这个时候正常就是启动一个新线程去做一些业务处理。
主线程异步的执行其他业务。
何为异步调用
说异步调用前,我们说说它对应的同步调用。通常开发过程中,一般上我们都是同步调用,即:程序按定义的顺序依次执行的过程,每一行代码执行过程必须等待上一行代码执行完毕后才执行。
而异步调用指:程序在执行时,无需等待执行的返回值可继续执行后面的代码。显而易见,同步有依赖相关性,而异步没有,所以异步可并发执行,可提高执行效率,在相同的时间做更多的事情。
**题外话:**处理异步、同步外,还有一个叫回调。其主要是解决异步方法执行结果的处理方法,比如在希望异步调用结束时返回执行结果,这个时候就可以考虑使用回调机制。
**springBoot--需要在启动类加入@EnableAsync使异步调用@Async注解生效
***future:
thread.start();--线程开始运行
thread.join();一般是在主线程中启动了一个子线程,然后主线程等待子线程执行完毕才能执行。也就是说join方法会阻塞主线程。
isDone();任务是否执行完毕。
//第二十二章:定时任务的使用
Timer:jdk中自带的一个定时调度类,可以简单的实现按某一频度进行任务执行。提供的功能比较单一,无法实现复杂的调度任务。
ScheduledExecutorService:也是jdk自带的一个基于线程池设计的定时任务类。其每个调度任务都会分配到线程池中的一个线程执行,所以其任务是并发执行的,互不影响。
Spring Task:Spring提供的一个任务调度工具,支持注解和配置文件形式,支持Cron表达式,使用简单但功能强大。
Quartz:一款功能强大的任务调度器,可以实现较为复杂的调度功能,如每月一号执行、每天凌晨执行、每周五执行等等,还支持分布式调度,就是配置稍显复杂。
***ScheduledExecutorService可以说是Timer的替代类,因为Timer不支持多线程,任务是串行的,而且也不捕获异常,假设某个任务异常了,整个Timer就无法运行了。
2.基于SpringTask实现定时任务
使用SpringTask在SpringBoot是很简单的,使用@Scheduled注解即可轻松搞定
//第二十三章:日志管理之整合篇
log4j 2.x版本不再支持像1.x中的.properties后缀的文件配置方式,2.x版本配置文件后缀名只能为".xml",".json"或者".jsn"。