【JavaEE进阶】Spring 更简单的读取和存储对象
文章目录
- 一. 存储Bean对象
- 1. 配置扫描路径
- 2. 添加注解存储 Bean 对象
- 2.1 使用五大类注解存储Bean
- 2.2 为什么要有五大类注解?
- 2.3 有关获取Bean参数的命名规则
- 3. 使用方法注解储存 Bean 对象
- 3.1 方法注解储存对象的用法
- 3.2 @Bean的重命名
- 3.3 同⼀类型多个 @Bean 报错
- 二. 获取 Bean 对象(对象装配)
- 1. 属性注入
- 2. Setter注入
- 3. 构造方法注入(Spring官方推荐)
- 4. @Resource:另⼀种注入关键字
一. 存储Bean对象
1. 配置扫描路径
配置扫描路径是使用注解之前的前置工作,是非常重要的,是必须的操作项.只有被配置的包下的所有类,添加了注解才能被正确的识别并保存到 Spring 中.
首先创建一个Spring项目.创建好后,第一步就是配置扫描路径:在resources目录中创建一个spring-config.xml文件.然后在spring-config.xml添加如下配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:content="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><content:component-scan base-package=""></content:component-scan>
</beans>
<content:component-scan base-package=""></content:component-scan>中base-package=""的值设置为需要扫描对象的根路径.注意:这个根路径是从java目录开始的.

