SpringBoot学习

Spring Boot概述

Spring Boot是一个开源的开发框架,旨在简化基于Spring的应用开发,其特性有:

  1. 自动配置:根据项目中的依赖自动配置 Spring 应用。
  2. 启动器依赖(Starter Dependencies):简化 Maven 或 Gradle 配置,只需引入适当的启动器即可。
  3. 内嵌服务器:内置了 Tomcat、Jetty 等服务器,支持将应用打包为可执行的 JAR 文件。
  4. 生产准备特性:如监控、指标、健康检查等,方便应用的部署和维护。

核心模块与组件

  1. Spring MVC

    用于构建基于MVC模式的Web应用。包括控制器,视图解析,数据绑定等功能

  2. Spring Data JPA

    用于简化数据访问层的开发,提供了一套基于JPA的数据访问抽象

  3. Spring Security

    用于集成安全认证与授权机制,保护Web应用免受未授权访问

  4. Spring Boot Actuator

    提供生产监控和管理功能,包括健康检查、指标收集、审计事件等。

  5. Spring Boot DevTools

注解

Spring Boot中,注解是非常重要的组成部分,用于简化配置,定义组件以及处理各种功能。

@Autowired

@Autowired是Spring框架提供的一个依赖注入的注解,用于自动装配Bean(组件)

作用:自动将Spring容器中匹配的Bean注入到当前类的字段,构造方法或setter方法中,减少了手动配置和耦合

字段注入:直接在字段上使用@Autowired,Spring会自动为该字段注入相应的Bean

@Autowired
private UserService userService;

构造方法注入:推荐使用构造方法注入,因为它可以使 Bean 更加不可变,并且更容易进行单元测试

private final UserService userService;
@Autowired
public UserController(UserService userService){
    this.userService = userService;
}

Setter 方法注入

private UserService userService;

@Autowired
public void setUserService(UserService userService) {
    this.userService = userService;
}

@RestController

@RestController是Spring MVC提供的一个复合注解,结合了@Controller和@ResponseBody功能,用于定义RESTful Web服务的控制器

作用:标注的类会被Spring识别为控制器,并且所有的方法返回的对象会自动序列化为JSON并写入HTTP响应体,无需在每个方法上使用使用@RestController

@RestController
@RequestMapping("/users")
public class UserController {
    // 控制器方法
}

@RequestMapping

@RequestMapping是Spring MVC中用于映射HTTP请求到处理方法或类级别的注解

作用:定义URL路径,HTTP方法,请求参数等信息。指定哪些请求应该由哪个控制器或方法处理

// 类级别
@RestController
@RequstMapping("/users")
public class UserController{

}
@Getmapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
    // 方法实现
}

@GetMapping & @PostMapping

@GetMapping@PostMapping@RequestMapping的快捷注解,分别用于处理HTTP的GET和POST请求

作用:简化了代码,使得映射特定HTTP方法的请求更加直观和简洁

  • @GetMapping

    @GetMapping("/{id}")
    public ResponseEntity getUser(@PathVariable Long id) {
      // 获取用户逻辑
    }

    处理 GET 请求,例如获取资源。

  • @PostMapping

    @PostMapping
    public ResponseEntity createUser(@RequestBody User user) {
      // 创建用户逻辑
    }

    处理 POST 请求,例如创建资源。

    其他类似注解:

  • @PutMapping:处理 PUT 请求,用于更新资源。

  • @DeleteMapping:处理 DELETE 请求,用于删除资源。

  • @PatchMapping:处理 PATCH 请求,用于部分更新资源。

@PathVariable

@PathVariable注解用于将URL中的动态部分绑定到方法参数上

作用:提取URL中的变量部分,并将其作为方法参数传递

@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id){

}

{id}会被提取并赋值给ID参数

指定变量名称给ID

@GetMapping("/{userId}")
public ResponseEntity<User> getUser(@PathVariable("userId") Long id){

}

@RequestBody

@RequestBody注解用于将HTTP请求体中的内容绑定到方法参数上,通常用于处理JSON,XML等格式的数据

作用:将请求体中的 JSON(或其他格式)反序列化为 Java 对象

@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
    // 创建用户逻辑
}

上述代码中,HTTP POST 请求的 JSON 数据会被反序列化为 User 对象,并传递给 createUser 方法。

@Entity

@Entity 是 JPA(Java Persistence API)提供的注解,用于标识一个类作为实体类,与数据库中的表对应。

