IOC:Inversion of Control 控制反转 (发现这个类 创建这个对象)
DI:Dependency Injection 依赖注入 (为空指针注入对象)
先有控制反转 ,再有依赖注入
不可缺一
1.组件类的包层级不能高于启动类,只能小于等于
2.组件类上需要有 IOC 注解
发现 --> 注册 --> 注入 (运行时发生的)
创建对象的控制权 new 构造方法()
高内聚低耦合
耦合=依赖(工程依赖工程,类依赖类)

Component 组件(组成工程的元件,指的是类)
Bean/JavaBean 咖啡豆/组成 (指的对象/被IOC容器发现后创建的对象)
发现 - 注册 - 注入
1.基于 xml 文件实现(已经淘汰)
xml 文件写在 resources 目录中,xml 文件可以又多个
2.基于注解实现
3.基于配置类实现
启动类或者任意一个带有@Configuration 注解的类都可以是一个配置类
发现 / 注册 UserController
发现 / 注册 UserServiceImpl
在 UserController 中注入 UserServiceImpl
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 框架日志配置文件在哪里


日志配置文件 可以复用,需要了解里面如何配置日志打印规则
- <configuration scan="true" scanPeriod="10 seconds">
-
-
- <contextName>logbackcontextName>
-
- <property name="log.path" value="logs" />
-
- <property name="log.maxHistory" value="30" />
-
- <property name="log.maxFileSize" value="100MB" />
-
-
-
- <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
- <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
- <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
-
- <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}}"/>
-
-
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
-
- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
- <level>infolevel>
- filter>
- <encoder>
- <Pattern>${CONSOLE_LOG_PATTERN}Pattern>
-
- <charset>UTF-8charset>
- encoder>
- appender>
-
-
-
-
-
- <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-
- <encoder>
- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
- <charset>UTF-8charset>
- encoder>
-
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-
- <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.logfileNamePattern>
- <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
- <maxFileSize>${log.maxFileSize}maxFileSize>
- timeBasedFileNamingAndTriggeringPolicy>
-
- <maxHistory>${log.maxHistory}maxHistory>
- rollingPolicy>
-
- <filter class="ch.qos.logback.classic.filter.LevelFilter">
- <level>debuglevel>
- <onMatch>ACCEPTonMatch>
- <onMismatch>DENYonMismatch>
- filter>
- appender>
-
-
- <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-
- <encoder>
- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
- <charset>UTF-8charset>
- encoder>
-
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-
- <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.logfileNamePattern>
- <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
- <maxFileSize>${log.maxFileSize}maxFileSize>
- timeBasedFileNamingAndTriggeringPolicy>
-
- <maxHistory>${log.maxHistory}maxHistory>
- rollingPolicy>
-
- <filter class="ch.qos.logback.classic.filter.LevelFilter">
- <level>infolevel>
- <onMatch>ACCEPTonMatch>
- <onMismatch>DENYonMismatch>
- filter>
- appender>
-
-
- <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-
- <encoder>
- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
- <charset>UTF-8charset>
- encoder>
-
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.logfileNamePattern>
- <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
- <maxFileSize>${log.maxFileSize}maxFileSize>
- timeBasedFileNamingAndTriggeringPolicy>
-
- <maxHistory>${log.maxHistory}maxHistory>
- rollingPolicy>
-
- <filter class="ch.qos.logback.classic.filter.LevelFilter">
- <level>warnlevel>
- <onMatch>ACCEPTonMatch>
- <onMismatch>DENYonMismatch>
- filter>
- appender>
-
-
- <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-
- <encoder>
- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
- <charset>UTF-8charset>
- encoder>
-
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.logfileNamePattern>
- <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
- <maxFileSize>${log.maxFileSize}maxFileSize>
- timeBasedFileNamingAndTriggeringPolicy>
-
- <maxHistory>${log.maxHistory}maxHistory>
- rollingPolicy>
-
- <filter class="ch.qos.logback.classic.filter.LevelFilter">
- <level>ERRORlevel>
- <onMatch>ACCEPTonMatch>
- <onMismatch>DENYonMismatch>
- filter>
- appender>
-
-
-
-
-
-
-
-
-
-
- <springProfile name="dev">
- <logger name="com.nmys.view" level="debug"/>
- springProfile>
-
- <root level="info">
- <appender-ref ref="CONSOLE" />
- <appender-ref ref="DEBUG_FILE" />
- <appender-ref ref="INFO_FILE" />
- <appender-ref ref="WARN_FILE" />
- <appender-ref ref="ERROR_FILE" />
- root>
-
- configuration>
trace(追踪) < debug(调试) < info(信息) < warn(警告) < error(错误)
使用 log 打印 日志来替代 System.out.println()
写 Demo
System.out.println()
写项目
使用 log 打印
1.log 打印的信息更多
日志打印时间 所在线程 所在类 日志信息
2.log 可以按级别打印日志,可以通过级别控制哪些打印,哪些不打印
3.log 可以打印到控制台,还可以打印到文件
·
aop 编程的依赖
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-aopartifactId>
- dependency>