2. 添加注解存储 Bean 对象
想要将对象存储在spring中,有两种注解类型可以实现:
-
使用类注解(五大类注解):
@Controller:控制器:验证用户请求的数据正确性(相当于安保系统).@Service:服务:编排和调度具体执行方法(相当于客服中心).@Repository:持久层:和数据库交互;(相当于执行者) = DAO(Date Access Obiect)数据访问层@Component:组件;(工具类)@Configuration:配置项(项目中的一些配置)
-
方法注解
@Bean
2.1 使用五大类注解存储Bean
首先,我们来了解如何使用五大类注解来储存对象
-
@Controllerpackage com.spring.demo;import org.springframework.stereotype.Controller;@Controller public class UserController {public void sayHi() {System.out.println("UserController sayHi!");} }在扫描路径下创建该
UserController类.并在类上加@Controller注解,此时就将Bean存储到容器中了.接下来就是从 Spring 中读取出我们的对象,这里还是先使用依赖查找的方式来获取 Bean,使用五大类注解,默认情况下,Bean 的名字就是原类名首字母小写(小驼峰).
import com.spring.demo.UserController; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {//1.获取 srping 容器ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");//2.获取 bean 对象//获取对象时使用类名的小驼峰形式作为 name 参数UserController userController = context.getBean("userController", UserController.class);//3.使用 beanuserController.sayHi();} }运行结果:

注意:要将Bean存储到Spring中需要满足两个条件:- 使用五大类注解创建的类
- 必须在配置的扫描路径下.(包括子包)
扫描路径也叫做根路径.两个条件缺一不可.
为什么要设置根路径?
设置根路径其实也是为了提高程序的性能,因为如果不设置根路径,Spring 就会扫描项目文件中所有的目录,但并不是所有类都需要储存到 Spring当中,这样性能就会比较低,设置了根路径,Spring 就只扫描该根路径下所有的目录就可以了,提高了程序的性能。下来我们演示一下没有配置扫描路径下的情况:

还需要知道的是使用注解存储的 Bean 和使用XML存储的的 Bean 是可以一同使用的,比如我们将刚刚有问题的Student重新通过XML的方式进行存储.

注意:默认情况下,使用原类名首字母小写就能读取到Bean对象.特例情况:原类名如果首字母和第二个字母都是大写的情况下,那么bean名称就是原类名.

-
@Service
启动类中代码://1.获取 srping 容器ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");//2.获取 bean 对象//获取对象时使用类名的小驼峰形式作为 name 参数UserService userService = context.getBean("userService", UserService.class);//3.使用 beanuserService.sayHi();UserService类:package com.spring.demo;import org.springframework.stereotype.Service;@Service public class UserService {public void sayHi(){System.out.println("UserService sayHi!");} }运行结果:

其余三种使用方式相同,此处不再做介绍.
2.2 为什么要有五大类注解?
既然都五大类完成的是同样的工作,那为什么要有五大类注解呢?
其实五大类注解主要是为了规范 Java 项目的代码,Java 项目的标准分层如下:
- 控制层(Controller)
- 服务层(Service)
- 数据持久层(Dao)
而五大类注解便是对应着不同的层级别使用的,让程序猿看到某一个注解就可以明确这个了类是做什么的。
程序的⼯程分层,调⽤流程如下:

包括企业中也是按照这样的结构来将项目分层的,典型的比如阿里,它只是在标准分层在服务层(Service)做了一个扩展,划分的更加细致详细了.

五大类注解主要起到的是“见名知意”的作用,代码层面上来看,作用是类似的.查看五大类源码可知:
五大类的源码中除了 @Component 以外,其他四大类注解中都包含了 @Component 注解的功能,这四大类注解都是基于 @Component 实现的,是 @Component 拓展。
2.3 有关获取Bean参数的命名规则
上文中在使用依赖查找的方式获取Bean时,我们讲到了getBean方法的BeanName是使用类名的小驼峰形式(即类名的首字母小写)以及第一个字母和第二个字母都大写情况下的特例.
注意:BeanName的规范命名规则并不是 Spring 独创的,而依照 Java 标准库的规则进行的。
BeanName的规范命名规则:
- 如果类名不存在或类名为空字符串,
BeanName为原类名。 - 如果类名字长度大于1,且第一个与第二个字符为大写,
BeanName为原类名。 - 其他情况,
BeanName为原类名的小驼峰形式.
3. 使用方法注解储存 Bean 对象
3.1 方法注解储存对象的用法
类注解是添加到某个类上的,而方法注解是放到某个方法上的.在Spring框架的设计中,方法注解@Bean要配合类注解才能将对象正常存储到Spring容器中.
举个🌰:我们有一个普通书本类
package com.spring.demo;import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;@Controller
public class BookInfo {private String bookName;private String author;private String style;public String getBookName() {return bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public String getStyle() {return style;}public void setStyle(String style) {this.style = style;}@Override@Beanpublic String toString() {return "com.spring.demo.BookInfo{" +"bookName='" + bookName + '\'' +", author='" + author + '\'' +", style='" + style + '\'' +'}';}}
下面演示使用@Bean方法注解储存对象:
package com.spring.demo;import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;@Controller
public class Books {@Beanpublic BookInfo getBook(){BookInfo bookInfo = new BookInfo();bookInfo.setBookName("三体");bookInfo.setAuthor("刘慈欣");bookInfo.setStyle("文学科幻");return bookInfo;}public void sayHi(){System.out.println("Books sayHi!");}
}
启动类:
获取方法注解储存的对象时,传入的BeanName参数值默认值就是方法名,上面的代码中方法名为getBook,所以获取时,就使用getBook作为参数来进行获取。
import com.spring.demo.BookInfo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App2 {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");BookInfo book = context.getBean("getBook", BookInfo.class);System.out.println(book);}
}
运行结果:

3.2 @Bean的重命名
获取方法注解储存的对象时,传入的BeanName参数值默值为方法名,但像上面那样返回对象的方法名称往往是getXXX这样式取名的,虽然在语法与实现上是没有问题的,但实际开发写出这样的代码,看起来还是比较别扭的。
实际上注解 @Bean 是可以加参数的,给储存的对象起别名,像下面这个样子。
package com.spring.demo;import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;@Controller
public class Books {@Bean(name = "book")public BookInfo getBook(){BookInfo bookInfo = new BookInfo();bookInfo.setBookName("三体");bookInfo.setAuthor("刘慈欣");bookInfo.setStyle("文学科幻");return bookInfo;}public void sayHi(){System.out.println("Books sayHi!");}
}

也可以给 Bean 设置多个别名,总结起来有如下几种方式:
//方式一(省略参数名的情况下默认是name)
@Bean("article1")
//方式二
@Bean(name = "article2")
//方式三
@Bean(value = "article3")
//起多个别名
@Bean(name = {"article4", "article5"})
@Bean(value = {"article6", "article7"})
@Bean({"article8", "article9", "article10"})
但是需要注意,当重新命名之后,就不能使用原来的方法名来获取对象了.

所以使用 @Bean 存储对象的beanName命名规则是,当没有设置name/value属性时,此时 Bean 的默认名字就是方法名,一旦添加了别名name/value属性后,就只能通过重命名的别名来获取 Bean 了,默认的使用方法名获取 Bean 对象就不能使用了。
@Bean 使用时,同一类如果多个 Bean 使用相同的名称,此时程序执行是不会报错的,他会根据类加载顺序和类中代码从上至下的的顺序,将第一个 Bean 存放到 Spring 中,但第一个之后的对象就不会被存放到容器中了,也就是只有在第一次创建 Bean 的时候会将对象和 Bean 名称关联起来,后续再有相同名称的Bean存储时候,容器会自动忽略。
还可以通过类注解 @Order 注解控制类加载顺序(值越小,优先级越高),进而影响 Bean 的存放的先后顺序.
3.3 同⼀类型多个 @Bean 报错
当出现以下多个 Bean,返回同⼀对象类型时程序会报错,如下代码所示:


运行结果如下:

报错的原因是,⾮唯⼀的 Bean 对象.
同⼀类型多个 Bean 报错处理:
解决同⼀个类型,多个 bean 的解决⽅案有以下两个:
- 使⽤
@Resource(name="user1")定义。(@Resource下文有介绍)

- 使⽤
@Qualifier注解定义名称。

二. 获取 Bean 对象(对象装配)
获取bean对象也叫做对象装配.是把bean对象取出来放到某个类中.有时候也叫对象注⼊(DI).
对象装配(对象注⼊)的实现⽅法以下 3 种:
- 属性注⼊
- 构造⽅法注⼊
- Setter 注⼊
接下来,我们分别来看。
下⾯我们按照实际开发中的模式,将Service类注⼊到Controller类中。
1. 属性注入
属性注⼊是使⽤ @Autowired 实现的,将 Service 类注⼊到 Controller 类中。
User代码:
package com.spring.demo;public class User {private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +'}';}
}
Service代码:
package com.spring.demo;import org.springframework.stereotype.Service;@Service
public class UserService {public void sayHi(){System.out.println("UserService sayHi!");}public User getUser(Integer id){User user = new User();user.setId(id);user.setName("xxxflower-"+id);return user;}}
Controller代码:
package com.spring.demo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {@Autowiredprivate UserService userService;public User getUser(Integer id){return userService.getUser(id);}public void sayHi() {System.out.println("UserController sayHi!");}
}
运行结果:


优点:简单.
缺点:
- 没办法实现final修饰的变量注入.

- 兼容不好:只适用于Ioc容器.
- 风险:因为写法简单,所以违背单一设计原则的概率更大.
2. Setter注入
Setter 注⼊和属性的 Setter ⽅法实现类似,只不过在设置 set ⽅法的时候需要加上 @Autowired 注解,如下代码所示:
package com.spring.demo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController2 {private UserService userService;//2.使用Setter注入@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}public User getUser(Integer id){return userService.getUser(id);}
}
运行结果:

优点:符合单一设计原则(每个方法只传递一个对象)
缺点:
- 不能注入不可变对象

- 使用setter注入的对象可能会被修改.
3. 构造方法注入(Spring官方推荐)
构造⽅法注⼊是在类的构造⽅法中实现注⼊,如下代码所示:
package com.spring.demo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController3 {private UserService userService;//3.构造方法注入@Autowiredpublic UserController3(UserService userService){this.userService = userService;}public User getUser(Integer id){return userService.getUser(id);}
}
运行结果:

特点:如果当前类中只有一个构造方法的话,那么@Autowired 注解可以省略.

优点:
- 可以注入一个不可变对象(使用fianl修饰的对象)

问题:为什么构造方法可以注入一个不可变对象,而属性注入和Setter注入却不行?
答:这是Java的规定,在java中,被final对象必须满足以下两个条件中的任意一个:
- final修饰的对象,是直接复制的.
- final修饰的对象,必须在构造方法中赋值.
- 注入的对象不会被改变(构造方法只能执行一次)
- 构造方法注入可以保证注入对象完全被初始化
- 通用性更好.
4. @Resource:另⼀种注入关键字
在进行类注⼊时,除了可以使⽤ @Autowired 关键字之外,我们还可以使⽤ @Resource 进⾏注⼊,如下代码所示:
package com.spring.demo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;import javax.annotation.Resource;@Controller
public class UserController {// @Autowired@Resourceprivate UserService userService;public User getUser(Integer id){return userService.getUser(id);}public void sayHi() {System.out.println("UserController sayHi!");}
}
上述三种注入方式使用@Autowired行,使用@Resource也行,但是这两者也是有区别的:
- 出身不同:@Autowired 来自于
Spring,而 @Resource 来⾃于JDK的注解; - 使⽤时设置的参数不同:相比于
@Autowired来说,@Resource⽀持更多的参数设置,例如
name设置,根据名称获取 Bean。 @Autowired可⽤于Setter注⼊、构造函数注⼊和属性注⼊,⽽@Resource只能⽤于Setter注⼊和属性注⼊,不能⽤于构造函数注⼊。
相关文章:
【JavaEE进阶】Spring 更简单的读取和存储对象
文章目录 一. 存储Bean对象1. 配置扫描路径2. 添加注解存储 Bean 对象2.1 使用五大类注解存储Bean2.2 为什么要有五大类注解?2.3 有关获取Bean参数的命名规则 3. 使用方法注解储存 Bean 对象3.1 方法注解储存对象的用法3.2 Bean的重命名3.3 同⼀类型多个 Bean 报错 …...
KafKa集群搭建和知识点
一、KafKa概述 1.1 定义 KafKa是一个分布式的基于发布/订阅模式的消息队列,主要应用于大数据试试处理领域 是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统&a…...
剑指 Offer 56 - I. 数组中数字出现的次数题解
题目描述:剑指 Offer 56 - I. 数组中数字出现的次数 - 力扣(LeetCode) 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。 示…...
CSDN付费专栏写作协议
一、总则 1.1、欢迎您选用CSDN付费专栏服务(“本服务”)。以下所述条款和条件即构成您与CSDN就使用本服务所达成的协议(“本协议)。本协议被视为《CSDN用户服务条款》(链接:https://passport.csdn.net/ser…...
[保研/考研机试] KY30 进制转换-大整数转二进制 清华大学复试上机题 C++实现
描述 将一个长度最多为30位数字的十进制非负整数转换为二进制数输出。 输入描述: 多组数据,每行为一个长度不超过30位的十进制非负整数。 (注意是10进制数字的个数可能有30个,而非30bits的整数) 输出描述ÿ…...
vue3多条件搜索功能
搜索功能在后台管理页面中非常常见,本篇就着重讲一下vue3-admin-element框架中如何实现一个顶部多条件搜索功能 一、首先需要在vue页面的<template></template>中写入对应的结构 <!-- 搜索 --><div style"display: flex; justify-content…...
C++20协程
目录 协程原理: 进程、线程和协程的区别和联系编辑 协程在IO多路复用中 协程的目的: 协程的优势: 协程原理: (学习来源:幼麟实验室) 线程是进程中的执行体,拥有一个…...
Zabbix 6.0 监控其他
文章目录 一、Zabbix 监控 Windows 系统1)下载 Windows 客户端 Zabbix agent 22)安装客户端,配置3)在服务端 Web 页面添加主机,关联模板 二、Zabbix 监控 java 应用1)客户端开启 java jmxremote 远程监控功…...
Django rest_framework Serializer中的create、Views中的create/perform_create的区别
Django rest_framework Serializer中的create、Views中的create/perform_create的区别 对于后端来说,前后端分离的方式能让前后端的开发都爽。和所有的爽一样,每爽一次都要付出一定的代价。而前后端分离的代价,就是后端要面对巨量的模块化的功…...
差异性分析傻瓜版
path1输入你的第一个Excel path2输入你的第二个Excel DEG.dig <- function(path1,path2) { require(xlsx) require(tidyverse) require(limma) require(edgeR) E<- read.xlsx (path1,sheetIndex 1,header 1) %>% column_to_rownames(var &…...
Keystone Automotive EDI 需求分析
Keystone Automotive 是一家知名的汽车零部件销售卖场,自创立以来,在汽车行业取得了卓越的成就。作为一家专业的汽车零部件供应商,Keystone Automotive 致力于为客户提供优质的产品和卓越的服务。公司的经营范围涵盖广泛,涉及多个…...
jmeter创建一个压测项目
1.jemeter新建一个项目: 2.接下来对Thread进行描述,也可以先使用默认的Thread进行操作。 3.添加http请求头的信息。按照如图所示操作 4.在请求头里面添加必要的字段,可以只填必要字段就可以 5.添加Http请求信息,如下图ÿ…...
CEC2013(MATLAB):淘金优化算法GRO求解CEC2013的28个函数
一、淘金优化算法GRO 淘金优化算法(Gold rush optimizer,GRO)由Kamran Zolf于2023年提出,其灵感来自淘金热,模拟淘金者进行黄金勘探行为。淘金优化算法(Gold rush optimizer,GRO)提…...
AI Deep Reinforcement Learning Autonomous Driving(深度强化学习自动驾驶)
AI Deep Reinforcement Learning Autonomous Driving(深度强化学习自动驾驶) 背景介绍研究背景研究目的及意义项目设计内容算法介绍马尔可夫链及马尔可夫决策过程强化学习神经网络 仿真平台OpenAI gymTorcs配置GTA5 参数选择行动空间奖励函数 环境及软件…...
Java super
在Java中,关键字"super"用于引用一个类的父类。它可以有以下几种用法: 1. 访问父类成员:通过使用"super"后跟一个点,你可以从子类中访问父类的成员(方法或字段)。当子类重写一个方法或…...
【人工智能前沿弄潮】——生成式AI系列:Diffusers学习(1)了解Pipeline 、模型和scheduler
Diffusers旨在成为一个用户友好且灵活的工具箱,用于构建针对您的用例量身定制的扩散系统。工具箱的核心是模型和scheduler。虽然DiffusionPipeline为了方便起见将这些组件捆绑在一起,但您也可以拆分管道并单独使用模型和scheduler来创建新的扩散系统。 …...
TypeScript 非空断言
TypeScript 非空断言 发布于 2020-04-08 15:20:15 17.5K0 举报 一、非空断言有啥用 介绍非空断言前,先来看个示例: function sayHello(name: string | undefined) {let sname: string name; // Error } 对于以上代码,TypeScript 编译器…...
Python编程——谈谈函数的定义、调用与传入参数
作者:Insist-- 个人主页:insist--个人主页 本文专栏:Python专栏 专栏介绍:本专栏为免费专栏,并且会持续更新python基础知识,欢迎各位订阅关注。 目录 一、理解函数 二、函数的定义 1、语法 2、定义一个…...
在Ubuntu中使用Docker启动MySQL8的天坑
写在前面 简介: lower_case_table_names 是mysql设置大小写是否敏感的一个参数。 1.参数说明: lower_case_table_names0 表名存储为给定的大小和比较是区分大小写的 lower_case_table_names 1 表名存储在磁盘是小写的,但是比较的时候是不区…...
Python3.x String内置函数大全
文章目录 总结一下Python3.x字符串的常用系统函数,总共分为8类1. 大小写字母转换类的函数str.capitalize()str.title()str.lower()str.upper()str.swapcase() 2. 统计类的函数str.count(str1, beg 0,endlen(string)) 3. 匹配类的函数str.endswith(suffix, beg0, end…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
