Springboot的日誌管理&Springboot整合Junit測試&Springboot中AOP的使用

==============Springboot的日誌管理=============

  springboot無需引入日誌的包,springboot默認已經依賴了slf4j、logback、log4j等日誌。我習慣用slf4j,下面就用slf4j作配置。html

若是你導入了spring-boot-starter-web,這個會自動依賴上述日誌。以下依賴:java

 

0.日誌測試類:

package daoTest; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import cn.qlq.MySpringBootApplication; @RunWith(SpringRunner.class) @SpringBootTest(classes = MySpringBootApplication.class) public class PlainTest { private static final Logger logger = LoggerFactory.getLogger(PlainTest.class); @Test public void findAll() { logger.error("error , msg->{} ", "錯誤"); logger.info("info , msg->{} ", "信息"); } }

 

1.springboot默認的日誌級別是debug

 

 

2.若是須要修改日誌的相關配置能夠修改applications.properties文件

############################################################ # # 日誌相關配置(默認集成的有slf4j,Logback等) # ############################################################ #指定配置文件的位置,只能是xml或者groovy結尾 #logging.config=classpath:logback.xml #默認的日誌級別 logging.level.root=INFO # mapper 接口所在的包設置爲 debug logging.level.cn.qlq.mapper=DEBUG #生成日誌文件的位置 logging.file=G:/springboot.log #生成日誌文件的目錄,名稱默認爲spring.log #logging.path=e:/ #指定日誌的格式 #logging.pattern.console=%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %clr(%logger){cyan} %clr(%msg%n){green} #logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n

     解釋:上面logging.level.root能夠指定因此包默認的日誌級別,logging.level.cn.qlq.mapper是對單獨的子包設定日誌級別,其級別可低於上面的root,也能夠高於rootweb

    logging.file是指定文件日誌的輸出位置以及名稱,logging.path是指定日誌文件的位置,默認名稱是spring.log(若是二者都配置以logging.file生效)spring

    最後面是指定控制檯和輸出文件的日誌格式。sql

    logging.config是指定配置文件的位置,只能是xml或者groovy結尾。springboot

 

  關於日誌級別等大體相同,參考:http://www.javashuo.com/article/p-eqaqjdod-es.htmlapp

==============Springboot整合Junit測試=============

Springboot中咱們也能夠像在普通的SSM環境中進行SpringJunit測試。spring-boot

1.引入測試須要的模塊

<!--springboot單元測試 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

2.創建測試目錄,通常在src/test/java下面和src/test/resources目錄下

  mapper文件和配置文件要複製到src/test/resources目錄下。單元測試

3.創建測試類進行測試

  SpringBootTest的classes是springboot項目啓動的運行類,也就是帶有@SpringBootApplication的類。測試

package daoTest; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import cn.qlq.MySpringBootApplication; import cn.qlq.bean.User; import cn.qlq.mapper.UserMapper; @RunWith(SpringRunner.class) @SpringBootTest(classes = MySpringBootApplication.class) public class PlainTest { @Autowired private UserMapper userMapper; @Test public void findAll() { List<User> findAll = userMapper.findAll(); System.out.println(findAll); } }

 

==============Springboot的AOP整合=============

  springboot整合Aop很是簡單,只用引入AOP模塊的依賴便可。而後就可使用註解AOP。

<!-- 引入 spring aop 依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

 

1.AOP的第一種切入方式:基於切點表達式進行攔截

  以下記錄servcice層的全部方法的執行時間的AOP寫法

package cn.qlq.aspect; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * 記錄service層執行時間的AOP切面 * * @author QiaoLiQiang * @time 2019年2月21日下午9:20:15 */ @Aspect @Component public class LogServiceTakeTime { private final static Logger log = LoggerFactory.getLogger(LogServiceTakeTime.class); @Pointcut("execution(* cn.qlq.service..*.*(..))") public void performance() { } /** * 環繞通知記錄時間 * * @param joinPoint * @return * @throws Throwable */ @Around("performance()") public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable { // 記錄起始時間
        long begin = System.currentTimeMillis(); Object result = ""; /** 執行目標方法 */
        try { result = joinPoint.proceed(); } catch (Exception e) { log.error("日誌記錄發生錯誤, errorMessage: {}", e.getMessage()); } finally { /** 記錄操做時間 */
            long took = (System.currentTimeMillis() - begin) / 1000; log.info("Service執行時間爲: {}秒", took); } return result; } /** * 前置通知 * * @param joinPoint * @throws Throwable */ @Before("performance()") public void doBefore(JoinPoint joinPoint) throws Throwable { // 接收到請求,記錄請求內容
        log.info("doBefore"); } }

 

2.第二種切入方式:基於註解

(1)編寫註解

package cn.qlq.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 自定義註解 * * @author QiaoLiQiang * @time 2019年2月21日下午9:45:17 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyLogAnnotation { String operateDescription();// 記錄日誌的操做類型,不寫默認值就是一個必須填的註解
}

 

(2)編寫切面進行攔截:通常在環繞通知中處理足夠了

package cn.qlq.aspect; import java.lang.reflect.Method; import java.sql.SQLException; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import cn.qlq.annotation.MyLogAnnotation; /** * @Author: qlq * @Description 日誌記錄切面(攔截自定義註解進行日誌記錄) * @Date: 11:46 2018/5/14 */ @Component @Aspect public class MyLogAspect { private final static Logger log = LoggerFactory.getLogger(MyLogAspect.class); /** * 環繞通知處理 * * @param pjp * @return * @throws Throwable */ @Around("@annotation(cn.qlq.annotation.MyLogAnnotation)") public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable { // 1.方法執行前的處理,至關於前置通知 // 獲取方法簽名
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature(); // 獲取方法
        Method method = methodSignature.getMethod(); // 獲取方法上面的註解
        MyLogAnnotation logAnno = method.getAnnotation(MyLogAnnotation.class); // 獲取到類名
        String targetName = pjp.getTarget().getClass().getName(); // 獲取到方法名字
        String methodName = method.getName(); // 獲取操做描述的屬性值
        String operateDescription = logAnno.operateDescription(); Object result = null; try { // 讓代理方法執行
            result = pjp.proceed(); // 2.至關於後置通知(方法成功執行以後走這裏)
        } catch (SQLException e) { // 3.至關於異常通知部分
        } finally { // 4.至關於最終通知
            log.info("class->{},methodName->{},operateDescription->{}", targetName, methodName, operateDescription); } return result; } }

(3)測試:

 

結果:

 

   關於AOP在以前也研究過了,在這裏就只研究其使用,具體的使用方法參考:https://www.cnblogs.com/qlqwjy/p/8729280.html                               https://www.cnblogs.com/qlqwjy/p/8747476.html

相關文章
相關標籤/搜索