【Spring】简单的登录案例和配套知识
创始人
2024-01-16 19:23:05

本篇文章接着介绍 Spring 的相关知识,主要通过一个非常非常简单用户登录案例来介绍,各位大佬们路过记得赏小的一颗赞🤩


文章目录

  • 1. 演示一下 Spring 管理类的模式
  • 2. 用户登录案例
    • 2.1 准备的对象和其功能
      • 2.1.1 User
      • 2.1.2 UserController
      • 2.1.3 UserService
      • 2.1.4 UserDao
      • 2.1.5 AppConfig
      • 2.1.6 DemoApplication
    • 2.2 各对象之间的依赖关系
    • 2.3 IOC 带来的一个好处
  • 3. Spring 中的日志打印
    • 3.1 Spring 官方提供的方式
    • 3.2 lombok 提供的方法
    • 3.2 日志打印级别
    • 3.3 修改当前日志级别

1. 演示一下 Spring 管理类的模式

下面代码在第一次打印 Person 对象的时候,pid = 0,name = null,

第二次打印的时候,pid 有值,name 依旧是 null

第三次打印的时候,pid 和 name 都有值

而 pid 和 name 是由不同的两个类赋值的,说明这两个类被注入了同一个 Bean,由此可知 Spring 管理对象采用单例模式

一般在 Java 中,表过程的对象总是以单例的方式出现,表数据的对象无法使用单例管理,所以,一般让 Spring 管理的对象大多是表过程的对象(不是绝对的)

@Component
public class Person {int pid;String name;@Overridepublic String toString() {return "Person{" +"pid=" + pid +", name='" + name + '\'' +'}';}
}
@Component
public class Person1 {@Autowiredpublic void usePerson1(Person person) {System.out.println("usePerson1(), person = " + person);person.pid = 20221024;}
}
@Component
public class Person2 {@Autowiredpublic void usePerson2(Person person) {System.out.println("usePerson2(), person = " + person);person.name = "hsq";}
}
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) throws Exception {ApplicationContext context = SpringApplication.run(DemoApplication.class, args);Person bean = context.getBean(Person.class);System.out.println(bean);}}

请添加图片描述

2. 用户登录案例

没有用到 Web 的形式,仅仅只是从控制台输入输出,然后将数据存入数据库

2.1 准备的对象和其功能

在 IOC 之外的场景下,Bean 注入的注释标签就要有一些区分了

2.1.1 User

表示用户本身(属性,构造方法,toString)

public class User {public Integer uid;public String username;public String password;public User() {}public User(String username, String password) {this.username = username;this.password = password;}public User(Integer uid, String username, String password) {this.uid = uid;this.username = username;this.password = password;}@Overridepublic String toString() {return "User{" +"uid=" + uid +", username='" + username + '\'' +", password='" + password + '\'' +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;User user = (User) o;return Objects.equals(uid, user.uid);}@Overridepublic int hashCode() {return Objects.hash(uid);}
}

2.1.2 UserController

进行用户输入、输出的操作(不同于 Web 的模式,这里的输入输出通过 Scanner(System.in) 和 System.out 控制)

@Controller
public class UserController {// 依赖输入、输出,我们自己不强调一定是标准输入输出private final Scanner scanner;private final PrintWriter writer;private final UserService userService;// 全部让 Spring 帮我们注入@Autowiredpublic UserController(Scanner scanner, PrintWriter writer, UserService userService) {this.scanner = scanner;this.writer = writer;this.userService = userService;}public void run() throws Exception {while (true) {writer.print("请选择是注册还是登录:");writer.flush();String func = scanner.nextLine();if (func.equals("注册")) {writer.println("您选择了【注册】功能,接下来请输入用户名和密码");writer.print("请输入用户: ");writer.flush();String username = scanner.nextLine();writer.print("请输入密码: ");writer.flush();String password = scanner.nextLine();User user = userService.register(username, password);writer.println("注册完成,您的用户信息是: " + user);} else if (func.equals("登录")) {writer.println("您选择了【登录】功能,接下来请输入用户名和密码");writer.print("请输入用户: ");writer.flush();String username = scanner.nextLine();writer.print("请输入密码: ");writer.flush();String password = scanner.nextLine();User user = userService.login(username, password);if (user == null) {writer.println("登录失败");} else {writer.println("登录成功,您的用户信息是: " + user);}}}}
}

2.1.3 UserService

进行必要的数据操作,进行密码的加密和解密