将 Java 类映射到数据库表,定义实体类的属性与表的列之间的关系。

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
    // getters and setters
}
  • @Id:标识主键字段。

  • @GeneratedValue:指定主键生成策略,如自动增长。

  • @Table:指定表名,如果不使用默认表名(类名)。

  • @Column:指定列名及其他属性,如果不使用默认列名(字段名)。

@Service

@Service 是 Spring 提供的一个标识注解,用于标识服务层的组件

将类标识为 Spring 容器中的一个服务 Bean,通常用于封装业务逻辑。

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public User saveUser(User user) {
        return userRepository.save(user);
    }

    public Optional<User> getUserById(Long id) {
        return userRepository.findById(id);
    }

    // 更多业务方法
}
  • @Component:通用的组件标识注解。
  • @Repository:标识数据访问层组件,通常用于 DAO 类。

@Repository

@Repository 是 Spring 提供的用于标识数据访问层组件的注解。

将接口或类标识为数据访问层的 Bean,特别是与数据库交互的组件。它还具有异常转换的功能,将持久层的异常转换为 Spring 的数据访问异常。

public interface UserRepository extends JpaRepository<User, Long> {
    User findByEmail(String email);
}

Spring Data JPA 自动为接口生成实现类,无需显式使用 @Repository,但有时为了明确性,也可以添加:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    User findByEmail(String email);
}

注解的底层机制

1. 元注解(Meta-Annotations)

许多注解本身也是由其他注解构成的,例如 @RestController 就是由 @Controller@ResponseBody 组合而成的。

2. 处理机制

Spring 通过反射和 AOP(面向切面编程)机制,在运行时扫描和处理这些注解,执行相应的逻辑。

3. 注解驱动配置

Spring 注解是 Spring 应用中配置的主要方式,取代了传统的基于 XML 的配置方法,使得配置更加简洁和直观。

Spring Boot开发流程

  1. 添加依赖项

  2. 创建实体类:定义与数据库表对应的实体类

    @Entity
    public class User{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
       private Long id;
       private String name;
       private String email;
    }
  3. 创建仓库接口:使用Spring Data JPA提供的数据访问接口

    public interface UserRepository extends JpaRepoitory
    {
       User findByEmail(String email);
       // More Api
    }
  4. 创建服务类:编写业务逻辑

    @Service
    public class UserService{
       @Autowired
       private UserRepository userRepository;
    
       public User saveUser(User user){
           return userRepository.save(user);
       }
       public Optional getUserById(Long id) {
           return userRepository.findById(id);
       }
    }
  5. 创建控制器:处理HTTP请求

    @RestController
    @RequestMapping("/users")
    public class UserController{
       @Autowired
       private UserService userService;
    
       @PostMapping
       public ResponseEntity createUser(@RequestBody User user)
       {
           User savedUser = userService.saveUser(user);
           return new ResponseEntity<>(saveUser,HttpStatus.CREATED);
       }
       @GetMapping("/{id}")
       public ResponseEntity getUser(@PathVariable Long id) {
           Optional user = userService.getUserById(id);
           return user.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
                      .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
       }
    }
  6. 启动

Lombok

@Data生成的getter/setter/toString方法

Getter方法:

public Long getId() {
    return this.id;
}

public String getName() {
    return this.name;
}

public Integer getAge() {
    return this.age;
}

public String getEmail() {
    return this.email;
}

Setter方法:

public void setId(Long id) {
    this.id = id;
}

public void setName(String name) {
    this.name = name;
}

public void setAge(Integer age) {
    this.age = age;
}

public void setEmail(String email) {
    this.email = email;
}

toString方法:

@Override
public String toString() {
    return "User(id=" + this.getId() + 
           ", name=" + this.getName() + 
           ", age=" + this.getAge() + 
           ", email=" + this.getEmail() + ")";
}

equals方法:

@Override
public boolean equals(Object o) {
    if (o == this) return true;
    if (!(o instanceof User)) return false;
    User other = (User) o;
    return Objects.equals(this.id, other.id) &&
           Objects.equals(this.name, other.name) &&
           Objects.equals(this.age, other.age) &&
           Objects.equals(this.email, other.email);
}

hashCode方法:

@Override
public int hashCode() {
    return Objects.hash(id, name, age, email);
}

Demo

Demo概述

该demo使用了MVC模式,包含了MyBatis-Plus的实体,用于数据库表映射的实体Entity User,模型层Service,控制层Controller,交互层Mapper

1.User

在导入注解:标记主键的@TableId,指定数据库表名的@TableName,主建生成策略,@Data表示Lombok注解,用于自动生成getter/setter/toString等方法

类注解

@Data   // 自动生成方法
@TableName("user")    // 对应数据库的user表
public class User{
}

