当前位置: 首页 > news >正文

一、Spring Boot集成Spring Security之自动装配

Spring Boot集成Spring Security之自动装配介绍

  • 一、实现功能及软件版本说明
  • 二、创建Spring Boot项目
  • 三、查看自动装配配置类
  • 四、自动装配配置类之SecurityAutoConfiguration
    • 1、SecurityAutoConfiguration部分源码
    • 2、主要作用
    • 3、SpringBootWebSecurityConfiguration
      • 3.1、SpringBootWebSecurityConfiguration部分源码
      • 3.2、主要作用
    • 4、@EnableWebSecurity
      • 4.1、部分源码
      • 4.2、主要作用
    • 5、WebSecurityConfiguration
      • 5.1、部分源码
      • 5.2、主要作用
    • 6、HttpSecurityConfiguration
      • 6.1、部分源码
      • 6.2、主要作用
  • 五、自动装配配置类之UserDetailsServiceAutoConfiguration
    • 1、部分源码
    • 2、主要作用
  • 六、自动装配配置类之SecurityFilterAutoConfiguration
    • 1、部分源码
    • 2、主要作用

一、实现功能及软件版本说明

  1. 使用Spring Boot集成Spring Security实现Servlet项目的安全个性化配置
  2. Spring Boot版本:2.7.18
  3. Spring Security版本:5.7.11

二、创建Spring Boot项目

  1. 创建Spring Boot项目,目录结构如下
    Spring Boot目录结构
  2. 引入Spring Security包,完成pom.xml如下
<?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><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.18</version><relativePath/></parent><groupId>com.yu</groupId><artifactId>spring-boot-security2-demo</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-boot-security2-demo</name><description>Spring Boot集成Spring Security样例</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency></dependencies></project>

三、查看自动装配配置类

  1. 查看Security Servlet相关自动装配配置类
    自动装配配置

四、自动装配配置类之SecurityAutoConfiguration

1、SecurityAutoConfiguration部分源码

@AutoConfiguration
@ConditionalOnClass(DefaultAuthenticationEventPublisher.class)
@EnableConfigurationProperties(SecurityProperties.class)
@Import({ SpringBootWebSecurityConfiguration.class, SecurityDataConfiguration.class })
public class SecurityAutoConfiguration {@Bean@ConditionalOnMissingBean(AuthenticationEventPublisher.class)public DefaultAuthenticationEventPublisher authenticationEventPublisher(ApplicationEventPublisher publisher) {return new DefaultAuthenticationEventPublisher(publisher);}}

2、主要作用

  1. 导入SpringBootWebSecurityConfiguration

3、SpringBootWebSecurityConfiguration

3.1、SpringBootWebSecurityConfiguration部分源码

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
class SpringBootWebSecurityConfiguration {@Configuration(proxyBeanMethods = false)@ConditionalOnDefaultWebSecuritystatic class SecurityFilterChainConfiguration {@Bean@Order(SecurityProperties.BASIC_AUTH_ORDER)SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated();http.formLogin();http.httpBasic();return http.build();}}@Configuration(proxyBeanMethods = false)@ConditionalOnMissingBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN)@ConditionalOnClass(EnableWebSecurity.class)@EnableWebSecuritystatic class WebSecurityEnablerConfiguration {}}

3.2、主要作用

  1. 默认Security配置(Spring容器中没有SecurityFilterChain和WebSecurityConfigurerAdapter)时,向Spring容器中注入默认过滤器链,即用户没有自定义过滤器链时,生成默认过滤器链
    默认过滤器链
  2. Spring容器中不存在名称为springSecurityFilterChain对象时,启用WebSecurity,即用户未显示的启用WebSecurity时,隐式的启用WebSecurity
    在这里插入图片描述

4、@EnableWebSecurity

4.1、部分源码

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import({ WebSecurityConfiguration.class, SpringWebMvcImportSelector.class, OAuth2ImportSelector.class,HttpSecurityConfiguration.class })
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {/*** Controls debugging support for Spring Security. Default is false.* @return if true, enables debug support with Spring Security*/boolean debug() default false;}

4.2、主要作用

  1. 导入WebSecurityConfiguration
  2. 导入HttpSecurityConfiguration

5、WebSecurityConfiguration

5.1、部分源码

