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

SpringBoot Bean管理

我们知道可以通过Spring当中提供的注解@Component以及它的三个衍生注解(@Controller、@Service、@Repository)来声明IOC容器中的bean对象,同时我们也学习了如何为应用程序注入运行时所需要依赖的bean对象,也就是依赖注入DI。

本篇主要介绍IOC容器中Bean的使用细节:

  • 如何从IOC容器中手动的获取到bean对象

  • bean的作用域

  • 管理第三方的bean对象(重点)

1、如何从IOC容器中手动的获取到bean对象

获取Bean

默认情况下,SpringBoot项目在启动的时候会自动的创建IOC容器(也称为Spring容器),并且在启动的过程当中会自动的将bean对象都创建好,存放在IOC容器当中。应用程序在运行时需要依赖什么bean对象,就直接进行依赖注入就可以了。

而在Spring容器中提供了一些方法,可以主动从IOC容器中获取到bean对象,下面介绍3种常用方式:

1)根据name获取bean

Object getBean(String name)

2)根据类型获取bean

<T> T getBean(Class<T> requiredType)

3)根据name获取bean(带类型转换)

<T> T getBean(String name, Class<T> requiredType)

思考:要从 IOC容器 当中来获取到 bean对象,需要 先拿到 IOC容器对象,怎么样才能拿到IOC容器呢?

想获取到IOC容器,直接将 IOC容器对象 注入进来就可以了,java中万物皆对象。

  • step1: 创建 bean 容器

Mapper接口:‍

@Mapper
public interface UserMapper {//查询所有门派@Select("select * from sects")List<Sect> selectAll();
}

业务实现类:


@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper  userMapper ;@Overridepublic List<Sect> getAllSects() {List<Sect> sects =  sectsMapper.selectAll();return sects;}
}

控制器:

@RestController
@Slf4j
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/get/all")public Result getAll() {List<Sect> sects = sectsService.getAllSects();return Result.success(sects);}
}
  • step2: 获取 Bean 容器

测试类:

import org.springframework.context.ApplicationContext;@SpringBootTest
class TianlongManagementApplicationTests {@Autowiredprivate ApplicationContext applicationContext;@Testpublic void testGetBean() {//根据bean的名称获取SectsController bean1 = (UserController) applicationContext.getBean("userController");System.out.println(bean1);//根据bean的类型获取SectsController bean2 = applicationContext.getBean(UserController.class);System.out.println(bean2);//根据bean的名称及类型获取SectsController bean3 = applicationContext.getBean("userController", UserController.class);System.out.println(bean3);}
}

输出的bean对象地址值一样,说明在IOC容器中SectsController这个bean是 单例的。那能否将bean对象设置为非单例?

说到这,笔者之前想过一个问题,为什么在SpringBoot项目中,都是Controller类、ServiceImpl实现类和Mapper接口需要添加@Componet及其衍生注解,而我们写的POJO实现类却不用添加?POJO也是一个一个的类,在项目里也需要创建对象,为什么这些POJO对象不需要添加到IOC容器来管理呢?(如下图Sects这个实现类并没有添加@Component注解)

谈一下我的拙见,首先需要知道为啥Spring框架IOC控制反转很重要,因为通过这个可以实现Controller、Service、DAO三层的解耦,大白话就是当Controller需要用ServiceImpl对象,就不用new的方式创建,而是直接通过DI依赖注入从IOC容器中拿对象。

明白了上面这一点,我们想想为啥POJO实现类和一些工具类不用加入IOC容器?

  • 原因一:普通的POJO类、工具类通常是不涉及业务逻辑的辅助功能,不涉及复杂的依赖关系和配置,因此不需要被IOC容器管理;

