Problem

转换器都有什么功能

转换器(Converter) 的核心功能可以通俗理解为:比如把前端传的字符串转成后端需要的对象

1. 前端请求数据 → 后端参数:解决 “格式不匹配”

2. 后端内部数据转换:解决 “逻辑适配”

3. 后端响应数据 → 前端 / 存储:解决 “输出格式统一”

转换器的 2 个关键特性:自动触发,不用手动调用;支持自定义

web依赖有什么
  • Tomcat提供运行环境
  • DispatcherServlet负责请求分发(Spring MVC 的核心)
  • XML用于配置项目参数
mybatis配置具体含义

这是 Spring Boot 中 MyBatis 的核心配置,用于告诉 MyBatis 如何找到你的实体类(POJO)和 Mapper 映射文件(XML),简化开发时的代码编写。下面逐行拆解含义:

1. mybatis.type-aliases-package: com.guo.pojo

作用:指定「实体类(POJO)的包路径」,让 MyBatis 自动给实体类起「别名」

  • 背景:MyBatis 在 XML 映射文件(或注解)中使用实体类时,默认需要写「全类名」(如 com.guo.pojo.User),繁琐且易出错。
  • 配置后效果:MyBatis 会扫描 com.guo.pojo 包下的所有类,自动将「类名」作为「别名」(不区分大小写,推荐首字母小写)。

示例对比:

  • 未配置时(需写全类名):
<!-- XML 中查询返回 User 实体,需写全类名 -->
<select id="getUserById" resultType="com.guo.pojo.User">
  select * from user where id = #{id}
</select>
  • 配置后(可直接用别名):
<!-- 直接用类名 User 或 user 作为别名,简洁很多 -->
<select id="getUserById" resultType="User">
  select * from user where id = #{id}
</select>

注意:

  • 别名默认是「类名」(如 User → 别名 userUser,MyBatis 不区分大小写)。
  • 若包下有重名类(如 com.guo.pojo.Usercom.guo.pojo.admin.User),需手动通过 @Alias 注解指定唯一别名:
// 在 POJO 类上添加注解,指定别名
@Alias("userInfo")
public class User { ... }

