1.今天實現基本的構建框架,異常處理,日誌處理
-首先我們這裏插入 AOP的基本概念
@Aspect(切面): 通常是一個類,裏面可以定義切入點和通知
JointPoint(連接點): 程序執行過程中明確的點,一般是方法的調用
Advice(通知): AOP在特定的切入點上執行的增強處理:
@Before: 標識一個前置增強方法,相當於BeforeAdvice的功能
@After: final增強,不管是拋出異常或者正常退出都會執行。
@AfterReturning: 後置增強,似於AfterReturningAdvice, 方法正常退出時執行
@AfterThrowing: 異常拋出增強,相當於ThrowsAdvice
@Around: 環繞增強,相當於MethodInterceptor
Pointcut(切入點): 帶有通知的連接點,在程序中主要體現爲書寫切入點表達式
AOP Proxy:AOP框架創建的對象,代理就是目標對象的加強。Spring中的AOP代理可以使JDK動態代理,也可以是CGLIB代理,前者基於接口,後者基於子類。
1.這是初期創建好項目的整體結構
2.
這裏是pom.xml導入的依賴
`<?xml version="1.0" encoding="UTF-8"?>
4.0.0
<groupId>com.xyj</groupId>
<artifactId>blog</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>blog</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.5.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3.application.yml文件配置,application-dev.yml, application-pro.yml三個yml配置,這樣做爲了區別生產環境,輸出日誌
spring:
thymeleaf:
mode: HTML
profiles:
active: dev
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
jpa:
hibernate:
ddl-auto: update
show-sql: true
logging:
level:
root: info
com.lrm: debug
file: log/blog-dev.log
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
jpa:
hibernate:
ddl-auto: none
show-sql: true
logging:
level:
root: warn
com.lrm: info
file: log/blog-pro.log
server:
port: 8081
4.這裏是logback-spring.xml的配置
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--包含Spring boot對logback日誌的默認配置-->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<!--重寫了Spring Boot框架 org/springframework/boot/logging/logback/file-appender.xml 配置-->
<appender name="TIME_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i</fileNamePattern>
<!--保留歷史日誌一個月的時間-->
<maxHistory>30</maxHistory>
<!--
Spring Boot默認情況下,日誌文件10M時,會切分日誌文件,這樣設置日誌文件會在100M時切分日誌
-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="TIME_FILE" />
</root>
</configuration>
<!--
1、繼承Spring boot logback設置(可以在appliaction.yml或者application.properties設置logging.*屬性)
2、重寫了默認配置,設置日誌文件大小在100MB時,按日期切分日誌,切分後目錄:
blog.2017-08-01.0 80MB
blog.2017-08-01.1 10MB
blog.2017-08-02.0 56MB
blog.2017-08-03.0 53MB
......
-->
5.ControllerExceptionHandler類
package com.xyj.blog.handler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
/**
* @author xyj
* @date 2020/4/3 -21:19
* 異常返回error
*/
@ControllerAdvice
public class ControllerExceptionHandler {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@ExceptionHandler(Exception.class)
public ModelAndView exceptionHander(HttpServletRequest request, Exception e) throws Exception {
logger.error("Requst URL : {},Exception : {}", request.getRequestURL(),e);
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
throw e;
}
ModelAndView mv = new ModelAndView();
mv.addObject("url",request.getRequestURL());
mv.addObject("exception", e);
mv.setViewName("error/error");
return mv;
}
}
小黑板重點來了
爲了讓你的404,500不那麼難看,所以這裏我們先簡易的做個錯誤跳轉的頁面。
1.NotFoundException類
package com.xyj.blog;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {
public NotFoundException() {
}
public NotFoundException(String message) {
super(message);
}
public NotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
2.IndexController,這裏故意做一個錯誤,你可以試驗一下500錯誤9/0
package com.xyj.blog.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @author xyj
* @date 2020/4/3 -21:13
*/
@Controller
public class IndexController {
@GetMapping("/")
public String index() {
int i = 9/0;//這裏故意做一個錯誤,你可以試驗一下500錯誤
// String blog = null;
// if (blog == null) {
// throw new NotFoundException("博客不存在");
// }
return "index";
}
@GetMapping("/blog")
public String blog() {
return "blog";
}
}
3.400.500錯誤頁面你可以從網上嫖一個漂亮的模板,我這裏就很簡單了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404</title>
</head>
<body>
<h1>404</h1>
</body>
</html>
你可以在localhost:8080/後面隨便瞎輸入一個網址,這樣就可以測試你的跳轉是否成功
查看目錄網址,直接傳送