  • 原因二:Controller、Service和Mapper这三层主要是处理业务,而普通的POJO类一般用于封装数据,封装数据意味着每次封装的数据可能不同,也就是每次对象不同,交给IOC容器管理反而更复杂。

2、bean的作用域

在前面我们提到的IOC容器当中,默认bean对象是单例模式(只有一个实例对象)。那么如何设置bean对象为非单例呢?需要设置bean的作用域。

在Spring中支持五种作用域,后三种在web环境才生效:

作用域说明
singleton容器内同名称的bean只有一个实例(单例)(默认)
prototype每次使用该bean时会创建新的实例(非单例)
request每个请求范围内会创建新的实例(web环境中,了解)
session每个会话范围内会创建新的实例(web环境中,了解)
application每个应用范围内会创建新的实例(web环境中,了解)

可以借助Spring中的@Scope注解来配置作用域:
在这里插入图片描述

再次运行后控制台日志显示 UserController这个bean就生成了多份,不过实际开发中,绝大多数bean都是单例的,也就是不用配置scope属性。
在这里插入图片描述

除此之外,Spring还提供了一个注解:@Lazy,用于延迟加载,意思是当第一次使用bean对象时,才会创建bean对象并交给ioc容器管理。

3、管理第三方的bean对象(重点)

前面所配置的bean,像controller、service,dao三层体系下编写的类,这些类都是我们在项目当中自己定义的类(自定义类)。当我们要声明这些bean,也非常简单,我们只需要在类上加上@Component以及它的这三个衍生注解(@Controller、@Service、@Repository),就可以来声明这个bean对象了。
但是在我们项目开发当中,还有一种情况就是这个类它不是我们自己编写的,而是我们引入的 第三方依赖 当中提供的。

在pom.xml文件中,引入dom4j:

<!--Dom4j-->
<dependency><groupId>org.dom4j</groupId><artifactId>dom4j</artifactId><version>2.1.3</version>
</dependency>

dom4j就是第三方组织提供的。dom4j中的SAXReader类就是第三方编写的。

当我们需要使用到SAXReader对象时,直接进行依赖注入是不是就可以了呢?

按照我们之前的做法,需要在SAXReader类上添加一个注解@Component(将当前类交给IOC容器管理),如下:
在这里插入图片描述
注意看,第三方提供的类是 只读的,无法在第三方类上添加@Component注解或衍生注解。

那应该怎样定义并使用第三方的bean对象呢?

Spring框架又提供了一个注解 @Bean,可以用来管理来第三方(不是自定义的)容器。

方法一: 在引导类/启动类上添加@Bean标识的方法 (不推荐,抛砖引玉)


@SpringBootApplication
public class SpringbootWebConfig2Application {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfig2Application.class, args);}//声明第三方bean@Bean //将当前方法的返回值对象交给IOC容器管理, 成为IOC容器beanpublic SAXReader saxReader(){return new SAXReader();}
}

测试xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<emp><name>Tom</name><age>18</age>
</emp>

测试类:


@SpringBootTest
class SpringbootWebConfig2ApplicationTests {@Autowiredprivate SAXReader saxReader;//第三方bean的管理@Testpublic void testThirdBean() throws Exception {Document document = saxReader.read(this.getClass().getClassLoader().getResource("1.xml"));Element rootElement = document.getRootElement();String name = rootElement.element("name").getText();String age = rootElement.element("age").getText();System.out.println(name + " : " + age);}
}

运行测试方法,程序可以正常运行并解析xml数据,说明SAXReader类的对象被成功注入进来了。

Tom : 18

方法二: 在配置类中定义@Bean标识的方法 (推荐)

以上在启动类中声明第三方Bean的作法,不建议使用,项目中要保证启动类的 纯粹性

  • 创建配置类:CommonConfig
package com.nvyao.conf;import com.nvyao.pojo.Dept;
import com.nvyao.service.DeptService;
import org.dom4j.io.SAXReader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.List;@Configuration  //配置类
public class CommonConfig {//声明第三方Bean,一般情况下专门定一个配置类来声名第三方bean对象//加了这个注解,spring框架会自动调用这个方法,并且将方法返回值交给IOC容器管理,成为IOC容器的bean对象//通过@Bean注解的name或value属性可以声明Bean的名称,如果不指定,默认bean的名称就是方法名@Bean//("reader")public SAXReader saxReader() {return new SAXReader();}
}

去除之前启动类的@Bean方法,重启依然有效。

假如第三方Bean在使用过程还需要使用其他Bean,也就是还需要依赖其他对象,可以直接通过在@Bean注解的这个方法添加需要依赖的对象的形参来解决,如下:


