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

Spring IoCDI(中)--IoC的进步

        通过上文的讲解和学习, 我们已经知道了Spring IoC 和DI的基本操作, 接下来我们来系统的学习Spring IoC和DI 的操作. 前⾯我们提到IoC控制反转,就是将对象的控制权交给Spring的IOC容器,由IOC容器创建及管理对 象,也就是bean的存储。

1. Bean的存储

        在之前的代码学习中,要把某个对象交给IOC容器管理,需要在类上添加⼀个注解: @Component ,⽽Spring框架为了更好的服务web应⽤程序, 提供了更丰富的注解. 共有两类注解类型可以实现:

        1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration.

        2. ⽅法注解:@Bean

1.1 @Controller(控制器存储)

        使⽤ @Controller 存储 bean 的代码如下所⽰:

package com.example.zxslzw2014_8_11.controller;import org.springframework.stereotype.Controller;@Controller
public class UserController1 {public void sayHi() {System.out.println("hi, UserController");}
}

        这个对象加了@Controller注解,就把这个对象放在Spring容器中了,下面是从Spring容器获取对象,代码如下: 

package com.example.zxslzw2014_8_11;import com.example.zxslzw2014_8_11.controller.UserController;
import com.example.zxslzw2014_8_11.controller.UserController1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;@SpringBootApplication
public class Zxslzw2014811Application {public static void main(String[] args) {//获取Spring的上下文ApplicationContext context = SpringApplication.run(Zxslzw2014811Application.class, args);//从Spring的上下文中获取对象UserController1 bean = (UserController1)context.getBean(UserController1.class);bean.sayHi();}}

         ApplicantContent ,即Spring 上下文。因为对象交给Spring管理了,所以获取对象要从Spring中获取,那么就得先得到Spring的上下文。

        在计算机领域,上下文这个概念,在线程那已经了解过了,比如应用进行线程切换的时候,切换前都会把线程的状态信息暂时存储起来,这里的上下文就包括了当前线程的信息,等下次该线程又得到CPU时间的时候,从上下文中拿到线程上次运行的信息

        我们当前说的上下文,就是当前的运行环境,也可以看做是一个容器,容器里存了很多内容,这些内容是当前运行的环境

        运行代码,发现成功从Spring中获取了Controller 对象,并执行Controller的sayHi方法,如图: 

         如果把UserController类上面的注解@Controller去掉,就会报错,如图:   

        报错信息:找不到类型是com.example.zxslzw2014_8_11.controller.UserController1的bean;因为没加这个注解,自然也就没声明把这个类交给Spring管理,Spring也就找不到该类的bean了。 

1.1.1 获取bean对象的其他方式

        上述代码是根据类型来查找对象的,如果Spring容器中,同一个类型存在多个bean的话,要怎么获取?

        ApplicationContext也提供了其他获取bean的方式,ApplicationContext获取bean对象的功能,是父类BeanFactory提供的功能。如下代码:

public interface BeanFactory {//以上省略...// 1. 根据bean名称获取beanObject getBean(String var1) throws BeansException;// 2. 根据bean名称和类型获取bean<T> T getBean(String var1, Class<T> var2) throws BeansException;// 3. 按bean名称和构造函数参数动态创建bean,只适⽤于具有原型(prototype)作⽤域的beanObject getBean(String var1, Object... var2) throws BeansException;// 4. 根据类型获取bean<T> T getBean(Class<T> var1) throws BeansException;// 5. 按bean类型和构造函数参数动态创建bean, 只适⽤于具有原型(prototype)作⽤域的bean<T> T getBean(Class<T> var1, Object... var2) throws BeansException;//以下省略...
}

        最常用的是1、2、4种,这三种方式(根据bean名称获取bean、根据bean类型和名称获取bean、根据bean类型获取bean),获取到的bean是一样的。

        其中1、2种都涉及到根据名称来获取对象,那么bean的名称是什么呢?

        Spring bean 是Spring框架在运行时管理的对象,Spring会给管理的对象起一个名字。所以给每个对象都起一个名字,然后根据Bean的名称(BeanId)就可以获取到对应的对象。

1.1.2 Bean 命名约定

