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

相关文章
相关标签/搜索