@Configuration  //配置类
public class CommonConfig {@Beanpublic SAXReader saxReader(DeptService deptService) {System.out.println(deptService);List<Dept> deptList = deptService.listDept();System.out.println(deptList);return new SAXReader();}
}


可以断点调试看到,形参的对象已经注入进来了,真挺好!
在这里插入图片描述

总结一下:

1)SpringBoot的启动类也是一个配置类,理论上声明第三方Bean的方法可以放在启动类,但一般是单独定义一个配置类

2)加了@Bean注解,Spring框架会自动调用@Bean注解的方法,并且将方法返回值交给IOC容器管理,成为IOC容器的bean对象

3)通过@Bean注解的name或value属性可以声明Bean的名称,如果不指定,默认bean的名称就是方法名

4)如果第三方Bean需要依赖其他bean对象,直接在bean定义方法中设置行参即可,容器会根据类型自动装配

4、bean 三种注入方式

属性注入

属性注入目前最 常用的注入方式,使用@Autowired注解实现。
在类的属性上添加@Autowired注解,Spring会自动注入对应的Bean对象。
需要注意的是,属性注入可能会导致Bean状态的不完整性,因为它们是在构造函数后才被注入的,因此可能会出现空指针异常等问题。

适用于 类容器

  • Bean 容器
package com.xuzhongkj.components;import com.xuzhongkj.po.Users;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component
public class WttFunBeanTest {@Bean(name = "aaa")public String aaa() {return "aaaaaaaaaaa";}@Bean(name = "bbb")public Users bb22b() {return new Users(1, "wtt");}public String Hi() {return "Hi";}
}
  • 属性注入
package com.xuzhongkj.controller;import com.xuzhongkj.components.WttFunBeanTest;
import com.xuzhongkj.po.Users;
import com.xuzhongkj.service.NewsService;
import com.xuzhongkj.service.impl.NewsServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
public class WttTest {@Autowiredprivate WttFunBeanTest wttFunBeanTest;@GetMapping("/wtt1")public int a1() {System.out.println(wttFunBeanTest.Hi());return 0;}
}

构造函数注入

构造函数注入是一种类型安全、清晰明了的方式,可以保证Bean的完整性。
在类中定义一个构造函数,并在其参数列表中声明需要注入的Bean对象。Spring会在初始化Bean的时候,自动将对应的Bean对象传入。

适用于 方法容器

package com.xuzhongkj.controller;import com.xuzhongkj.components.WttFunBeanTest;
import com.xuzhongkj.po.Users;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
public class WttTest {private Users users;private String aaa2;// 注意: 这里 一定要使用 要注入的 bean 名称 为 形参的参数名public WttTest(Users bbb,String aaa) {this.users = bbb;this.aaa2 = aaa;}@GetMapping("/wtt1")public int a1() {System.out.println(users);System.out.println(aaa2);return 0;}
}
  • 上述代码的 简化版,也叫 @AllArgsConstructor 注解版
package com.xuzhongkj.controller;import com.xuzhongkj.components.WttFunBeanTest;
import com.xuzhongkj.po.Users;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
@AllArgsConstructor
public class WttTest {// 注意: 这里 一定要使用 要注入的 bean 名称 为 属性 的参数名private Users bbb;private String aaa;@GetMapping("/wtt1")public int a1() {System.out.println(bbb);System.out.println(aaa);return 0;}
}

方法注入

方法注入是一种灵活的注入方式,在类中定义一个方法,并在其参数列表中声明需要注入的Bean对象。
使用@Autowired注解标记该方法,Spring会在初始化Bean的时候,自动调用该方法并传入对应的Bean对象。

适用于 方法、类 容器 的 再封装 容器

  • 在 service 层 使用 方法注入:
package com.xuzhongkj.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuzhongkj.dao.NewsMapper;
import com.xuzhongkj.po.News;
import com.xuzhongkj.po.Users;
import com.xuzhongkj.service.NewsService;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
@Data
public class NewsServiceImpl extends ServiceImpl<NewsMapper, News> implements NewsService {private Users bbb;private String aaa;// 注意: 这里 一定要使用 要注入的 bean 名称 为 形参的参数名@Autowiredpublic void aaa(Users bbb, String aaa) {this.bbb = bbb;this.aaa = aaa;}
}
  • 在 controller层,验证 是否注入成功