@Service
public class UserService {// UserService 对象依赖 UserDao 对象// 直接使用注入的方式private final UserDao userDao;// 构造方法注入@Autowiredpublic UserService(UserDao userDao) {this.userDao = userDao;}public User register(String username, String password) throws Exception {// 1. 密码的 hash 加密String salt = BCrypt.gensalt();password = BCrypt.hashpw(password, salt);// 2. 进行插入User user = new User(username, password);userDao.insert(user);// 3. 返回构造完成的用户对象return user;}public User login(String username, String password) throws Exception {// 1. 先查询用户User user = userDao.selectOneByUsername(username);if (user == null) {return null;}// 2. 进行密码的比较if (!BCrypt.checkpw(password, user.password)) {return null;}// 3. 返回构造完成的用户对象return user;}
}

上面代码中用到的 BCrypt 算法是一种密码加密算法,代码篇幅过长,有需要的大佬可以去自行下载 —— BCrypt 加密算法下载

2.1.4 UserDao

对数据库进行操作

@Repository
public class UserDao {private static final Logger log = LoggerFactory.getLogger(UserDao.class);// 依赖 DataSource 对象才能完成// 需要 Spring 帮我们注入 DataSource 对象private final DataSource dataSource;// 使用构造方法注入(依赖注入)@Autowiredpublic UserDao(DataSource dataSource) {this.dataSource = dataSource;}public void insert(User user) throws Exception {try (Connection c = dataSource.getConnection()) {String sql = "insert into users (username, password) values (?, ?)";try (PreparedStatement ps = c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {ps.setString(1, user.username);ps.setString(2, user.password);log.info("执行的 SQL = {} ", ps);ps.executeUpdate();try (ResultSet rs = ps.getGeneratedKeys()) {rs.next();user.uid = rs.getInt(1);}}}}public User selectOneByUsername(String username) throws Exception {try (Connection c = dataSource.getConnection()) {String sql = "select uid, username, password from users where username = ?";try (PreparedStatement ps = c.prepareStatement(sql)) {ps.setString(1, username);log.info("执行的 SQL = {} ", ps);try (ResultSet rs = ps.executeQuery()) {if (!rs.next()) {return null;}return new User(rs.getInt("uid"),rs.getString("username"),rs.getString("password"));}}}}
}

2.1.5 AppConfig

因为案例只是我自己写的,所以前面代码中所注入的 Bean,我需要自行注册进 Spring,这里采用方法注册。并且在这里配置数据库

@Configuration
public class AppConfig {@Beanpublic Scanner scanner() {return new Scanner(System.in);}@Beanpublic PrintWriter writer() {// PrintStream -> PrintWriterPrintStream printStream = System.out;return new PrintWriter(printStream, true);}@Beanpublic DataSource dataSource() {MysqlDataSource dataSource = new MysqlDataSource();dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/demo?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");dataSource.setUser(" ");	// 数据库用户名dataSource.setPassword(" ");	// 数据库密码return dataSource;}
}

2.1.6 DemoApplication

主类,程序的入口,调用 UserController 中的 run() 方法开始程序

@SpringBootApplication
public class DemoApplication {public static void main(String[] args) throws Exception {ApplicationContext context = SpringApplication.run(DemoApplication.class, args);UserController userController = context.getBean(UserController.class);userController.run();}}

2.2 各对象之间的依赖关系

请添加图片描述

2.3 IOC 带来的一个好处

我们去依赖抽象的概念,不需要具体的实现

好处是,我们可以很方便的替换背后的依赖对象。比如:刚才我们依赖的 Scanner 对象是从标准输入读取的,我们可以很方便的替换成读取文件的方式

只需修改 AppConfig 对象中的 Scanner 方法为以下即可

public Scanner scanner() throws FileNotFoundException {
//        return new Scanner(System.in);File file = new File("input.txt");return new Scanner(file, "UTF-8");
}

3. Spring 中的日志打印

3.1 Spring 官方提供的方式

先得到 log 对象,再调用其中方法打印日志即可

private static final Logger log = LoggerFactory.getLogger(UserDao.class);log.info("执行的 SQL = {} ", ps);

3.2 lombok 提供的方法

使用 @Slf4j 注释修饰此类,然后使用 log 调用方法打印即可,前提是必须要有 lombok 插件

3.2 日志打印级别

比当前日志级别低的打印方式不会有结果

如:当前日志级别为 info 时,那么用 debug 打印不会有结果

请添加图片描述

3.3 修改当前日志级别

默认日志级别是 info ,我们可以在配置文件中修改当前日志级别

在配置文件中写入如下代码,即可将 com.hsq.demo 包下的日志文件修改为 debug

logging.level.com.hsq.demo=debug

相关内容

热门资讯

北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
阿西吧是什么意思 阿西吧相当于... 即使你没有受到过任何外语培训,你也懂四国语言。汉语:你好英语:Shit韩语:阿西吧(아,씨발! )日...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...