        官方文档:Bean Overview :: Spring Framework

         程序开发人员不需要为bean指定名称(BeanId),如果没有显示的提供名称(BeanId),Spring容器将为该bean生成唯一的名称。

        命名约定:使用Java标准约定作为实例字段名。也就是bean名称以小写字母开头,然后使用驼峰式大小写。例子如下:

类名:UserController,Bean的名称为:userController

        也有一些特殊情况,当多个字符并且第一个字符和第二个字符都是大写时,将保留原始大小写。这些规则与java.beans.Introspector.decapitalize(Spring在这里使用的)定义的规则相同。例子如下:

类名:UController,Bean的名称为:UController

        根据这个命名规则,我们来获取Bean,代码如下:

package com.example.zxslzw2014_8_11;import com.example.zxslzw2014_8_11.controller.UserController;
import com.example.zxslzw2014_8_11.controller.UserController1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;@SpringBootApplication
public class Zxslzw2014811Application {public static void main(String[] args) {//获取Spring的上下文ApplicationContext context = SpringApplication.run(Zxslzw2014811Application.class, args);//从Spring的上下文中获取对象//根据bean类型,从Spring上下文中获取对象UserController1 userController1 = (UserController1)context.getBean(UserController1.class);//根据bean名称,从Spring上下文获取对象UserController1 userController2 = (UserController1) context.getBean("userController1");
//        //根据bean名称+类型,从Spring上下文获取对象UserController1 userController3 = (UserController1) context.getBean("userController1", UserController1.class);System.out.println(userController1);System.out.println(userController2);System.out.println(userController3);}
}

         运行结果如下:

         上图bean的地址都是一样的,说明对象是同一个。

ApplicationContext 和 BeanFactory (常见面试题)

1、从继承关系和功能方面来说:Spring容器有两个顶级的接口:BeanFactory 和 ApplicationContext。其中BeanFactory提供了基础的访问容器的能力,而 ApplicationContext 属于 BeanFactory 的子类,它除了继承 BeanFactory 的所有功能外,它还有自己独特的特性,还添加了对国际化支持、资源访问支持、以及事件传播等方面支持。

2、从性能方面来说:ApplicationContext是一次性加载并初始化所有Bean对象(提前加载),而 BeanFactory 是需要哪个对象了,才去加载那个对象(懒加载),因此更轻量。

1.2 @Service(服务存储)

        使用@Service存储bean的代码如下:

@Service
public class UserService {public void doService() {System.out.println("do Service...");}
}

         读取bean的代码:

@SpringBootApplication
public class SpringIoC2Application {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(SpringIoC2Application.class, args);//从Spring中获取UserService对象UserService userService = context.getBean(UserService.class);//使用对象userService.doService();}
}

        执行结果如下:

         把注解@Service删掉,会报错,如图: 

        报错原因如上所示; 

1.3 @Repository(仓库存储)

        使用@Repository存储bean代码如下:

@Repository
public class UserRepository {public void doRepository() {System.out.println("do Repository...");}
}

        读取bean的代码:

@SpringBootApplication
public class SpringIoC2Application {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(SpringIoC2Application.class, args);//从Spring中获取UserRepository对象UserRepository userRepository = context.getBean(UserRepository.class);//使用对象userRepository.doRepository();}
}

        运行结果如下:

         同样把注解@Repository去掉,会报错,原因如上所示;

1.4 @Component(组件存储)

        使用@Component存储bean的代码:

package com.example.zxslzw2014_8_11;import org.springframework.stereotype.Component;@Component
public class UserComponent {public void doComponent(){System.out.println("do component");}
}

        读取bean的代码:

@SpringBootApplication
public class SpringIoC2Application {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(SpringIoC2Application.class, args);//从Spring中获取UserComponent对象UserComponent userComponent = context.getBean(UserComponent.class);//使用对象userComponent.doComponent();}
}

        运行结果如下:

        如果把注释@Component去掉,报错和上面的一样

1.5 @Configuration(配置存储)