2. mybatis.mapper-locations: classpath:mybatis/mapper/*.xml

作用:指定「MyBatis Mapper 映射文件(XML)的存放路径」,让 MyBatis 自动加载这些文件

核心概念:

    • classpath::表示从项目的「类路径」下查找(Maven 项目中,src/main/resources 目录就是类路径根目录)。
    • mybatis/mapper/*.xml:匹配「类路径下 mybatis/mapper 文件夹中所有 .xml 后缀的文件」。
  • 为什么需要:Mapper 映射文件是用来写 SQL 语句的(如查询、新增、修改),MyBatis 必须找到这些文件才能执行 SQL,否则会报「绑定失败」错误(如 BindingException: Invalid bound statement (not found))。

项目目录结构示例(需对应配置路径):

src/main/resources/  # 类路径根目录
└── mybatis/
    └── mapper/      # 映射文件存放目录
        ├── UserMapper.xml  # 符合 *.xml 匹配规则,会被加载
        ├── OrderMapper.xml # 同样会被加载
        └── other/
            └── GoodsMapper.xml # 不会被加载(路径不匹配)

补充:

  • 若映射文件放在 src/main/resources/mapper/*.xml,配置需改为 classpath:mapper/*.xml(路径要和实际存放位置一致)。
  • 若使用「纯注解开发」(不写 XML,直接在 Mapper 接口上用 @Select@Insert 等注解),可省略该配置;但如果是「XML + 接口」混合开发,必须配置该路径。
如何启动异步

①想办法告诉spring我们的异步方法是异步的,所以要在方法上添加注解

②去springboot主程序中开启异步注解功能(@EnableAsync)

异步任务,邮件任务,定时任务的学习重点是什么

任务类型

Spring Boot 中的定位

学习重点

异步任务

应用性能优化

@Async

, @EnableAsync

, 线程池配置

邮件任务

业务功能实现

spring-boot-starter-mail

, JavaMailSender

定时任务

系统调度管理

@Scheduled

, @EnableScheduling

, cron表达式

result类什么作用

Result<T> 这个类是一个通用的接口返回结果封装类,在后端开发中非常常见,尤其是在 RESTful API 中。它的核心作用是统一接口的返回格式,让前端能够更方便、更规范地处理后端响应。

核心作用

  1. 统一返回格式
    • 无论接口是成功还是失败,都会返回一个包含 codemsgdata 三个字段的 JSON 对象。
    • 这使得前端不需要针对不同的成功或失败情况编写不同的解析逻辑。
  1. 明确的状态标识
    • code 字段用于标识请求的状态。
    • 1 代表成功。
    • 0 或其他数字代表失败,不同的数字可以对应不同的错误类型。
    • 前端可以通过判断 code 的值来快速确定请求是否成功。
  1. 携带返回数据
    • 当请求成功时(code=1),data 字段会包含接口返回的具体业务数据。
    • 这个 data 字段的类型是泛型 <T>,这意味着它可以是任何类型的对象(比如一个用户信息对象、一个商品列表、一个数字等),使得这个 Result 类具有极高的灵活性和通用性。
  1. 提供错误信息
    • 当请求失败时(code!=1),msg 字段会包含人类可读的错误信息。
    • 这个信息可以直接展示给用户,或者用于开发者调试。

代码逐行解析

  • @Data: 这是 Lombok 注解,它会自动为这个类生成 gettersettertoString()equals()hashCode() 等方法,让代码更简洁。
  • public class Result<T> implements Serializable:
    • Result<T>: 声明这是一个泛型类,T 是一个类型占位符,可以在使用时指定具体的类型。
    • implements Serializable: 表示这个类的对象可以被序列化,这在某些场景下(如分布式系统、缓存)是必需的。
  • private Integer code;: 状态码。
  • private String msg;: 消息描述。
  • private T data;: 泛型数据。

静态工厂方法解析

这些静态方法是 Result 类的核心,它们提供了一种优雅的方式来创建 Result 对象。

  1. public static <T> Result<T> success():
    • 用于创建一个无数据返回的成功响应
    • 例如,一个删除操作,成功后不需要返回任何数据,只需要告知前端成功即可。
    • 它会创建一个 Result 对象,将 code 设置为 1
  1. public static <T> Result<T> success(T object):
    • 用于创建一个携带数据的成功响应
    • 这是最常用的方法。当查询或创建数据成功后,将获取到的数据对象作为参数传入。
    • 它会创建一个 Result 对象,将 code 设置为 1,并把传入的 object 赋值给 data 字段。
  1. public static <T> Result<T> error(String msg):
    • 用于创建一个失败响应
    • 当业务逻辑校验失败、数据库操作出错或发生其他异常时,可以调用此方法。
    • 它会创建一个 Result 对象,将 code 设置为 0,并把传入的错误信息 msg 赋值给 msg 字段。
    • 注意:这个方法的返回类型是 Result<T>,但它内部创建的是 new Result()。在 Java 中,这会被推断为 Result<Object>,然后向上转型为 Result<T>。这是一个小瑕疵,更严谨的写法应该是 new Result<T>()。不过在大多数情况下,由于类型擦除,这并不会导致问题。

在实际应用中的例子

假设你有一个用户控制器 UserController

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public Result<User> getUserById(@PathVariable Integer id) {
        User user = userService.getById(id);
        if (user != null) {
            // 查询成功,返回用户数据
            return Result.success(user);
        } else {
            // 查询失败,返回错误信息
            return Result.error("用户不存在");
        }
    }

    @PostMapping
    public Result<User> createUser(@RequestBody User user) {
        boolean success = userService.save(user);
        if (success) {
            // 创建成功,返回创建后的用户信息
            return Result.success(user);
        } else {
            // 创建失败
            return Result.error("创建用户失败");
        }
    }

    @DeleteMapping("/{id}")
    public Result<Void> deleteUser(@PathVariable Integer id) {
        boolean success = userService.removeById(id);
        if (success) {
            // 删除成功,无需返回数据
            return Result.success();
        } else {
            return Result.error("删除用户失败");
        }
    }
}

成功响应示例 (getUserById)

{
  "code": 1,
  "msg": null,
  "data": {
    "id": 1,
    "username": "张三",
    "email": "zhangsan@example.com"
  }
}

失败响应示例 (getUserById)

{
  "code": 0,
  "msg": "用户不存在",
  "data": null
}
@AutoFill作用是什么

它通常配合 AOP(面向切面编程)MyBatis 插件 实现,在数据新增(INSERT)或更新(UPDATE)时,自动给注解标记的字段赋值,无需手动 set。

一、核心使用场景

日常开发中,几乎所有实体类都有通用字段:

  • 新增时需填充:createTime(创建时间)、createBy(创建人 ID / 名称)
  • 更新时需填充:updateTime(更新时间)、updateBy(更新人 ID / 名称)

如果没有 @AutoFill,每次保存 / 修改数据都要手动写:

// 手动填充(重复且繁琐)
user.setCreateTime(new Date());
user.setCreateBy(getCurrentUserId());
user.setUpdateTime(new Date());
user.setUpdateBy(getCurrentUserId());
userMapper.insert(user);

@AutoFill 后,只需在字段上加注解,自动填充逻辑会通过切面 / 插件触发:

public class User {
    private Long id;
    private String username;

    // 新增时自动填充:创建时间
    @AutoFill(type = OperationType.INSERT)
    private Date createTime;

    // 新增/更新时都自动填充:更新时间
    @AutoFill(type = {OperationType.INSERT, OperationType.UPDATE})
    private Date updateTime;

    // 新增时自动填充:创建人
    @AutoFill(type = OperationType.INSERT)
    private String createBy;

    // 新增/更新时自动填充:更新人
    @AutoFill(type = {OperationType.INSERT, OperationType.UPDATE})
    private String updateBy;
}

// 业务代码无需手动 set,直接保存
userMapper.insert(user); // 切面/插件自动填充 createTime、updateTime、createBy、updateBy

二、实现原理(简化版)

@AutoFill 本身只是「标记」,真正的填充逻辑由配套组件实现,核心流程:

  1. 定义注解:指定该注解可用于字段(@Target(FIELD)),保留到运行时(@Retention(RUNTIME)),并添加 type 属性标记需要触发的操作(INSERT/UPDATE)。java运行
// 注解定义示例
@Target(FIELD) // 仅作用于字段
@Retention(RUNTIME) // 运行时可通过反射获取注解信息
public @interface AutoFill {
    // 触发填充的操作类型(新增/更新)
    OperationType[] type();
}

// 枚举:操作类型
public enum OperationType {
    INSERT, UPDATE
}
  1. 实现填充逻辑
    • 方式 1(AOP):拦截 @Service 层的保存 / 更新方法,通过反射获取实体类中带 @AutoFill 的字段,根据操作类型(INSERT/UPDATE)赋值。
    • 方式 2(MyBatis 插件):拦截 MyBatis 的 StatementHandler,在 SQL 执行前修改参数(实体类),填充注解字段。
  1. 触发填充:当执行新增 / 更新操作时,拦截器触发,根据注解的 type 属性判断是否需要填充,最终通过反射给字段设值(如 new Date()、当前登录用户 ID 等)
@Pointcut作用是什么

没有 @Pointcut,AOP 就不知道该对哪些代码生效;有了它,才能精准定位要增强的目标,再配合 @Before(前置)、@After(后置)等注解执行切面逻辑。

一、核心本质:定义「拦截规则」

@Pointcut 的核心是 表达式,通过表达式明确:

  • 拦截哪些类?(如 com.example.service 包下的所有类)
  • 拦截哪些方法?(如所有 save* 开头的保存方法、带 @AutoFill 注解的方法)
  • 拦截方法的什么特征?(如 public 修饰、参数类型为 XX、返回值为 XX)

它就像一个「过滤器」,只有符合表达式规则的方法执行时,才会触发后续的切面逻辑(比如之前聊的 @AutoFill 自动填充逻辑)。

二、常见使用场景(结合表达式)

1. 最常用:按「包 + 类 + 方法」匹配(execution 表达式)

这是最灵活的方式,通过 execution() 表达式精准匹配方法,语法格式:

execution(访问修饰符 返回值类型 包名.类名.方法名(参数类型) 异常类型)

示例(对应 @AutoFill 场景):

// 定义切入点:拦截 com.example.mapper 包下所有类的 insert*/update* 开头的方法
@Pointcut("execution(* com.example.mapper.*.insert*(..)) || execution(* com.example.mapper.*.update*(..))")
public void autoFillPointcut() {} // 方法体为空,仅作为切入点标识(方法名任意)