主键配置

    @TableId(value = "id" , type = IdType.AUTO)
    private Long id;

value = "id":对应数据库表的id列

type = IdType.AUTO:主键自增策略

普通字段

private String name;   // 姓名
private Integer age;   // 年龄
private String email;  // 邮箱
  • 字段名与数据库表列名默认对应

2.Mapper

这是一个使用MyBatis-Plus框架定义的Mapper接口,使用MyBatis-Plus提供的基础映射器接口BaseMapper,User是对应的实体类

@Mapper表示是MyBatis注解,标记为数据访问接口

接口定义

@Mapper
public interface UserMapper extends BaseMapper<User>{

}

通过继承BaseMapper\<User>,自动获得以下基础CURD方法:

// 插入操作
int insert(User entity);

// 根据ID删除
int deleteById(Serializable id);

// 根据ID更新
int updateById(User entity);

// 根据ID查询
User selectById(Serializable id);

// 查询所有
List<User> selectList(Wrapper<User> queryWrapper);

// 条件查询
List<User> selectList(QueryWrapper<User> queryWrapper);

// 分页查询
IPage<User> selectPage(IPage<User> page, Wrapper<User> queryWrapper);

Service – 处理数据库的业务

这是一个使用MyBatis-Plus框架定义的Service接口

import com.baomidou.mybatisplus.extension.service.IService;
public interface UserService extends IService<User>{

}

继承IService\<User>接口的丰富的通用服务方法:

// 插入操作
boolean save(User entity);

// 批量插入
boolean saveBatch(Collection<User> entityList);

// 根据ID更新
boolean updateById(User entity);

// 根据条件更新
boolean update(User entity, Wrapper<User> updateWrapper);

// 根据ID删除
boolean removeById(Serializable id);

// 根据条件删除
boolean remove(Wrapper<User> queryWrapper);

// 根据ID查询
User getById(Serializable id);

// 列表查询
List<User> list();

// 条件查询
List<User> list(Wrapper<User> queryWrapper);

// 分页查询
IPage<User> page(IPage<User> page);

实现类

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demodb.entity.User;
import com.example.demodb.mapper.UserMapper;
import com.example.demodb.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    // 可以添加自定义方法的实现

   @Override
    public User getUserByEmail(String email) {
        return this.lambdaQuery()
                .eq(User::getEmail, email)
                .one();
    }

    @Override
    public boolean registerUserWithRole(User user, String roleName) {
        // 可以实现复杂的业务逻辑
        // 比如注册用户并分配角色
        boolean saveResult = this.save(user);
        // 其他业务逻辑...
        return saveResult;
    }
}

Controller – 控制层

这是一个使用Spring Boot和MyBatis-Plus实现的RESTful风格的控制器

  1. 类注解
@RestController
@RequestMapping("/users")
  • @RestController:组合注解,等同于@Controller + @ResponseBody
    • 表示这是一个RESTful风格的控制器
    • 所有方法的返回值直接写入HTTP响应体
  • @RequestMapping("/users"):定义基础访问路径
    • 所有方法的访问路径都会基于"/users"
  1. 依赖注入
@Autowired
private UserService userService;
  • 使用@Autowired进行依赖注入
  • 自动注入UserService实例
  • 用于调用业务逻辑层的方法
  1. 获取所有用户
@GetMapping
public List<User> getAllUsers() {
    return userService.list();
}
  • HTTP方法:GET
  • 访问路径:/users
  • 调用userService.list()获取所有用户
  • 返回用户列表
  1. 根据ID获取用户
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
    return userService.getById(id);
}
  • HTTP方法:GET
  • 访问路径:/users/{id}
  • @PathVariable:从URL路径中获取参数
  • 根据ID查询单个用户
  1. 创建新用户
@PostMapping
public boolean createUser(@RequestBody User user) {
    return userService.save(user);
}
  • HTTP方法:POST
  • 访问路径:/users
  • @RequestBody:将请求体映射为User对象
  • 调用userService.save()保存用户
  • 返回操作是否成功
  1. 更新用户
@PutMapping
public boolean updateUser(@RequestBody User user) {
    return userService.updateById(user);
}
  • HTTP方法:PUT
  • 访问路径:/users
  • 更新用户信息
  • 根据ID更新用户全部信息
  1. 删除用户
@DeleteMapping("/{id}")
public boolean deleteUser(@PathVariable Long id) {
    return userService.removeById(id);
}
  • HTTP方法:DELETE
  • 访问路径:/users/{id}
  • 根据ID删除用户