        使用@Configuration存储bean的代码如下:

package com.example.zxslzw2014_8_11;import org.springframework.context.annotation.Configuration;@Configuration
public class UserConfiguration {public void doConfiguration() {System.out.println("do Configuration...");}
}

        读取bean的代码:

@SpringBootApplication
public class SpringIoC2Application {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(SpringIoC2Application.class, args);//从Spring中获取UserComponent对象UserConfiguration userConfiguration = context.getBean(UserConfiguration.class);//使用对象userConfiguration.doConfiguration();}
}

        运行结果如下,如果取消Configuration,那么就会报错,报错信息如上所示:

2. 类注解的说明

2.1 为什么有这么多的注解

        这么多的注解和前面的应用分层是对应的,程序员看到这些类注解后,就能直接了解当前类的用途。

@Controller:控制层,接收请求,对请求进行处理,并进行响应。

@Service:业务逻辑层,处理具体的业务逻辑。

@Repository:数据访问层,也称为持久层。负责数据访问操作

@Configuration:配置层,户处理项目中的一些配置信息。

        和三层架构的对应关系:@Controller 对应 表现层,@Service 对应 业务逻辑层,@Repository 对应 数据层。

        程序的应用分层,调用流程如下:

2.2 类注解之间的关系

        查看@Controller、@Service 、@Repository、@Configuration注解的源码我们发现,它们里面都有一个@Component注解。

          这也能说明它们本身就是属于 @Component 的 “子类”。而@Component是一个元注解,也就是说可以注解其他类的注解,如 @Controller、@Service、@Repository 等等,这些注解则被称为 @Component的衍生注解。

        @Controller、@Service 和 @Repository 用于更具体的用例(分别为控制层、业务逻辑层、数据访问层),在开发过程中,如果你要在业务逻辑层使用@Component或者@Service,显然@Service是更好的选择。

3. 方法注解 @Bean

        类注解是添加到某个类上的,但是存在两个问题:1、使用外部包里的类,没办法添加类注解。2、一个类,需要多个对象,比如多个数据源。这些场景,我们就需要使用方法注解:@Bean

        以下是方法注解@Bean使用的代码:

public class BeanConfig {@Beanpublic UserInfo userInfo() {UserInfo user = new UserInfo();user.setId(6);user.setName("shenmengyao");user.setAge(18);return user;}
}

        读取bean的代码:

@SpringBootApplication
public class SpringIoC2Application {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(SpringIoC2Application.class, args);//从Spring中获取对象UserInfo userInfo = context.getBean(UserInfo.class);//使用对象System.out.println(userInfo);}
}

        我们发现如下所示的报错信息:

         报错原因就是方法注解要搭配类注解使用,上面却没有搭配。因为Spring Boot项目会引入非常多的依赖,里面的代码的方法也会有很多注解,如果都进行扫描,那就太耗时了,不如搭配类注解,Spring就知道从哪些类中扫描,大大的提高了性能。

3.1 方法注解要配合类注解使用

        在Spring框架的设计中,方法注解 @Bean 要配合类注解才能将对象正常的存储到Spring容器中,在之前的代码的类名前面加上@component注解:

package com.example.zxslzw2014_8_11;import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component
public class BeanConfig {@Beanpublic UserInfo userInfo() {UserInfo user = new UserInfo();user.setId(6);user.setName("shenmengyao");user.setAge(18);return user;}
}

        运行结果如下:

 3.2 定义多个对象

        对于同一个类,定义多个对象(多个方法使用@Bean注解);比如多数据源的场景,类是同一个,但配置是不同的,指向不同的数据源。

package com.example.zxslzw2014_8_11;import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component
public class BeanConfig {@Beanpublic UserInfo userInfo() {UserInfo user = new UserInfo();user.setId(6);user.setName("shenmengyao");user.setAge(18);return user;}@Beanpublic UserInfo userInfo1() {UserInfo user = new UserInfo();user.setId(7);user.setName("yuanyiqi");user.setAge(19);return user;}}

        定义多个对象的话,我们根据类型获取对象,获取的是哪个对象呢?代码和上面之前的一样,不变,运行代码结果如下:

         可以看到,报错信息显示:期望只有一个匹配,结果发现两个:userInfo,userInfo1。从报错信息中,可以看出来,@Bean注解的bean,bean的名称就是它的方法名