// 前置通知:切入点匹配成功后,执行自动填充逻辑
@Before("autoFillPointcut()")
public void doAutoFill(JoinPoint joinPoint) {
    // 这里就是之前聊的 @AutoFill 填充逻辑(反射给字段赋值)
    System.out.println("执行自动填充...");
}

关键表达式说明:

  • *:通配符(如 * 代表任意返回值类型、任意类、任意方法名)
  • com.example.mapper.*com.example.mapper 包下的所有类(不含子包用 *,含子包用 **
  • insert*(..)insert 开头的方法,(..) 代表任意参数(无参 / 有参都匹配)
  • ||:逻辑或(同时拦截 insert 和 update 开头的方法)

2. 按「注解」匹配(@annotation 表达式)

拦截所有带指定注解的方法(比如拦截带 @Log 注解的方法做日志记录):

// 定义切入点:所有带 @Log 注解的方法
@Pointcut("@annotation(com.example.annotation.Log)")
public void logPointcut() {}

// 后置通知:方法执行后记录日志
@AfterReturning("logPointcut()")
public void recordLog(JoinPoint joinPoint) {
    System.out.println("记录方法执行日志...");
}

3. 按「类注解」匹配(@within 表达式)

拦截所有带指定注解的类中的 所有方法(比如拦截 @Service 注解类的所有方法做事务控制):

// 定义切入点:所有 @Service 注解标注的类的方法
@Pointcut("@within(org.springframework.stereotype.Service)")
public void servicePointcut() {}

// 环绕通知:控制事务(简化示例)
@Around("servicePointcut()")
public Object doTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
    System.out.println("开启事务...");
    Object result = joinPoint.proceed(); // 执行目标方法
    System.out.println("提交事务...");
    return result;
}