@Configuration(proxyBeanMethods = false)
public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)public Filter springSecurityFilterChain() throws Exception {boolean hasConfigurers = this.webSecurityConfigurers != null && !this.webSecurityConfigurers.isEmpty();boolean hasFilterChain = !this.securityFilterChains.isEmpty();Assert.state(!(hasConfigurers && hasFilterChain),"Found WebSecurityConfigurerAdapter as well as SecurityFilterChain. Please select just one.");if (!hasConfigurers && !hasFilterChain) {WebSecurityConfigurerAdapter adapter = this.objectObjectPostProcessor.postProcess(new WebSecurityConfigurerAdapter() {});this.webSecurity.apply(adapter);}for (SecurityFilterChain securityFilterChain : this.securityFilterChains) {this.webSecurity.addSecurityFilterChainBuilder(() -> securityFilterChain);for (Filter filter : securityFilterChain.getFilters()) {if (filter instanceof FilterSecurityInterceptor) {this.webSecurity.securityInterceptor((FilterSecurityInterceptor) filter);break;}}}for (WebSecurityCustomizer customizer : this.webSecurityCustomizers) {customizer.customize(this.webSecurity);}return this.webSecurity.build();}
}

5.2、主要作用

  1. 两种方式注册过滤器链:
    • 继承WebSecurityConfigurerAdapter(本质是实现SecurityConfigurer接口) (已弃用)
    • 直接向Spring容器种注册SecurityFilterChain对象
  2. 没有默认的过滤器链时,使用WebSecurityConfigurerAdapter中默认配置生成过滤器链
  3. 根据配置的SecurityFilterChain集合构建FilterChainProxy类型的对象并注入到Spring容器中名称为springSecurityFilterChain

6、HttpSecurityConfiguration

6.1、部分源码

@Configuration(proxyBeanMethods = false)
class HttpSecurityConfiguration {@Bean(HTTPSECURITY_BEAN_NAME)@Scope("prototype")HttpSecurity httpSecurity() throws Exception {WebSecurityConfigurerAdapter.LazyPasswordEncoder passwordEncoder = new WebSecurityConfigurerAdapter.LazyPasswordEncoder(this.context);AuthenticationManagerBuilder authenticationBuilder = new WebSecurityConfigurerAdapter.DefaultPasswordEncoderAuthenticationManagerBuilder(this.objectPostProcessor, passwordEncoder);authenticationBuilder.parentAuthenticationManager(authenticationManager());authenticationBuilder.authenticationEventPublisher(getAuthenticationEventPublisher());HttpSecurity http = new HttpSecurity(this.objectPostProcessor, authenticationBuilder, createSharedObjects());// @formatter:offhttp.csrf(withDefaults()).addFilter(new WebAsyncManagerIntegrationFilter()).exceptionHandling(withDefaults()).headers(withDefaults()).sessionManagement(withDefaults()).securityContext(withDefaults()).requestCache(withDefaults()).anonymous(withDefaults()).servletApi(withDefaults()).apply(new DefaultLoginPageConfigurer<>());http.logout(withDefaults());// @formatter:onapplyDefaultConfigurers(http);return http;}
}

6.2、主要作用

  1. Spring容器中注册HttpSecurity对象
  2. httpSecurity用于配置构建自定义过滤器链

五、自动装配配置类之UserDetailsServiceAutoConfiguration

1、部分源码

@AutoConfiguration
@ConditionalOnClass(AuthenticationManager.class)
@ConditionalOnBean(ObjectPostProcessor.class)
@ConditionalOnMissingBean(value = { AuthenticationManager.class, AuthenticationProvider.class, UserDetailsService.class,AuthenticationManagerResolver.class },type = { "org.springframework.security.oauth2.jwt.JwtDecoder","org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector","org.springframework.security.oauth2.client.registration.ClientRegistrationRepository","org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository" })
public class UserDetailsServiceAutoConfiguration {@Bean@Lazypublic InMemoryUserDetailsManager inMemoryUserDetailsManager(SecurityProperties properties,ObjectProvider<PasswordEncoder> passwordEncoder) {SecurityProperties.User user = properties.getUser();List<String> roles = user.getRoles();return new InMemoryUserDetailsManager(User.withUsername(user.getName()).password(getOrDeducePassword(user, passwordEncoder.getIfAvailable())).roles(StringUtils.toStringArray(roles)).build());}private String getOrDeducePassword(SecurityProperties.User user, PasswordEncoder encoder) {String password = user.getPassword();if (user.isPasswordGenerated()) {logger.warn(String.format("%n%nUsing generated security password: %s%n%nThis generated password is for development use only. "+ "Your security configuration must be updated before running your application in "+ "production.%n",user.getPassword()));}if (encoder != null || PASSWORD_ALGORITHM_PATTERN.matcher(password).matches()) {return password;}return NOOP_PASSWORD_PREFIX + password;}

2、主要作用