- package com.iweb.springbootshop.aop;
-
-
- import lombok.extern.slf4j.Slf4j;
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.annotation.*;
- import org.springframework.stereotype.Component;
-
- import java.util.Arrays;
-
- /**
- * AOP 增强类 - execution(* com.iweb.springbootshop.controller.*.*(..))
- * 任意返回值类型 com.iweb.springbootshop.controller.任意类.任意方法(任意参数列表)
- * 1. @Before - 前置增强:在目标方法执行之前增强
- * 2. @After - 后置增强:在目标方法执行之后增强
- * 3. @AfterReturning - 返回增强:在目标方法返回之后增强
- * 4. @AfterThrowing - 异常增强:在目标方法抛出异常时增强
- * 任意一个目标方法执行之前,先执行before
- * 任意一个目标方法执行之后,执行after
- * 任意一个目标方法返回之后,执行afterReturning
- * 任意一个目标方法抛出异常,执行afterThrowing
- */
- @Slf4j
- @Component
- @Aspect
- public class ControllerAdvice {
-
- @Pointcut("execution(* com.iweb.springbootshop.controller.*.*(..))")
- public void pointcut(){}
-
-
- @Before(value = "pointcut()")
- public void before(JoinPoint jp){
- String targetMethodName = jp.getSignature().getName();
- Object[] args = jp.getArgs();
- log.info(targetMethodName + "开始执行,参数列表" + Arrays.toString(args));
- }
-
- @After(value = "pointcut()")
- public void after(JoinPoint jp){
- String targetMethodName = jp.getSignature().getName();
- log.info(targetMethodName + "执行结束");
- }
- @AfterReturning(value = "pointcut()",returning = "result")
- public void afterReturning(JoinPoint jp , Object result){
- String targetMethodName = jp.getSignature().getName();
- log.info(targetMethodName + "正常执行结束,有返回值:" +result);
- }
- @AfterThrowing(value = "pointcut()",throwing = "e")
- public void afterThrowing(JoinPoint jp , Exception e){
- String targetMethodName = jp.getSignature().getName();
- log.info(targetMethodName + "执行结束,发生异常:" +e.getMessage());
- }
- }



当发生异常的时候


- @Around(value = "pointcut()")
- public Object around(ProceedingJoinPoint p ){
- String targetMethodName = p.getSignature().getName();
- try {
- Object[] args = p.getArgs();
- log.info(targetMethodName + "开始执行,参数列表" + Arrays.toString(args));
- //让目标方法执行(甚至可以决定目标方法执行或不执行)
- Object result = p.proceed();
- log.info(targetMethodName + "执行结束,有返回值"+ result);
- return result;
- } catch (Throwable e) {
- e.printStackTrace();
- log.info(targetMethodName + "执行结束,发生了异常" + e.getMessage());
- return null;
- } finally {
- log.info(targetMethodName + "执行结束");
- }
- }