package com.xuzhongkj.controller;import com.xuzhongkj.components.WttFunBeanTest;
import com.xuzhongkj.po.Users;
import com.xuzhongkj.service.NewsService;
import com.xuzhongkj.service.impl.NewsServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
public class WttTest {@Autowiredprivate NewsServiceImpl newsServiceImpl;@GetMapping("/wtt1")public int a1() {System.out.println(newsServiceImpl.getAaa());System.out.println(newsServiceImpl.getBbb());return 0;}
}

好文分享, 一起加油!

相关文章:

SpringBoot Bean管理

我们知道可以通过Spring当中提供的注解Component以及它的三个衍生注解&#xff08;Controller、Service、Repository&#xff09;来声明IOC容器中的bean对象&#xff0c;同时我们也学习了如何为应用程序注入运行时所需要依赖的bean对象&#xff0c;也就是依赖注入DI。 本篇主要…...

Qt5.12.2安装教程

文章目录 文章介绍下载连接安装教程 文章介绍 安装Qt5.12.2 下载连接 点击官网下载 安装包下载完毕 安装教程 点开设置&#xff0c;添加临时储存库&#xff0c;复制连接“https://download.qt.io/online/qtsdkrepository/windows_x86/root/qt/” 点击测试&#xff0…...

2024年大数据高频面试题(中篇)

文章目录 Kafka为什么要用消息队列为什么选择了kafkakafka的组件与作用(架构)kafka为什么要分区Kafka生产者分区策略kafka的数据可靠性怎么保证ack应答机制(可问:造成数据重复和丢失的相关问题)副本数据同步策略ISRkafka的副本机制kafka的消费分区分配策略Range分区分配策略…...

Python编程工具PyCharm和Jupyter Notebook的使用差异

在编写Python程序时需要用到相应的编程工具&#xff0c;PyCharm和Jupyter Notebook是最常用2款软件。 PyCharm是很强大的综合编程软件&#xff0c;代码提示、代码自动补全、语法检验、文本彩色显示等对于新手来说实在太方便了&#xff0c;但在做数据分析时发现不太方便&#xf…...

顶顶通呼叫中心中间件-被叫路由、目的地绑定(mod_cti基于FreeSWITCH)

顶顶通呼叫中心中间件-被叫路由、目的地绑定(mod_cti基于FreeSWITCH) 1、配置分机 点击分机 -> 找到你需要设置的分机 ->呼叫路由设置为external&#xff0c;这里需要设置的分机是呼叫的并不是坐席的分机呼叫路由 2、配置拨号方案 点击拨号方案 -> 输入目的地绑定 …...

【数据集处理工具】根据COCO数据集的json标注文件实现训练与图像的文件划分

根据COCO数据集的json标注文件实现训练与图像的文件划分 一、适用场景&#xff1a;二、COCO数据集简介&#xff1a;三、场景细化&#xff1a;四、代码优势&#xff1a;五、代码 一、适用场景&#xff1a; 适用于一个常见的计算机视觉项目应用场景&#xff0c;特别是当涉及到使…...

vue 如何做一个动态的 BreadCrumb 组件,el-breadcrumb ElementUI

vue 如何做一个动态的 BreadCrumb 组件 el-breadcrumb ElementUI 一、ElementUI 中的 BreadCrumb 定义 elementUI 中的 Breadcrumb 组件是这样定义的 <template><el-breadcrumb separator"/"><el-breadcrumb-item :to"{ path: / }">主…...

FFmpeg播放视频

VS2017+FFmpeg6.2.r113110+SDL2.30.5 1.下载 ShiftMediaProject/FFmpeg 2.下载SDL2 3.新建VC++控制台应用 3.配置include和lib 4.把FFmpeg和SDL的dll 复制到工程Debug目录下,并设置调试命令...

重叠区间的求和

#摘抄 GetGeneLength/src/GetGeneLength/GetGeneLength.py at main PoShine/GetGeneLength GitHub def main(): """ Extract gene length based on featureCount calculation gene nonredundant exon length method. """ # 引…...

java包装类 及其缓存