  1. 用户未自定义认证接口时,生成默认认证接口inMemoryUserDetailsManager(基于内存用户认证)
  2. 生成默认名称为user,密码为随机生成的uuid(项目启动时会打印在控制台中),角色为空的用户存入内存中
#UserDetailsServiceAutoConfiguration.inMemoryUserDetailsManager方法中获取user对象
SecurityProperties.User user = properties.getUser();
#SecurityProperties中的Userpublic static class User {private String name = "user";private String password = UUID.randomUUID().toString();private List<String> roles = new ArrayList<>();}
  1. 通过配置文件可以修改默认用户名、密码、角色(示例如下)
    配置默认用户名、密码、角色

六、自动装配配置类之SecurityFilterAutoConfiguration

1、部分源码

@AutoConfiguration(after = SecurityAutoConfiguration.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(SecurityProperties.class)
@ConditionalOnClass({ AbstractSecurityWebApplicationInitializer.class, SessionCreationPolicy.class })
public class SecurityFilterAutoConfiguration {private static final String DEFAULT_FILTER_NAME = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME;@Bean@ConditionalOnBean(name = DEFAULT_FILTER_NAME)public DelegatingFilterProxyRegistrationBean securityFilterChainRegistration(SecurityProperties securityProperties) {DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean(DEFAULT_FILTER_NAME);registration.setOrder(securityProperties.getFilter().getOrder());registration.setDispatcherTypes(getDispatcherTypes(securityProperties));return registration;}private EnumSet<DispatcherType> getDispatcherTypes(SecurityProperties securityProperties) {if (securityProperties.getFilter().getDispatcherTypes() == null) {return null;}return securityProperties.getFilter().getDispatcherTypes().stream().map((type) -> DispatcherType.valueOf(type.name())).collect(Collectors.toCollection(() -> EnumSet.noneOf(DispatcherType.class)));}}

2、主要作用

  1. 注册DelegatingFilterProxyRegistrationBean(委托过滤器代理注册Bean)
  2. 设置代理目标Bean对象名称为springSecurityFilterChain

相关文章:

一、Spring Boot集成Spring Security之自动装配

Spring Boot集成Spring Security之自动装配介绍 一、实现功能及软件版本说明二、创建Spring Boot项目三、查看自动装配配置类四、自动装配配置类之SecurityAutoConfiguration1、SecurityAutoConfiguration部分源码2、主要作用3、SpringBootWebSecurityConfiguration3.1、Spring…...

计数相关的题 Python 力扣

2284. 最多单词数的发件人 给你一个聊天记录&#xff0c;共包含 n 条信息。给你两个字符串数组 messages 和 senders &#xff0c;其中 messages[i] 是 senders[i] 发出的一条 信息 。 一条 信息 是若干用单个空格连接的 单词 &#xff0c;信息开头和结尾不会有多余空格。发件…...

Express内置的中间件(express.json和express.urlencoded)格式的请求体数据

目录 Express内置的中间件 express.json 中间件的使用 express.urlencoded 中间件的使用 express.urlencoded([options]) 解析req.body的兼容写法 Express内置的中间件 自 Express 4.16.0 版本开始&#xff0c;Express 内置了 3 个常用的中间件&#xff0c;极大的提高了 …...

cmakelist加载Qt模块

Qt编程中&#xff0c;cmakelist会自动添加Core&#xff0c;Gui&#xff0c;Widgets模块&#xff0c;有时需要添加新的Qt的模块。在命令find_package中搜索要新增的模块&#xff0c;在命令target_link_libraries中添加要新增的模块。 比如要使用QUiLoader类&#xff0c;要增加对…...

8-2.Android 任务之 CountDownTimer 编码模板(开启计时器、取消计时器)

一、CountDownTimer 1、概述 CountDownTimer 是 Android 中一个用于执行定时操作的类 CountDownTimer 主要应用于在指定时间段内完成某项任务&#xff0c;或者每隔一段时间触发某项任务 2、使用步骤 创建 CountDownTimer&#xff1a;创建 CountDownTimer 就是创建它的匿名…...

Servlet的生命周期及用户提交表单页面的实现(实验报告)

一、实验目的、要求 1. 掌握Servlet的定义&#xff0c;即Servlet是运行在服务器端的Java程序&#xff0c;用于扩展服务器的功能。 2. 学习和掌握在开发环境中搭建Servlet应用所需的工具&#xff0c;如Tomcat服务器、IDEA等。 二、实验内容 根据本章所学知识&#xff0c;实验…...

【Router】路由功能之IP过滤(IP Filter)功能(基于端口)介绍及实现

IP过滤(IP Filter) IP Filter是一种通过对网络数据包中的 IP 地址进行分析和筛选,以实现对网络流量的控制和管理的技术。 IP过滤(IP Filter)作用 安全防护 可以阻止来自特定 IP 地址或 IP 地址范围的恶意攻击、非法访问等,增强网络的安全性。 流量管理 根据不同的 IP …...

数据结构_2.2、顺序表插入删除查找

1、线性表的顺序存储表示定义&#xff1a; 线性表&#xff1a;是具有相同数据类型的n &#xff08;n≥0&#xff09;个数据元素的有限序列 顺序表&#xff1a;用顺序存储的方式实现线性表 顺序存储&#xff1a;把逻辑上相邻的元素存储在物理 位置上也相邻的存储单元中&#…...

嵌入式C语言自我修养:编译链接

源文件生成可执行文件的过程&#xff1f; 源文件经过预处理、编译、汇编、链接生成一个可执行的目标文件。 编译器驱动程序&#xff0c;包括预处理器、编译器、汇编器和链接器。Linux用户可以调用GCC驱动程序来完成整个编译流程。 使用GCC驱动程序将示例程序从ASCII码源文件转换…...

Mac制作Linux操作系统启动盘

前期准备 一个 Mac 电脑 一个 U 盘&#xff08;8GB 以上&#xff09; 下载好 Linux 系统镜像&#xff08;iso 文件&#xff09; 具体步骤 挂载 U 盘 解挂 U 盘 写系统镜像到 U 盘 完成 一、挂载 U 盘 首先插入 U 盘&#xff0c;打开终端输入下面的命令查看 U 盘是否已经 m…...

PHP语言发展历程

PHP是一种开源的服务器端脚本语言&#xff0c;主要用于Web开发&#xff0c;最初由Rasmus Lerdorf在1994年创建。PHP的发展历程如下&#xff1a; PHP的起源&#xff1a;1994年&#xff0c;Rasmus Lerdorf创建了PHP的第一个版本&#xff0c;最初是一套用于跟踪他个人简历访问的C…...

Notepad++ 之 AndroidLogger插件

背景 最近一段时间在分析Android log 定位问题&#xff0c;Notepad 之前用的比较少&#xff0c;现在看log觉得确实好用&#xff0c;美中不足的是 看Android log的时候不像 logcat -v color 可以区分不同等级的颜色&#xff0c;于是调研了一下&#xff0c;发现大部分都是使用An…...

开源2+1链动模式AI智能名片O2O商城小程序源码:线下店立体连接的超强助力器

摘要&#xff1a;本文将为您揭示线下店立体连接的重大意义&#xff0c;您知道吗&#xff1f;线上越火&#xff0c;线下就得越深入经营。现代门店可不再只是卖东西的地儿&#xff0c;还得连接KOC呢&#xff01;咱们来看看门店要做的那些超重要的事儿&#xff0c;还有开源21链动模…...

我为什么决定关闭ChatGPT的记忆功能?

你好&#xff0c;我是三桥君 几个月前&#xff0c;ChatGPT宣布即将推出一项名为“记忆功能”的新特性&#xff0c;英文名叫memory。 这个功能听起来相当吸引人&#xff0c;宣传口号是让GPT更加了解用户&#xff0c;仿佛是要为我们每个人量身打造一个专属的AI助手。 在记忆功…...

如何使用ssm实现中学生课后服务的信息管理与推荐+vue

TOC ssm766中学生课后服务的信息管理与推荐vue 第一章 绪论 1.1 选题背景 目前整个社会发展的速度&#xff0c;严重依赖于互联网&#xff0c;如果没有了互联网的存在&#xff0c;市场可能会一蹶不振&#xff0c;严重影响经济的发展水平&#xff0c;影响人们的生活质量。计算…...

【分别为微服务云原生】9分钟ActiveMQ延时消息队列:定时任务的革命与Quartz的较量

ActiveMQ延时消息队列&#xff1a;定时任务的革命与Quartz的较量 摘要&#xff1a; 在现代的消息驱动架构中&#xff0c;ActiveMQ的延迟消息队列功能为定时任务提供了一种新的解决方案。本文将详细介绍ActiveMQ延迟消息队列的功能、应用场景&#xff0c;并与Quartz定时任务进行…...

泛型编程--模板【C++提升】(特化、类属、参数包的展开、static、模板机制、重载......你想知道的全都有)

更多精彩内容..... &#x1f389;❤️播主の主页✨&#x1f618; Stark、-CSDN博客 本文所在专栏&#xff1a; C系列语法知识_Stark、的博客-CSDN博客 其它专栏&#xff1a; 数据结构与算法_Stark、的博客-CSDN博客 C系列项目实战_Stark、的博客-CSDN博客 座右铭&#xff1a;梦…...

安卓使用memtester进行内存压力测试

memteser简介 memtester 是一个用于测试内存可靠性的工具。 它可以对计算机的内存进行压力测试&#xff0c;以检测内存中的错误&#xff0c;例如位翻转、随机存取错误等。memtester 可以在不同的操作系统上运行&#xff0c;并且可以针对不同大小的内存进行测试。 下载源码 m…...

Dave Cheney: Go语言之禅

本篇内容是根据2020年3月份The Zen of Go音频录制内容的整理与翻译, Dave Cheney 讲述了 Go 之禅&#xff08;编写简单、可读、可维护的 Go 代码的十个工程价值&#xff09;。是什么让 Go 代码变得优秀&#xff1f;编写 Go 代码时&#xff0c;我们应该牢记哪些指导原则&#x…...

SpringMVC源码-AbstractUrlHandlerMapping处理器映射器将实现Controller接口的方式定义的路径存储进去

DispatcherServlet的initStrategies方法用来初始化SpringMVC的九大内置组件 initStrategies protected void initStrategies(ApplicationContext context) {// 初始化 MultipartResolver:主要用来处理文件上传.如果定义过当前类型的bean对象&#xff0c;那么直接获取&#xff0…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)

旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据&#xff01;该数据集源自2025年4月发表于《地理学报》的论文成果…...

CppCon 2015 学习:REFLECTION TECHNIQUES IN C++

关于 Reflection&#xff08;反射&#xff09; 这个概念&#xff0c;总结一下&#xff1a; Reflection&#xff08;反射&#xff09;是什么&#xff1f; 反射是对类型的自我检查能力&#xff08;Introspection&#xff09; 可以查看类的成员变量、成员函数等信息。反射允许枚…...

Python的__call__ 方法

在 Python 中&#xff0c;__call__ 是一个特殊的魔术方法&#xff08;magic method&#xff09;&#xff0c;它允许一个类的实例像函数一样被调用。当你在一个对象后面加上 () 并执行时&#xff08;例如 obj()&#xff09;&#xff0c;Python 会自动调用该对象的 __call__ 方法…...

VSCode 没有添加Windows右键菜单

关键字&#xff1a;VSCode&#xff1b;Windows右键菜单&#xff1b;注册表。 文章目录 前言一、工程环境二、配置流程1.右键文件打开2.右键文件夹打开3.右键空白处打开文件夹 三、测试总结 前言 安装 VSCode 时没有注意&#xff0c;实际使用的时候发现 VSCode 在 Windows 菜单栏…...

【Zephyr 系列 16】构建 BLE + LoRa 协同通信系统:网关转发与混合调度实战

🧠关键词:Zephyr、BLE、LoRa、混合通信、事件驱动、网关中继、低功耗调度 📌面向读者:希望将 BLE 和 LoRa 结合应用于资产追踪、环境监测、远程数据采集等场景的开发者 📊篇幅预计:5300+ 字 🧭 背景与需求 在许多 IoT 项目中,单一通信方式往往难以兼顾近场数据采集…...