• Spring 框架两大核心 和 日志配置文件 2022-8-5


    IOC & DI

    IOC:Inversion of Control 控制反转  (发现这个类 创建这个对象)

    DI:Dependency Injection 依赖注入 (为空指针注入对象)

    先有控制反转 ,再有依赖注入  

    不可缺一

    IOC 控制反转的操作:发现和注册的过程 

    发现:让 IOC 容器发现组件类

            1.组件类的包层级不能高于启动类,只能小于等于

            2.组件类上需要有 IOC 注解

    发现后就会触发注册

    注册:创建对象放到 IOC 容器

    DI 依赖注入的操作:赋值的过程

    注入:在运行时,从IOC容器中找到与指针相匹配的对象赋值给指针的过程

    发现 --> 注册 --> 注入  (运行时发生的) 

    什么控制权?

    创建对象的控制权 new 构造方法()

    为什么要反转?

    高内聚低耦合

    耦合=依赖(工程依赖工程,类依赖类)

     

    Component  组件(组成工程的元件,指的是类)

    Bean/JavaBean 咖啡豆/组成 (指的对象/被IOC容器发现后创建的对象)

    IOC的实现方式有几种

    发现 - 注册 - 注入

            1.基于 xml 文件实现(已经淘汰)

                    xml 文件写在 resources 目录中,xml 文件可以又多个

            2.基于注解实现

            3.基于配置类实现

                    启动类或者任意一个带有@Configuration 注解的类都可以是一个配置类

    发现 / 注册 UserController

    发现 / 注册 UserServiceImpl

    在 UserController 中注入 UserServiceImpl

    具有 IOC 功能的注解有哪一些

            1.@Controller / @RestController

                    (1)用于控制器层类的发现和注册

            2.@Service

                    (1)用于 Service 层类的发现和注册

            3.@Repository(如果用来 MyBatis 框架就不会用到这个注解)

                    (1)用于 Dao 层类的发现和注册

            4.@Component

                    (1)用于任意一个普通类的发现和注册

            5.@MapperScan

                    (1)用于扫描 mapper 包,在运行时创建接口的实现类,并注册对象到 IOC 容器

    日志管理

            1.安装 Lombok 三方库

            2.日志配置文件log.xml

            3.设置日志配置文件位置

            4.需要打印日志的类中使用 @Slf4j 注解

    Lombok 三方库提供的注解

            @Setter        

            @Getter

            @AllArgsConstructor

            @NoArgsConstructor

            @EqualsAndHashCode

            @ToString 重写 toString 方法 

           @Data  = @Setter + @Getter + @EqualsAndHashCode + @ToString

            @Slf4j 

            4j = for java (为 Java 提供)

            在编译后的字节码文件中会出现一个私有的静态常量,常量是logger,指针名叫log,这个就是用来打印日志的对象,需要在哪个类中打印日志,只需有给这个类添加 @Slf4j 注解,这个类中就会有一个 log 指针

    private static final Logger log = LoggerFactory.getLogger(UserController.class)

    在使用 log 对象打印日志之前,需要先配置打印日志的规则

    1.将日志文件配置文件放在 resources 目录中

    2.在 application.properties 中告诉Lombok 框架日志配置文件在哪里

     

     

     

    日志配置文件 可以复用,需要了解里面如何配置日志打印规则

    1. <configuration scan="true" scanPeriod="10 seconds">
    2. <contextName>logbackcontextName>
    3. <property name="log.path" value="logs" />
    4. <property name="log.maxHistory" value="30" />
    5. <property name="log.maxFileSize" value="100MB" />
    6. <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    7. <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    8. <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    9. <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
    10. <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    11. <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
    12. <level>infolevel>
    13. filter>
    14. <encoder>
    15. <Pattern>${CONSOLE_LOG_PATTERN}Pattern>
    16. <charset>UTF-8charset>
    17. encoder>
    18. appender>
    19. <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    20. <encoder>
    21. <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
    22. <charset>UTF-8charset>
    23. encoder>
    24. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    25. <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.logfileNamePattern>
    26. <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
    27. <maxFileSize>${log.maxFileSize}maxFileSize>
    28. timeBasedFileNamingAndTriggeringPolicy>
    29. <maxHistory>${log.maxHistory}maxHistory>
    30. rollingPolicy>
    31. <filter class="ch.qos.logback.classic.filter.LevelFilter">
    32. <level>debuglevel>
    33. <onMatch>ACCEPTonMatch>
    34. <onMismatch>DENYonMismatch>
    35. filter>
    36. appender>
    37. <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    38. <encoder>
    39. <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
    40. <charset>UTF-8charset>
    41. encoder>
    42. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    43. <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.logfileNamePattern>
    44. <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
    45. <maxFileSize>${log.maxFileSize}maxFileSize>
    46. timeBasedFileNamingAndTriggeringPolicy>
    47. <maxHistory>${log.maxHistory}maxHistory>
    48. rollingPolicy>
    49. <filter class="ch.qos.logback.classic.filter.LevelFilter">
    50. <level>infolevel>
    51. <onMatch>ACCEPTonMatch>
    52. <onMismatch>DENYonMismatch>
    53. filter>
    54. appender>
    55. <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    56. <encoder>
    57. <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
    58. <charset>UTF-8charset>
    59. encoder>
    60. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    61. <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.logfileNamePattern>
    62. <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
    63. <maxFileSize>${log.maxFileSize}maxFileSize>
    64. timeBasedFileNamingAndTriggeringPolicy>
    65. <maxHistory>${log.maxHistory}maxHistory>
    66. rollingPolicy>
    67. <filter class="ch.qos.logback.classic.filter.LevelFilter">
    68. <level>warnlevel>
    69. <onMatch>ACCEPTonMatch>
    70. <onMismatch>DENYonMismatch>
    71. filter>
    72. appender>
    73. <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    74. <encoder>
    75. <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
    76. <charset>UTF-8charset>
    77. encoder>
    78. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    79. <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.logfileNamePattern>
    80. <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
    81. <maxFileSize>${log.maxFileSize}maxFileSize>
    82. timeBasedFileNamingAndTriggeringPolicy>
    83. <maxHistory>${log.maxHistory}maxHistory>
    84. rollingPolicy>
    85. <filter class="ch.qos.logback.classic.filter.LevelFilter">
    86. <level>ERRORlevel>
    87. <onMatch>ACCEPTonMatch>
    88. <onMismatch>DENYonMismatch>
    89. filter>
    90. appender>
    91. <springProfile name="dev">
    92. <logger name="com.nmys.view" level="debug"/>
    93. springProfile>
    94. <root level="info">
    95. <appender-ref ref="CONSOLE" />
    96. <appender-ref ref="DEBUG_FILE" />
    97. <appender-ref ref="INFO_FILE" />
    98. <appender-ref ref="WARN_FILE" />
    99. <appender-ref ref="ERROR_FILE" />
    100. root>
    101. configuration>

    日志级别

    trace(追踪) < debug(调试) < info(信息) < warn(警告) < error(错误)

    使用 log 打印 日志来替代 System.out.println()

    写 Demo

            System.out.println()

    写项目

            使用 log 打印

    1.log 打印的信息更多

            日志打印时间   所在线程  所在类  日志信息

    2.log 可以按级别打印日志,可以通过级别控制哪些打印,哪些不打印

    3.log 可以打印到控制台,还可以打印到文件

    ·

    AOP

    面向切面编程 Aspect Oriented Programming

    try.catch() finally{} 非业务代码

    log.debug("") 侵入式的代码

    aop 编程的依赖

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-aopartifactId>
    4. dependency>

     

    1. package com.iweb.springbootshop.aop;
    2. import lombok.extern.slf4j.Slf4j;
    3. import org.aspectj.lang.JoinPoint;
    4. import org.aspectj.lang.annotation.*;
    5. import org.springframework.stereotype.Component;
    6. import java.util.Arrays;
    7. /**
    8. * AOP 增强类 - execution(* com.iweb.springbootshop.controller.*.*(..))
    9. * 任意返回值类型 com.iweb.springbootshop.controller.任意类.任意方法(任意参数列表)
    10. * 1. @Before - 前置增强:在目标方法执行之前增强
    11. * 2. @After - 后置增强:在目标方法执行之后增强
    12. * 3. @AfterReturning - 返回增强:在目标方法返回之后增强
    13. * 4. @AfterThrowing - 异常增强:在目标方法抛出异常时增强
    14. * 任意一个目标方法执行之前,先执行before
    15. * 任意一个目标方法执行之后,执行after
    16. * 任意一个目标方法返回之后,执行afterReturning
    17. * 任意一个目标方法抛出异常,执行afterThrowing
    18. */
    19. @Slf4j
    20. @Component
    21. @Aspect
    22. public class ControllerAdvice {
    23. @Pointcut("execution(* com.iweb.springbootshop.controller.*.*(..))")
    24. public void pointcut(){}
    25. @Before(value = "pointcut()")
    26. public void before(JoinPoint jp){
    27. String targetMethodName = jp.getSignature().getName();
    28. Object[] args = jp.getArgs();
    29. log.info(targetMethodName + "开始执行,参数列表" + Arrays.toString(args));
    30. }
    31. @After(value = "pointcut()")
    32. public void after(JoinPoint jp){
    33. String targetMethodName = jp.getSignature().getName();
    34. log.info(targetMethodName + "执行结束");
    35. }
    36. @AfterReturning(value = "pointcut()",returning = "result")
    37. public void afterReturning(JoinPoint jp , Object result){
    38. String targetMethodName = jp.getSignature().getName();
    39. log.info(targetMethodName + "正常执行结束,有返回值:" +result);
    40. }
    41. @AfterThrowing(value = "pointcut()",throwing = "e")
    42. public void afterThrowing(JoinPoint jp , Exception e){
    43. String targetMethodName = jp.getSignature().getName();
    44. log.info(targetMethodName + "执行结束,发生异常:" +e.getMessage());
    45. }
    46. }

     

     

     当发生异常的时候

    1. @Around(value = "pointcut()")
    2. public Object around(ProceedingJoinPoint p ){
    3. String targetMethodName = p.getSignature().getName();
    4. try {
    5. Object[] args = p.getArgs();
    6. log.info(targetMethodName + "开始执行,参数列表" + Arrays.toString(args));
    7. //让目标方法执行(甚至可以决定目标方法执行或不执行)
    8. Object result = p.proceed();
    9. log.info(targetMethodName + "执行结束,有返回值"+ result);
    10. return result;
    11. } catch (Throwable e) {
    12. e.printStackTrace();
    13. log.info(targetMethodName + "执行结束,发生了异常" + e.getMessage());
    14. return null;
    15. } finally {
    16. log.info(targetMethodName + "执行结束");
    17. }
    18. }

  • 相关阅读:
    集合_HashSet(HashMap)扩容机制源码简析
    智能工单系统(IT运维工单系统),为企业IT运维跨部门协作量身定制!
    【Git】Git基础命令操作速记
    Web开发之HTML知识点总结
    uniapp&小程序打开地图导航
    Python_WebSocket服务器和Python_JavaScript客户端
    SpringBoot - SpringBoot整合Flyway实现数据库的迁移
    vue pc端/手机移动端 — 下载导出当前表格页面pdf格式
    如何使用 MySQL 做全文检索这件事
    C++学习笔记(Ⅰ):C++基础入门
  • 原文地址:https://blog.csdn.net/ZSDLZ37/article/details/126170360