2、 SpringBoot
一、Spring Boot 使用 slf4j 日志
在开发中经常使用 System.out.println()来打印一些信息,但是这样不好,因为大量的使用 System.out 会增加 资源的消耗。实际项目中使用的是 slf4j 的 logback 来输出日志,效率挺高的,Spring Boot 提供了一套日志系 统,logback 是最优的选择。
控制台打印输出日志
System.out.println(需要输出的内容字符串)
一般在开发阶段需要输出的信息较多,作为产品部署后则输出信息较少,引入了一种常量的定义方式以控制是 否输出日志
可以通过 Constants 接口中的常量定义是否需要输出,或者使用 int 型来控制不同的输出等
1、外观模式:
【应用场景、优缺点、编码】
为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容 易使用。可以降低访问复杂系统的内部子系统时的复杂度,简化客户端之间的接口。属于 23 种设计模式中的 结构型设计模式
-
优点: 1、减少系统相互依赖。 2、提高灵活性。 3、提高了安全性。
-
缺点:不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。
编码实现:
//1、产品接口 interface Shape{ public void draw(); } //2、具体实现 class Circle implements Shape{ public void draw(){ System.out.println("绘制一个圆形"); } } class Square implements Shape{ public void draw(){ System.out.println("绘制一个正方形"); } }
2、slf4j
SLF4J 即简单日志门面,不是具体的日志解决方案,它只服务于各种各样的日志系统。SLF4J 是一个用于日志系统的简单 Facade,允许最终用户在部署其应用时使用其所希望的日志系统。 即只需要按统一的方式写记录日志的代码,而无需关心日志是通过哪个日志系统,以什么风格输 出的。因为它们取决于部署项目时绑定的日志系统。例如,在项目中使用了 slf4j 记录日志,并且绑定了 log4j, 即导入相应的依赖,则日志会以 log4j 的风格输出;后期需要改为以 logback 的风格输出日志,只需要将 log4j 替换成 logback 即可,不用修改项目中的代码。
1、slf4j-log4j 通过 slf4j 调用 log4j
1)添加依赖
2)将log4j.properties添加到resources里面
log4j.rootLogger=DEBUG,stdout,logFile log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n log4j.appender.logFile=org.apache.log4j.FileAppender log4j.appender.logFile.ImmediateFlush=true log4j.appender.logFile.Append=true log4j.appender.logFile.File=D:/logs/log.log4j log4j.appender.logFile.layout=org.apache.log4j.PatternLayout log4j.appender.logFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
目前 SpringBoot 针对日志系统默认采用 logback
3)配置
1. application.yml 中对日志的配置 server: port: 8080 logging: config: classpath:logback.xml level: com.dyx.action: debu 2.logback.xml 配置文件解析【java笔记里面的文件赋值
二、Spring Boot 的项目属性配置
在项目中很多时候需要用到一些配置的信息,这些信息可能在测试环境和生产环境下会有不同的配置,后面根 据实际业务情况有可能还会做修改,针对这种情况不能将这些配置在代码中写死,最好就是写到配置文件中。 比如可以把这些信息写到 application.yml 文件中。 在具体应用中实际上 application.properties 和 application.yml 都可以使用,并允许同时使用。如果同时进行配 置,且配置冲突,则 properties 优先于 yml
1、少量配置信息的情形
例如在微服务架构中,最常见的就是某个服务需要调用其他服务来获取其提供的相关信息,那么在该服务的配 置文件中需要配置被调用的服务地址,比如在当前服务里需要调用订单微服务获取订单相关的信息,假设订单 服务的端口号是 8002,那可以做配置:
server: port: 8002
配置微服务的地址 url: # 自定义的订单微服务的地址。不是系统预定义的配置,所以不会出现任何提示
2、多个配置信息的情形
随着业务复杂度的增加,一个项目中可能会有越来越多的微服务,某个模块可能需要调 用多个微服务获取不同的信息,那么就需要在配置文件中配置多个微服务的地址。可是在需要调用这些微服务 的代码中,如果这样一个个去使用@Value 注解引入相应的微服务地址的话,太过于繁琐,也不科学。所以在实际项目中,业务繁琐,逻辑复杂的情况下,需要考虑封装一个或多个配置类。
举个例子:假如在当前服务中,某个业务需要同时调用订单微服务、用户微服务和购物车微服务,分别获取订 单、用户和购物车相关信息,然后对这些信息做一定的逻辑处理。那么在配置文件中,需要将这些微服务的地 址都配置好
url: 配置多个微服务的地址 url: orderUrl: http://www.baidu.com 订单微服务的地址 userUrl: http://localhost:8003 用户微服务的地址 shoppingUrl: http://localhost:8004 购物车微服务的地 num: 8
//MicroServiceUrl 类来专门保存微服务的 url。如果配置较多,可以自定义一个专门用于存储配置参数的类 @Component //定义受管 bean,否则 Spring 无法注入配置参数值 @ConfigurationProperties(prefix = "url") //用于读取配置信息,声明配置以 url 开头。需要解析的 key 是以 url. 开始的 public class MicroServiceUrl { //专门用于存储配置信息的类 private String orderUrl; //其中的属性名称和 key 对应的除去 url.部分之外的内容一致,例如这里对应 url.orderUrl private String userUrl; private String shoppingUrl; // 省去 get 和 set 方法 }
使用@ConfigurationProperties 注解需要导入它的依赖: spring-boot-configuration-processor
代码
@RestController @RequestMapping("/test") public class TestController { @Value("${url.orderUrl}") private String orderURL; @Autowired private MicroServiceUrl microServiceUrl; private static final Logger logger= LoggerFactory.getLogger(TestController.class); @GetMapping("/params") public String params(){ logger.warn("========="+orderURL); logger.error("========="+microServiceUrl.getOrderUrl()); logger.error("========="+microServiceUrl.getUserUrl()); return "success"; } }
3、指定项目配置文件
在实际项目中,一般有两个环境:开发环境和生产环境。开发环境中的配置和生产环境中的配置往往不同,比 如环境、端口、数据库、相关地址等。实际上不可能在开发环境调试好之后,部署到生产环境后,又要将配置 信息全部修改成生产环境上的配置,这样太麻烦,也不科学。 最好的解决方法就是开发环境和生产环境都有一套对用的配置信息,然后当在开发时,指定读取开发环境的配 置,当将项目部署到服务器上之后,再指定去读取生产环境的配置。
三、Spring Boot 中的 MVC 支持
Spring Boot 的 MVC 支持主要来最常用的几个注解,包括@RestController 用于声明控制器、@RequestMapping 用于实现方法映射地址、@PathVariable 用于接受路径中的参数、@RequestParam 用于接受 request 请求中的 参数以及@RequestBody 用于接受 application/json 类型的请求信息。
1、@RestController
@RestController 是 Spring Boot 新增的一个注解,等价于@Controller+@ResponseBody
为了编码方便建议使用@RestController 后就不用再使用@Controller 了。@Controller 则返回的是逻辑地址名 但是需要注意一个问题:如果是前后端分离,不用模板渲染的话,如 Thymeleaf,这种情况下是可以直接使用 @RestController 将数据以 json 格式传给前端,前端拿到之后解析;但如果不是前后端分离,需要使用模板来渲染的话,一般 Controller 中都会返回到具体的页面,那么此时就不能使用@RestController
其实是需要返回到 user.html 页面的,如果使用@RestController 的话,会将 user 作为字符串返回的。如果使 用@Controller 注解则表示返回一个逻辑地址名 user 字符串,需要依赖于 ViewResovler 组件将逻辑地址名称转 换为物理地址。在 Spring Boot 集成 Thymeleaf 模板引擎中会使用。
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.html
如果使用@Controller,方法的返回值是字符串 user,则前后缀自动生效,将逻辑地址名 user 转换为物理地址名/user.html,静态页面默认存储位置可以考虑使用 resources/static 目录
2、@RequestMapping
@RequestMapping 是一个用来处理请求地址映射的注解,它可以用于类上,也可以用于方法上。在类的级别 上的注解会将一个特定请求或者请求模式映射到一个控制器之上,表示类中的所有响应请求的方法都是以该地 址作为父路径;在方法的级别表示进一步指定到处理方法的映射关系。
该注解有 6 个属性,一般在项目中比较常用的有三个属性:value、method 和 produces。
-
value 属性:指定请求的实际地址,如果注解中只有一个 value 属性时,value=可以省略不写
-
method 属性:指定请求的类型,主要有 GET、PUT、POST、DELETE,默认为 GET。如果没有对应请求 方法的定义,则页面上报错 type=Method Not Allowed, status=405
-
produces 属性:指定返回内容类型,如 produces = "application/json; charset=UTF-8"
3、@PathVariable
@PathVariable 注解主要是用来获取 url 参数,Spring Boot 支持 restfull 风格的 url
比如一个 GET 请求携带一 个参数 id 过来 localhost:8080/user?id=123,可以将 id 作为参数接收,注解使用@RequestParam。如果使用路径参数则使用@PathVariable 注解。
@GetMapping("/user/{id}") 例如 http://localhost:8080/user/123 这里的{id}对应的就是 123 值。
4、@RequestParam
@RequestParam 也是获取请求参数的,@PathValiable 注解也是获取请求参数的
@RequestParam 和@PathVariable 有什么不同呢?主要区别在于:
-
@PathValiable 是从 url 模板中获取参数值, 即这种风格的 url 为 http://localhost:8080/user/{id};
-
@RequestParam 是从 request 里面获取参数值,即这 种风格的 url 为 http://localhost:8080/user?id=1
5、@RequestBody
@RequestBody 注解用于接收前端传来的实体,接收参数也是对应的实体,比如前端通过 json 提交传来两个参数 username 和 password,此时需要在后端封装一个实体来接收。在传递的参数比较多的情况下,使用 @RequestBody 接收会非常方便。
@RequestBody 注解用于 POST 请求上,接收 json 实体参数