d
一、介绍:
Spring Boot 是一个开源的Java-based 微服务框架,旨在简化Spring应用的创建和部署过程。它由Pivotal团队开发,首次发布于2014年。Spring Boot继承并扩展了Spring框架,简化了配置和部署过程,提供了大量的自动配置,使得开发者能够更快地构建和启动Spring应用程序。
二、优点
- 快速开发:Spring Boot 能够迅速搭建和启动Spring应用程序,减少了配置时间。
- 内嵌容器:支持内嵌Tomcat、Jetty或Undertow,简化了Web应用部署。
- 自动配置:根据添加的依赖自动配置Spring框架,简化了配置文件。
- 无代码生成和XML配置:不需要XML配置文件,尽可能地利用约定大于配置的原则。
- 提供生产就绪特性:如指标、健康检查和外部化配置。
- 微服务支持:易于创建独立的、生产级别的Spring应用。
三、缺点
- 学习曲线:对于初学者来说,Spring Boot的某些概念(如自动配置和Java配置)可能难以理解。
- 调试难度:自动配置简化了开发,但在出现问题时可能难以调试。
- 依赖版本控制:Spring Boot项目依赖于父项目来管理依赖版本,这可能导致版本升级时的问题。
四、用途
- Web应用程序开发:快速创建RESTful Web服务或动态Web应用程序。
- 微服务架构:作为微服务架构的基础框架。
- 企业应用集成:简化企业应用开发,提供数据访问、消息传递、事务管理等企业级特性。
- 云应用开发:与云平台(如Pivotal Cloud Foundry、AWS等)集成,支持云原生应用开发。
五、主要的组件和功能
-
Spring Boot Starters:Starters 是一系列的依赖描述符,它们能够简化项目依赖的管理。每个 Starter 都旨在为特定类型的应用提供所需的依赖。例如,
spring-boot-starter-web
为 Web 应用程序提供了 Spring MVC 和嵌入式 Tomcat 容器。 -
自动配置:Spring Boot 尝试根据添加的 jar 依赖自动配置 Spring 应用。例如,如果数据库的 JDBC 驱动在类路径中,Spring Boot 会自动配置一个数据库连接池。
-
嵌入式服务器:Spring Boot 支持内嵌的服务器,如 Tomcat、Jetty 和 Undertow,这使得开发者可以快速启动和测试 Web 应用程序,而不需要部署到一个外部服务器。
-
生产就绪特性:包括指标(如 Actuator)、健康检查和外部化配置,这些特性可以帮助开发者监控和管理生产环境中的应用。
-
命令行界面(CLI):Spring Boot CLI(Command Line Interface)是一个命令行工具,它可以用来快速开发 Spring 应用程序。它允许开发者立即启动和测试 Spring 应用,无需构建工具。
-
Actuator:Actuator 是 Spring Boot 的一个模块,用于监控和管理生产环境中的应用。它提供了许多生产就绪的特性,如健康检查、审计、指标收集和HTTP跟踪等。
-
安全性:Spring Boot 提供了安全方面的支持,通过添加
spring-boot-starter-security
依赖,可以快速集成 Spring Security 来保护应用程序。 -
数据访问:Spring Boot 支持 Spring Data,为 JPA、MongoDB、Redis 等数据存储提供支持。它还提供了对 SQL 数据库的自动配置,包括数据源配置和事务管理。
-
消息传递:Spring Boot 支持 Spring Messaging,可以集成 RabbitMQ、Kafka 等消息队列。
-
缓存:Spring Boot 提供了对缓存的支持,可以通过注解
@EnableCaching
启用缓存,并与 Redis、EhCache 等缓存提供商集成。 -
配置管理:Spring Boot 支持多种外部化配置的方式,包括属性文件、YAML文件、环境变量和命令行参数。它还提供了类型安全的配置属性绑定。
-
测试:Spring Boot 提供了测试支持,包括自动配置测试、MockMvc 测试 Web 应用、测试数据库和测试 REST 服务。
-
构建工具:Spring Boot 可以与 Maven 和 Gradle 等构建工具无缝集成,提供了许多插件来简化构建和部署过程。
六、登陆注册代码示例
1.依赖配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xinzhi</groupId>
<artifactId>SpringBootTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBootTest</name>
<description>SpringBootTest</description>
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.12.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.16</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<!-- 阿里json包 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.74</version>
</dependency>
<!-- FileUtils工具类 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!-- 通用mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.xinzhi.SpringBootTestApplication</mainClass>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.实体类
package com.xinzhi.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data // 构造函数、Getter和Setter省略
@NoArgsConstructor //无参构造
@Builder //用来构造复杂对象
@AllArgsConstructor //有参构造
public class User {
private int id;
private String username;
private String password;
private String sex;
private String age;
private String phone;
}
3.业务逻辑层
(1.)接口类
package com.xinzhi.service;
import com.xinzhi.model.User;
public interface UserService {
boolean isValidPhoneNumber(String phone);
boolean isValidPassword(String password);
boolean isValidUnique(String phone);
User getUserByPhone(String phone);
String register(String phone, String password,String username);
boolean login(String phone, String password);
void changePassword(String phone, String oldPassword, String newPassword);
void bindPhone(int userid, String phone);
void updateUserMation(User ui,String strSex);
}
(2.)实现类
package com.xinzhi.service.impl;
import com.xinzhi.dao.UserDao;
import com.xinzhi.model.User;
import com.xinzhi.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import javax.annotation.Resource;
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserDao userDao;
@Override
public boolean isValidPhoneNumber(String phone) {
String regex = "^1[3456789]\\d{9}$";
return phone.matches(regex);
}
@Override
public boolean isValidPassword(String password) {
String regex = "^(?=.*[0-9])(?=.*[a-zA-Z])(.{8,12})$";
return password.matches(regex);
}
@Override
public boolean isValidUnique(String phone) {
User regex = userDao.getUserByPhone(phone);
return regex == null;
}
@Override
public User getUserByPhone(String phone) {
return getUserByPhone(phone);
}
@Override
public String register(String phone, String password, String username) {
if (!isValidUnique(phone))
return "该手机号已被注册";
String encryptedPassword = DigestUtils.md5DigestAsHex(password.getBytes());
User user = new User();
user.setPhone(phone);
user.setPassword(encryptedPassword);
user.setUsername(username);
int insert = userDao.insert(user);
return insert > 0 ? "注册成功" : "注册失败";
}
@Override
public boolean login(String phone, String password) {
User user = userDao.getUserByPhone(phone);
if (user == null){
return false;
}
String encryptedPassword = DigestUtils.md5DigestAsHex(password.getBytes());
return user.getPassword().equals(encryptedPassword);
}
@Override
public void changePassword(String phone, String oldPassword, String newPassword) {
User user = userDao.getUserByPhone(phone);
if (user == null) {
throw new RuntimeException("该用户不存在");
}
String encryptedOldPassword = DigestUtils.md5DigestAsHex(oldPassword.getBytes());
if (!user.getPassword().equals(encryptedOldPassword)) {
throw new RuntimeException("原密码错误");
}
String encryptedNewPassword = DigestUtils.md5DigestAsHex(newPassword.getBytes());
userDao.update(phone, encryptedNewPassword);
}
@Override
public void bindPhone(int userid, String phone) {
User user = userDao.getUserById(userid);
if (user == null) {
throw new RuntimeException("该用户不存在");
}
userDao.updatePhone(userid,phone);
}
@Override
public void updateUserMation(User ui, String strSex) {
ui.setAge(String.valueOf(strSex.equals("男") ? 1 : 0));
userDao.updateUser(ui);
}
}
4.mapper接口
package com.xinzhi.dao;
import com.xinzhi.model.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface UserDao {
/**
* 根据手机号查询用户
* @param phone
* @return
*/
User getUserByPhone(@Param("phone")String phone);
/**
* 根据用户id查询用户
* @param userid
* @return
*/
User getUserById(@Param("id")int userid);
/**
* 新增用户
* @param user
* @return
*/
int insert(User user);
/**
* 更新用户密码
* @param phone 用户手机号
* @param password 密码
* @return
*/
int update(@Param("phone")String phone,@Param("password")String password);
/**
* 更新用户手机号
* @param userid
* @param phone
* @return
*/
int updatePhone(@Param("id")int userid,@Param("phone")String phone);
/**
* 更新用户信息
* @param user
* @return
*/
int updateUser(User user);
/**
* 更新用户头像
* @param user
* @return
*/
int updateAvatar(User user);
void updateAvatar(String imagePath);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.xinzhi.dao.UserDao" >
<insert id="insert">
insert into user(userid,username,password,phone) values(0,#{username},#{password},#{phone})
</insert>
<update id="update">
update user set password = #{password} where phone = #{phone}
</update>
<update id="updatePhone">
UPDATE user
SET phone = #{phone} where user=#{user}
</update>
<update id="updateUser">
UPDATE user
SET
username = #{username},
age = #{age},
sex = #{sex},
WHERE phone = #{phone}
</update>
<update id="updateAvatar">
UPDATE user
SET touphoto = #{imagePath}
</update>
<select id="getUserByPhone" resultType="com.xinzhi.model.User">
select * from user where phone = ${phone}
</select>
<select id="getUserById" resultType="com.xinzhi.model.User">
select * from user where userinfoid = ${userid}
</select>
</mapper>
5.数据访问层
package com.xinzhi.controller;
import com.xinzhi.model.User;
import com.xinzhi.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/register")
public String register(String phone,String password,String username) {
System.out.println(phone + "------" + password);
if (!userService.isValidPhoneNumber(phone)){
return "手机号格式错误";
}
if (!userService.isValidPassword(password)){
return "密码格式错误";
}
String register = userService.register(phone, password, username);
return register;
}
@PostMapping("/login")
public String login(String phone,String password) {
if (!userService.isValidPhoneNumber(phone)){
return "手机号格式错误";
}
if (!userService.isValidPassword(password)) {
return "密码格式错误";
}
if (userService.login(phone,password)){
return "登陆成功";
}else {
return "登陆失败";
}
}
@GetMapping("/user")
public User getUser(String phone) {
return userService.getUserByPhone(phone);
}
@PostMapping("/changePassword")
public String changePassword(String phone,String oldPassword,String newPassword,String confirmPassword) {
System.out.println(phone + oldPassword + newPassword + confirmPassword);
if (!newPassword.equals(confirmPassword)) {
return "两次输入的密码不一致";
}
try {
userService.changePassword(phone, oldPassword, newPassword);
return "修改成功";
} catch (Exception e) {
return e.getMessage();
}
}
@PostMapping("/bindPhone")
public String bindPhone(int userid,String phone) {
System.out.println(userid);
if (!userService.isValidPhoneNumber(phone)){
return "手机号格式错误,请重新输入";
}
try{
userService.bindPhone(userid,phone);
return "绑定成功";
}catch (Exception e){
return e.getMessage();
}
}
@PostMapping("/updateUser")
public String updateUser(User ui,String strSex) {
try{
userService.updateUserMation(ui,strSex);
return "修改成功";
}catch (Exception e){
return e.getMessage();
}
}
}