Java 包装类&#xff08;Wrapper Class&#xff09;是将基本数据类型转换为对象的方式&#xff0c;每个基本数据类型在 java.lang 包中都有一个相应的包装类&#xff1a; Boolean 对应基本类型 boolean Character 对应基本类型 char Integer 对应基本类型 int Float 对应基本…...

大龄程序员的出路在哪里?

对于许多资深程序员而言&#xff0c;年龄并非职业发展的桎梏&#xff0c;反而如同陈年的美酒&#xff0c;随着时间的流逝愈发醇厚。他们手握的是丰富的经验和不断进阶的技能&#xff0c;而这些都为他们打开了职业发展的无数扇大门。让我们一同探索这些令人心动的可能性吧&#…...

Unity不用脚本实现点击按钮让另外一个物体隐藏

1.首先在场景中创建一个按钮和一个其他随便什么东西 2.点击按钮中的这个加号 3.然后将刚刚你创建的物体拖到这里来 4.然后依次点击下面这些给按钮绑定事件 5.运行游戏并点击按钮&#xff0c;就会发现拖进来的物体消失了 总结&#xff1a;如果按钮的功能单一&#xff0c;可以使用…...

RAG技术-为自然语言处理注入新动力

引言&#xff1a; 在自然语言处理&#xff08;NLP&#xff09;的领域中&#xff0c;RAG&#xff08;Retrieval-Augmented Generation&#xff09;技术以其独特的方式&#xff0c;正在改变我们与机器的交互方式。RAG技术结合了大语言模型的强大能力&#xff0c;使得机器在理解和…...

Docker安装ELK(简易版)

1、下载ELK镜像&#xff1a;打开终端&#xff0c;并执行以下命令以下载Elasticsearch、Logstash和Kibana的Docker镜像。您也可以根据需要选择其他版本&#xff1a; docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.6 docker pull docker.elastic.co/logstash…...

WPF项目实战视频《一》(主要为WPF基础知识)

1.WPF布局&#xff1a; Grid&#xff0c;stackPanel&#xff0c;wrapPanel&#xff0c;DockPanel&#xff0c;UniformGrid Grid 按行列布局&#xff0c; Grid.ColumnDefinitions列&#xff0c;Grid.RowDefinitions行 Grid.Row“0” Grid.Column“0” stackPanel 默认从上往下排…...

iOS ------ ARC的工作原理

一&#xff0c;ARC的概念 ARC (Automatic Reference Counting&#xff0c;自动引用计数) 是苹果公司在其编程语言&#xff08;如 Objective-C 和 Swift&#xff09;中的内存管理机制。ARC 通过编译器插入的代码自动管理对象的内存生命周期&#xff0c;减少了手动内存管理的复杂…...

【React】JSX基础

一、简介 JSX是JavaScript XML的缩写&#xff0c;它是一种在JavaScript代码中编写类似HTML模板的结构的方法。JSX是React框架中构建用户界面&#xff08;UI&#xff09;的核心方式之一。 1.什么是JSX JSX允许开发者使用类似HTML的声明式模板来构建组件。它结合了HTML的直观性…...

1分钟带你了解苹果手机删除照片恢复全过程

在日常使用苹果手机时&#xff0c;我们可能会不小心删除掉一些重要的照片&#xff0c;这让人非常烦恼。那么苹果手机怎么恢复删除的照片&#xff1f;下面小编将会向大家介绍苹果手机恢复删除的照片的方法&#xff0c;帮助大家轻松找回你丢失的照片。 一、利用“最近删除”文件夹…...

Ruby爬虫技术:深度解析Zhihu网页结构

在互联网时代&#xff0c;数据的价值日益凸显&#xff0c;尤其是在社交媒体和问答平台如Zhihu&#xff08;知乎&#xff09;上&#xff0c;用户生成的内容蕴含着丰富的信息和洞察。本文将深入探讨如何使用Ruby爬虫技术来解析Zhihu的网页结构&#xff0c;并获取有价值的数据。 …...

python中的re模块--正则表达式

正则表达式&#xff0c;又称规则表达式。&#xff08;英语&#xff1a;Regular Expression&#xff0c;在代码中常简写为regex、regexp或RE&#xff09;&#xff0c;计算机科 学的一个概念。正则表达式通常被用来检索、替换那些符合某个模 式(规则)的文本 re模块作用 通过使用…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...