        我们现在改一下代码,根据名称来获取bean对象,代码如下:

@SpringBootApplication
public class SpringIoC2Application {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(SpringIoC2Application.class, args);//从Spring中获取对象UserInfo userInfo = (UserInfo) context.getBean("userInfo");UserInfo userInfo1 = (UserInfo) context.getBean("userInfo1");//使用对象System.out.println(userInfo);System.out.println(userInfo1);}
}

        运行结果如下,可以看到,@Bean可以针对同一个类,定义多个对象。 

 

3.3 重命名 Bean

        可以通过设置 name 属性,给Bean对象进行重命名操作,代码如下:

package com.example.zxslzw2014_8_11;import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component
public class BeanConfig {@Bean(name = {"u1", "userInfo"})public UserInfo userInfo() {UserInfo user = new UserInfo();user.setId(6);user.setName("shenmengyao");user.setAge(18);return user;}
}

          此时使用 u1 就可以获取到User对象了,代码如下:

@SpringBootApplication
public class SpringIoC2Application {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(SpringIoC2Application.class, args);//从Spring上下文中获取对象UserInfo u1 = (UserInfo)context.getBean("u1");//使用对象System.out.println(u1);}
}

         运行结果如下:

        使用 useInfo1 也可以获取到User对象,两个字符串都是对UserInfo的重命名,代码和结果如下:

@SpringBootApplication
public class SpringIoC2Application {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(SpringIoC2Application.class, args);//从Spring上下文中获取对象UserInfo userinfo = (UserInfo)context.getBean("userInfo1");//使用对象System.out.println(userinfo );}
}

 

        上面中同样的输出结果,但是关于@bean注解我们也可以修改成为以下的代码:

        如上图所示,@Bean中的name也可以省略;只有一个名称时,{ } 也可以省略;

4. 扫描路径

        我们来思考只要搭配了五大注解或者五大注解+Bean,Spring就能启动成功吗?

        其实不然,主要是扫描路径的问题,Spring只会默认对启动类所在的目录下进行扫描,并且扫描的是搭配了五大注解的类或者搭配五大注解+Bean的类

        启动类:加了 @SpringBootApplication 注解的类

        现在测试一下,把启动类移动一下,获取到UserService对象,我们发现如下报错信息:

        报错解释:没有bean的类型是UserService的。

        这里为什么没有找到bean对象,主要是因为即使使用了五大注解,或者五大注解 + @Bean注解,要想生效,还需要配置扫描路径,让Spring扫描到这些注解下的类,也就是通过 @ComponentScan 来配置。加了 @ComponentScan注解 的代码如下:

package com.example.zxslzw2014_8_11.service;import com.example.zxslzw2014_8_11.UserInfo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;@ComponentScan({"com.example.zxslzw2014_8_11"})
@SpringBootApplication
public class Zxslzw2014811Application {public static void main(String[] args) {//获取Spring的上下文ApplicationContext context = SpringApplication.run(Zxslzw2014811Application.class, args);//从Spring的上下文中获取对象UserInfo userInfo = (UserInfo)context.getBean("userInfo");//使用对象System.out.println(userInfo);}
}

        其中注解@ComponentScan的括号里面,加的是BeanConfig类的包路径,直接复制即可,在Service类里面,  执行结果如下:

        如此可以拿到bean对象,其中注解@ComponentScan括号里的 { } ,可以加多个大括号,表示扫描多个路径,如图:

        一般来说, 默认扫描的范围是:SpringBoot启动类所在包及其子包;在配置类添加 @ComponentScan注解,该注解默认会扫描该类所在的包下所有的配置类,如图: 

