Spring Boot概述
Spring Boot是一个开源的开发框架,旨在简化基于Spring的应用开发,其特性有:
- 自动配置:根据项目中的依赖自动配置 Spring 应用。
- 启动器依赖(Starter Dependencies):简化 Maven 或 Gradle 配置,只需引入适当的启动器即可。
- 内嵌服务器:内置了 Tomcat、Jetty 等服务器,支持将应用打包为可执行的 JAR 文件。
- 生产准备特性:如监控、指标、健康检查等,方便应用的部署和维护。
核心模块与组件
-
Spring MVC
用于构建基于MVC模式的Web应用。包括控制器,视图解析,数据绑定等功能
-
Spring Data JPA
用于简化数据访问层的开发,提供了一套基于JPA的数据访问抽象
-
Spring Security
用于集成安全认证与授权机制,保护Web应用免受未授权访问
-
Spring Boot Actuator
提供生产监控和管理功能,包括健康检查、指标收集、审计事件等。
-
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开发流程
-
添加依赖项
-
创建实体类:定义与数据库表对应的实体类
@Entity public class User{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; }
-
创建仓库接口:使用Spring Data JPA提供的数据访问接口
public interface UserRepository extends JpaRepoitory
{ User findByEmail(String email); // More Api } -
创建服务类:编写业务逻辑
@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); } } -
创建控制器:处理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)); } } -
启动
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风格的控制器
- 类注解
@RestController
@RequestMapping("/users")
@RestController
:组合注解,等同于@Controller
+@ResponseBody
- 表示这是一个RESTful风格的控制器
- 所有方法的返回值直接写入HTTP响应体
@RequestMapping("/users")
:定义基础访问路径- 所有方法的访问路径都会基于"/users"
- 依赖注入
@Autowired
private UserService userService;
- 使用
@Autowired
进行依赖注入 - 自动注入
UserService
实例 - 用于调用业务逻辑层的方法
- 获取所有用户
@GetMapping
public List<User> getAllUsers() {
return userService.list();
}
- HTTP方法:GET
- 访问路径:/users
- 调用
userService.list()
获取所有用户 - 返回用户列表
- 根据ID获取用户
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getById(id);
}
- HTTP方法:GET
- 访问路径:/users/{id}
@PathVariable
:从URL路径中获取参数- 根据ID查询单个用户
- 创建新用户
@PostMapping
public boolean createUser(@RequestBody User user) {
return userService.save(user);
}
- HTTP方法:POST
- 访问路径:/users
@RequestBody
:将请求体映射为User对象- 调用
userService.save()
保存用户 - 返回操作是否成功
- 更新用户
@PutMapping
public boolean updateUser(@RequestBody User user) {
return userService.updateById(user);
}
- HTTP方法:PUT
- 访问路径:/users
- 更新用户信息
- 根据ID更新用户全部信息
- 删除用户
@DeleteMapping("/{id}")
public boolean deleteUser(@PathVariable Long id) {
return userService.removeById(id);
}
- HTTP方法:DELETE
- 访问路径:/users/{id}
- 根据ID删除用户