三、关键细节

  1. 切入点方法的要求
    • 方法必须是 public(Spring AOP 要求)
    • 方法体必须为空(仅作为「切入点标识」,逻辑写在 @Before/@After 等通知中)
    • 方法名任意(建议见名知意,如 autoFillPointcutlogPointcut
  1. 切入点的复用:多个通知(@Before/@After)可以复用同一个 @Pointcut,避免重复写表达式:java运行
// 复用同一个切入点
@Before("autoFillPointcut()")
public void doBefore() {}

@After("autoFillPointcut()")
public void doAfter() {}
  1. 与之前的 @AutoFill 关联:之前聊的 @AutoFill 自动填充功能,核心就是通过 @Pointcut 定义切入点(拦截 mapper 的 insert/update 方法),再在 @Before 通知中通过反射读取 @AutoFill 注解,给字段赋值 ——@Pointcut@AutoFill 能生效的前提(定位要拦截的方法)
@RabbitListener 注解的核心作用

@RabbitListenerSpring AMQP 框架提供的消费者监听注解,核心作用是:

  1. 声明 “这个方法是 RabbitMQ 队列的消费者”:无需手动编写 channel.basicConsume 等底层代码,Spring 会自动帮你完成队列订阅、消息监听、消费回调的逻辑;
  2. 指定监听的队列:通过 queues 属性指定要监听的队列名称(支持多个队列,比如 queues = {QUEUE1, QUEUE2});
  3. 自动管理消费者生命周期:Spring 会自动创建消费者连接、处理消息接收后的线程调度,异常时还能配合 @RabbitHandler、重试机制等做更灵活的处理;
  4. 支持高级特性:比如指定消费组、消息转换器、异常处理器、手动确认消息(配合 ackMode 属性)等。
  • Application程序本身就是个组件
  • springboot依赖都是spring-boot-stater开头
  • 最开始通过new对象创建对象,给对象赋值;学了spring就@component通过@value来赋值;再学springboot就通过Application.yaml来赋值,需要@ConfigurationProperties(prefix = "")来绑定对象
  • xxxxAutoConfigurartion:自动配置类,绑定xxx类;给容器中添加组件,xxxxProperties:封装配置文件中相关属性
  • 可以通过debug=true来判断哪些自动配置类生效了
  • templates目录下的所有页面,只能通过controller来跳转
  • xxxconfiguration是来扩展springmvc,比如视图解析,视图跳转功能
  • Spring 会自动扫描 com.shuxuejia.managementsystem 包下的所有类,以及子包(默认扫包)
  • 自定义了国际化资源文件,因此我们需要在SpringBoot配置文件application.properties中加入以下配置指定我们配置文件的名称
spring.messages.basename=i18n.login
  • Spring Boot 不仅提供了默认的数据源,同时默认已经配置好了 JdbcTemplate 放在了容器中,程序员只需自己注入即可使用
  • springboot所有配置类都有一个自动配置类,xxxAutoconfiguration;自动配置类都会绑定一个properties配置文件

ConfigurableApplicationContext

  • 组件扫描:从 MainApplication.class 所在的包开始,递归扫描所有带有 @Component 及其派生注解(@Controller@Service@Repository 等)的类,将它们创建为 “Bean” 并注册到容器中
  • 自动配置:根据引入的依赖(如 spring-boot-starter-webspring-boot-starter-data-jpa),自动加载对应的 “自动配置类”(如 WebMvcAutoConfiguration 配置 Spring MVC、DataSourceAutoConfiguration 配置数据库连接池),无需手动编写 XML 或 Java 配置
  • Bean 的依赖注入:容器会解析 Bean 之间的依赖关系(如 @Autowired 标注的属性或构造方法),自动将依赖的 Bean 注入到目标对象中(例如将 UserService 注入到 UserController
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