        故此,一般我们把启动类放在我们希望扫描的包的路径下,这样我们自己写的代码就都可以被扫描到了,

ps:本次的内容就到这里了,如果对你有所帮助的话,就请一键三连哦!!!

本文的封面来自:bilibili苏杉杉的pv,侵权删 url:https://www.bilibili.com/video/BV1vo4y167eh/?spm_id_from=333.999.0.0&vd_source=866da5be2ef0ddd213b053523da53138
————————————————

电子签名:上嘉路

相关文章:

Spring IoCDI(中)--IoC的进步

通过上文的讲解和学习, 我们已经知道了Spring IoC 和DI的基本操作, 接下来我们来系统的学习Spring IoC和DI 的操作. 前⾯我们提到IoC控制反转&#xff0c;就是将对象的控制权交给Spring的IOC容器&#xff0c;由IOC容器创建及管理对 象&#xff0c;也就是bean的存储。 1. Bean的…...

读软件开发安全之道:概念、设计与实施02经典原则

1. CIA原则 1.1. 软件安全都构建在信息安全的三大基本原则之上&#xff0c;即机密性(confidentiality)、完整性(integrity)和可用性(availability) 1.2. 双方交换的数据 1.2.1. 从技术上看&#xff0c;端点之间的数据交换本身就会削弱交互的机密性 1.2.2. 隐藏通信数据量的一…...

MySQL中处理JSON数据:大数据分析的新方向,详解与示例

文章目录 1. MySQL中的JSON数据类型2. JSON函数和运算符3. 创建JSON列的表4. 插入JSON数据5. 查询JSON数据6. 复杂查询和聚合7. JSON 数据的索引8. 总结 在当今的大数据时代&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;作为一种轻量级的数据交换格式&a…...

【图形学】TA之路-矩阵

在 Unity 中&#xff0c;矩阵广泛用于处理各种图形变换&#xff0c;例如平移、旋转、缩放等。矩阵的使用不仅限于三维空间&#xff0c;还可以应用于二维空间的操作。了解矩阵及其运算对于游戏开发和计算机图形学非常重要。Unity 中使用的是行向量不是列向量&#xff0c;这个要注…...

LAMM: Label Alignment for Multi-Modal Prompt Learning

系列论文研读目录 文章目录 系列论文研读目录文章题目含义AbstractIntroductionRelated WorkVision Language ModelsPrompt Learning MethodologyPreliminaries of CLIPLabel AlignmentHierarchical Loss 分层损失Parameter Space 参数空间Feature Space 特征空间Logits Space …...

mac编译opencv 通用架构库的记录

1,通用架构 (x86_64;arm64&#xff09;要设置的配置项&#xff1a; CPU_BASELINE CPU_DISPATCH 上面这两个我设置成SSE_3&#xff0c;其他选项未尝试&#xff0c;比如不设置。 CMAKE_OSX_ARCHITECTURES:x86_64;arm64 WITH_IPP:不勾选 2,contrib库的添加&#xff1a; 第一次…...

Python 向IP地址发送字符串

Python 向IP地址发送字符串 在网络编程中&#xff0c;使得不同设备间能够进行数据传输是一项基本任务。Python提供了强大的库&#xff0c;帮助开发者轻松地实现这种通信。本文将介绍如何使用Python通过UDP协议向特定的IP地址发送字符串信息。 UDP协议简介 UDP&#xff08;用…...

上升响应式Web设计:纯HTML和CSS的实现技巧-1

响应式Web设计&#xff08;Responsive Web Design, RWD&#xff09;是一种旨在确保网站在不同设备和屏幕尺寸下都能良好运行的网页设计策略。通过纯HTML和CSS实现响应式设计&#xff0c;主要依赖于媒体查询&#xff08;Media Queries&#xff09;、灵活的布局、可伸缩的图片和字…...

利用java结合python实现gis在线绘图,主要技术java+python+matlab+idw+Kriging

主要技术javapythonmatlabidwKriging** GIS中的等值面和等高线绘图主要用于表达连续空间数据的分布情况&#xff0c;特别适用于需要展示三维空间中某个变量随位置变化的应用场景。 具体来说&#xff0c;以下是一些适合使用GIS等值面和等高线绘图的场景&#xff1a; 地形与地貌…...

Android全面解析之context机制(三): 从源码角度分析context创建流程(下)

前言 前面已经讲了什么是context以及从源码角度分析context创建流程&#xff08;上&#xff09;。限于篇幅把四大组件中的广播和内容提供器的context获取流程放在了这篇文章。广播和内容提供器并不是context家族里的一员&#xff0c;所以他们本身并不是context&#xff0c;因而…...

执行docker compose命令出现 Additional property include is not allowed

问题背景 在由docker-compose.yml的文件目录下执行命令 docker compose up -d 出现错误 Additional ininoperty include is not allowed 原因 我的docker-compose.yml 文件中出现了include标签旧版本的docker-compose 不支持此标签 解决办法 下载支持的docker-compose 解决…...

STM32通过I2C硬件读写MPU6050

目录 STM32通过I2C硬件读写MPU6050 1. STM32的I2C外设简介 2. STM32的I2C基本框图 3. STIM32硬件I2C主机发送流程 10位地址与7位地址的区别 7位主机发送的时序流程 7位主机接收的时序流程 4. STM32硬件与软件的波形对比 5. STM32配置硬件I2C外设流程 6. STM32的I2C.h…...

ubuntu2204-中文输入法-pycharm-python-django开发环境搭建

文章目录 1.系统常用设置1.1.安装中文输入法1.2.配置输入法1.3.卸载输入法1.4.配置镜像源2.java安装3.pycharm安装与启动4.卸载ubuntu2204默认版本5.安装Anaconda5.1.安装软件依赖包5.2.安装命令5.3.激活安装5.4.常用命令5.5.修改默认启动源6.安装mysql6.1.离线安装mysql6.2.在…...

【学习笔记】Matlab和python双语言的学习(一元线性回归)

文章目录 前言一、一元线性回归回归分析的一般步骤一元线性回归的基本形式回归方程参数的最小二乘法估计对回归方程的各种检验估计标准误差的计算回归直线的拟合优度判定系数显著性检验 二、示例三、代码实现----Matlab四、代码实现----python回归系数的置信区间公式残差的置信…...

LeetCode //C - 316. Remove Duplicate Letters

316. Remove Duplicate Letters Given a string s, remove duplicate letters so that every letter appears once and only once. You must make sure your result is the smallest in lexicographical order among all possible results. Example 1: Input: s “bcabc”…...

【ARM+Codesys 客户案例 】RK3568/A40i/STM32+CODESYS在工厂自动化中的应用:PCB板焊接机

现代化生产中&#xff0c;电子元件通常会使用自动化设备来进行生产&#xff0c;例如像PCB&#xff08;印刷电路板&#xff09;的组装。但是生产过程中也会面临一些问题&#xff0c;类似于如何解决在PCB板上牢固、精准地安装各种组件呢&#xff1f;IBL Lttechnik GmbH公司的CM80…...

【二分查找】--- 初阶题目赏析

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; 算法Joureny 上篇我们讲解了关于二分的朴素模板和边界模板&#xff0c;本篇博客我们试着运用这些模板。 &#x1f3e0; 搜索插入位置 &#x1f4cc; 题目…...

【PostgreSQL003】PostgreSQL数据表空间膨胀,磁盘爆满,应用宕机(经验总结,已更新)

1.一直以来想写下基于PostgreSQL的系列文章&#xff0c;作为较火的数据ETL工具&#xff0c;也是日常项目开发中常用的一款工具&#xff0c;最近刚好挤时间梳理、总结下这块儿的知识体系。 2.熟悉、梳理、总结下PostgreSQL数据库相关知识体系。空间膨胀&#xff08;主键、外键、…...

C语言第20天笔记

文件操作 概述 什么是 文件 文件时保存在外存储器上&#xff08;一般代指磁盘&#xff0c;也可以是U盘、移动硬盘等&#xff09;的数据的集合。 文件操作体现在哪几个方面 1. 文件内容的读取 2. 文件内容的写入 数据的读取和写入可被视为针对文件进行输入和输出的操作&a…...

为什么穷大方

为什么有些人明明很穷&#xff0c;却非常的大方呢&#xff1f; 因为他们认知太低&#xff0c;根本不懂钱的重要性&#xff0c;总是想着及时享乐&#xff0c;所以一年到头也存不了什么钱。等到家人孩子需要用钱的时候&#xff0c;什么也拿不出来&#xff0c;还到处去求人。 而真…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...