认识Spring 中的BeanPostProcessor

关于BeanPostProcessor和BeanFactoryPostProcessors,将分2篇文章来写,这篇文章是对Spring 中BeanPostProcessor进行了总结

先看下大模型对这个类的介绍,随后再看下这两个类的示例,最后看下这两个类的实现。
这两个类从名字看都很类似,见名知意:BeanPostProcessor=Bean后置处理器,BeanFactoryPostProcessors=BeanFactory后置处理器

BeanPostProcessor

在Spring 5.3中,BeanPostProcessor是一个强大的接口,它允许开发者在Spring容器中的bean实例化、配置和初始化前后添加自定义的逻辑处理。以下是关于BeanPostProcessor的详细解释:1. 作用阶段
BeanPostProcessor在Spring容器完成bean的实例化、配置和其他的初始化前后工作。它提供了两个方法,一个在初始化方法之前执行,另一个在初始化方法之后执行。
2. 主要方法
postProcessBeforeInitialization(Object bean, String beanName):
在bean的初始化方法(如@PostConstruct标记的方法或实现InitializingBean接口中的afterPropertiesSet方法)被调用之前执行。
允许在bean的属性被设置之后,但在初始化之前,对bean进行额外的处理。
postProcessAfterInitialization(Object bean, String beanName):
在bean的初始化方法被调用之后执行。
允许在bean完成初始化后,对其进行修改或返回一个新的对象(尽管这通常不是推荐的做法,因为可能导致意外的行为)。
3. 返回值
这两个方法都不能返回null。如果返回null,那么在后续的操作中可能会遇到空指针异常,或者通过getBean()方法无法获取到bean的实例。
4. 使用方式
要使用BeanPostProcessor,你需要:
实现BeanPostProcessor接口。
实现postProcessBeforeInitialization和postProcessAfterInitialization方法。
将你的BeanPostProcessor实现注册为Spring容器中的一个bean,这样Spring就能够识别并应用它。
5. 排序和优先级
如果在Spring配置中定义了多个BeanPostProcessor,那么默认情况下,Spring容器会根据它们的定义顺序来依次调用。
但是,你可以通过实现Ordered接口或使用@Order、@Priority注解来指定优先级。
6. 应用场景
BeanPostProcessor常被用于AOP(面向切面编程)的自动代理创建、日志记录、安全检查、性能监控等场景。
7. 注意事项
由于BeanPostProcessor能够影响所有bean的初始化过程,因此在使用时需要特别小心,避免引入不必要的复杂性或错误。
如果在postProcessBeforeInitialization或postProcessAfterInitialization方法中修改了bean的状态,需要确保这些修改是预期的,并且不会对其他bean或整个应用程序产生负面影响。
8. 总结
BeanPostProcessor是Spring框架中一个非常强大的工具,它允许开发者在bean的生命周期中的关键阶段插入自定义逻辑。然而,由于其强大的能力,使用时需要谨慎,并确保理解其工作原理和潜在影响。

现在写几个示例来看下是怎么执行的。
我这里定义A、B、C、D 、E、F类,分别如下:
A类

package org.springframework.example.BPP;import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;/*** 注解方式*/
@Component
public class A implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {System.out.println("A.postProcessBeforeInitialization");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {System.out.println("A.postProcessAfterInitialization");return bean;}
}

B类

package org.springframework.example.BPP;import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;/*** 注解方式,加了顺序*/
@Component
@Order(0)
public class B implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {System.out.println("B.postProcessBeforeInitialization, order: 0");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {System.out.println("B.postProcessAfterInitialization, order: 0");return bean;}
}

C类

package org.springframework.example.BPP;import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;/*** 注解方式,实现Order*/
@Component
public class C implements BeanPostProcessor, Ordered {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {System.out.println("C.postProcessBeforeInitialization, order: 1");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {System.out.println("C.postProcessAfterInitialization, order: 1");return bean;}@Overridepublic int getOrder() {return 1;}
}

D类

package org.springframework.example.BPP;import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.PriorityOrdered;
import org.springframework.stereotype.Component;/*** 注解方式,实现PriorityOrdered*/
@Component
public class D implements BeanPostProcessor, PriorityOrdered {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {System.out.println("D.postProcessBeforeInitialization, PriorityOrdered: 2");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {System.out.println("D.postProcessAfterInitialization, PriorityOrdered: 2");return bean;}@Overridepublic int getOrder() {return 2;}
}

E类

package org.springframework.example.BPP;import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.PriorityOrdered;
import org.springframework.stereotype.Component;/*** 注解方式,实现PriorityOrdered*/
@Component
public class E implements BeanPostProcessor, PriorityOrdered {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {System.out.println("E.postProcessBeforeInitialization, PriorityOrdered: 3");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {System.out.println("E.postProcessAfterInitialization, PriorityOrdered: 3");return bean;}@Overridepublic int getOrder() {return 3;}
}

F类

package org.springframework.example.BPP;import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;/*** 注解方式,实现Order*/
@Component
public class F implements BeanPostProcessor, Ordered {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {System.out.println("F.postProcessBeforeInitialization, order: 4");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {System.out.println("F.postProcessAfterInitialization, order: 4");return bean;}@Overridepublic int getOrder() {return 4;}
}

BeanTest 测试类

package org.springframework.example.BPP;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class BeanTest {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext =new AnnotationConfigApplicationContext("org.springframework.example.BPP");}
}

看下打印结果

D.postProcessBeforeInitialization, PriorityOrdered: 2
E.postProcessBeforeInitialization, PriorityOrdered: 3
D.postProcessAfterInitialization, PriorityOrdered: 2
E.postProcessAfterInitialization, PriorityOrdered: 3
D.postProcessBeforeInitialization, PriorityOrdered: 2
E.postProcessBeforeInitialization, PriorityOrdered: 3
D.postProcessAfterInitialization, PriorityOrdered: 2
E.postProcessAfterInitialization, PriorityOrdered: 3
D.postProcessBeforeInitialization, PriorityOrdered: 2
E.postProcessBeforeInitialization, PriorityOrdered: 3
C.postProcessBeforeInitialization, order: 1
F.postProcessBeforeInitialization, order: 4
D.postProcessAfterInitialization, PriorityOrdered: 2
E.postProcessAfterInitialization, PriorityOrdered: 3
C.postProcessAfterInitialization, order: 1
F.postProcessAfterInitialization, order: 4
D.postProcessBeforeInitialization, PriorityOrdered: 2
E.postProcessBeforeInitialization, PriorityOrdered: 3
C.postProcessBeforeInitialization, order: 1
F.postProcessBeforeInitialization, order: 4
D.postProcessAfterInitialization, PriorityOrdered: 2
E.postProcessAfterInitialization, PriorityOrdered: 3
C.postProcessAfterInitialization, order: 1
F.postProcessAfterInitialization, order: 4

初步分析结果,后面再看原因:
1、打印的结果怎么是这样
2、AB为什么没有打印
3、PriorityOrdered 优先级高于Ordered
4、B类的@Order(0)好像没用

带着问题,来分析一下源码:
首先我们的BeanTest类里面的AnnotationConfigApplicationContext,new 的时候内部自带了refresh(),在refresh()里面找到registerBeanPostProcessors(beanFactory),最后在PostProcessorRegistrationDelegate类的registerBeanPostProcessors中打个断点,后面调试用。

在这里插入图片描述
先整体分析一下这段代码:

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {// WARNING: Although it may appear that the body of this method can be easily// refactored to avoid the use of multiple loops and multiple lists, the use// of multiple lists and multiple passes over the names of processors is// intentional. We must ensure that we honor the contracts for PriorityOrdered// and Ordered processors. Specifically, we must NOT cause processors to be// instantiated (via getBean() invocations) or registered in the ApplicationContext// in the wrong order.//// Before submitting a pull request (PR) to change this method, please review the// list of all declined PRs involving changes to PostProcessorRegistrationDelegate// to ensure that your proposal does not result in a breaking change:// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22//上面的注释看,作者意思是这样写很多循环都是有意的,不需要重构//获取BeanPostProcessor的实现类的Bean名称集合//抛开Spring自带的BeanPostProcessor,这里将会获取到我们自定义的ABCDEF6个类,Spring 自带的BeanPostProcessor,后面再说String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// Register BeanPostProcessorChecker that logs an info message when// a bean is created during BeanPostProcessor instantiation, i.e. when// a bean is not eligible for getting processed by all BeanPostProcessors.//这里为什么要+1,我个人估计是因为BeanPostProcessorChecker本身也是一个BeanPostProcessor//BeanPostProcessorChecker 用来检测不符合BeanPostProcessors规则的Beanint beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// Separate between BeanPostProcessors that implement PriorityOrdered,// Ordered, and the rest.//分别收集PriorityOrdered、Ordered和没有实现排序的BeanPostProcessor和MergedBeanDefinitionPostProcessor类型的BeanList<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {//查询指定名称的Bean 是否实现PriorityOrdered 接口,判断的代码也挺复杂,暂且不关心if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//获取BeanPostProcessor的实例BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);//如果是MergedBeanDefinitionPostProcessor类型,该处理器后面再说if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}//如果实现了Ordered接口,则添加到orderedPostProcessorNames集合中else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}//如果没有实现排序接口,则添加到nonOrderedPostProcessorNames集合中else {nonOrderedPostProcessorNames.add(ppName);}}// First, register the BeanPostProcessors that implement PriorityOrdered.//先排序priorityOrderedPostProcessors//默认排序规则使用的OrderComparator,优先排序PriorityOrdered的实现类,顺序从小到大排序sortPostProcessors(priorityOrderedPostProcessors, beanFactory);//注册,就是往beanFactory中的一个List增加BeanPostProcessor//这里面又判断了beanFactory 是否是AbstractBeanFactory,关于什么事AbstractBeanFactory,也留着后面讲registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// Next, register the BeanPostProcessors that implement Ordered.//注册实现了Ordered的BeanPostProcessorsList<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());for (String ppName : orderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);orderedPostProcessors.add(pp);//同样判断了MergedBeanDefinitionPostProcessorif (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}//同理,排序sortPostProcessors(orderedPostProcessors, beanFactory);//同理,注册registerBeanPostProcessors(beanFactory, orderedPostProcessors);// Now, register all regular BeanPostProcessors.//处理没有实现排序的BeanPostProcessorList<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}//同理,注册registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);// Finally, re-register all internal BeanPostProcessors.//最后,处理MergedBeanDefinitionPostProcessorsortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);// Re-register post-processor for detecting inner beans as ApplicationListeners,// moving it to the end of the processor chain (for picking up proxies etc).//添加ApplicationListenerDetector,其用来注册ApplicationListener类型的bean到上下文中,后面来测试一下beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}

下面来调试一下
解释第一个问题,打印结果解密,首先要知道在哪里调用postProcessBeforeInitialization和postProcessAfterInitialization。这里是在通过beanFactory.getBean获取Bean的时候,没有Bean就会创建一个Bean,此时就会调用到,跟进去在AbstractAutowireCapableBeanFactory–>initializeBean 内部进行调用,此处打个断点调式。

在这里插入图片描述
由于几个内置BeanPostProcessor的存在,运行时会多次进入断点,所以我们都跳过,进入applyBeanPostProcessorsBeforeInitialization,查看**getBeanPostProcessors()**的值,此时为几个内置BeanPostProcessor。
在这里插入图片描述
内置Bean自然没有我们的东西,跳过,后面的进入断点次数,不算内置BeanPostProcessor!!!

第二次进入断点,此时beanName 是 e
在这里插入图片描述
此时的getBeanPostProcessors() 还是原来的内置BeanPostProcessor,跳过。

第三次进入断点,此时beanName是“c”
在这里插入图片描述
这时getBeanPostProcessors() 多了D、E,这时继续执行,将打印D、E的postProcessBeforeInitialization日志
在这里插入图片描述
继续往下执行到applyBeanPostProcessorsAfterInitialization,打印

在这里插入图片描述
到这里,Bean C已经处理完了,直接跳过,到下个断点

第四次进入断点是F
在这里插入图片描述
这里的getBeanPostProcessors() 还是DE,没有C,为什么?因为CF都是实现的Ordered,他们都是在一块处理,处理完后才添加到beanPostProcessors中。由前面的代码分析可知。
所以在这里还是打印的DE的日志
在这里插入图片描述

第五次进入断点,beanName是a
在这里插入图片描述
这里开始打印DECF的日志
在这里插入图片描述
第六次进入断点,beanName是b
在这里插入图片描述
到这里所有的类都执行完了

解释一下第二个问题,AB为什么没有被打印。
从上面可知,AB 两个bean的创建在最后,后续没有其他Bean创建,因此没有执行AB 两个BeanPostProcessor的机会。要想打印,单独创建一个普通Bean,来测试一下。
G类

package org.springframework.example.BPP;import org.springframework.stereotype.Component;@Component
public class G {
}

在这里插入图片描述
这里发现一个问题,B类的order 是0,怎么会在最后?实际是因为B类被认为是没有实现排序的BeanPostProcessor,也就是 Order(0) 注解在这里没用!!!这也就回答了第四个问题。
在这里插入图片描述

解释第三个问题,PriorityOrdered 优先级高于Ordered,因为代码是先处理的PriorityOrdered 的实现
在这里插入图片描述

最后对于大模型对BeanPostProcessor的介绍中的第五点

5. 排序和优先级
如果在Spring配置中定义了多个BeanPostProcessor,那么默认情况下,Spring容器会根据它们的定义顺序来依次调用。
但是,你可以通过实现Ordered接口或使用@Order、@Priority注解来指定优先级。

是错误的!!!目前只能通过实现Ordered或者PriorityOrdered接口

通过上面的实例测试@Order并没有起作用,@Priority 注解也没法在类上使用,查了一下该注解在javax.annotation-api中。
在这里插入图片描述

作者其他文章推荐:
基于Spring Boot 3.1.0 系列文章

  1. Spring Boot 源码阅读初始化环境搭建
  2. Spring Boot 框架整体启动流程详解
  3. Spring Boot 系统初始化器详解
  4. Spring Boot 监听器详解
  5. Spring Boot banner详解
  6. Spring Boot 属性配置解析
  7. Spring Boot 属性加载原理解析
  8. Spring Boot 异常报告器解析
  9. Spring Boot 3.x 自动配置详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/26022.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML静态网页成品作业(HTML+CSS)—— 兰蔻化妆品网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

网卡聚合链路配置

创建名为mybond0的绑定&#xff0c;使用示例如下&#xff1a; # nmcli con add type bond con-name mybond0 ifname mybond0 mode active-backup添加从属接口&#xff0c;使用示例如下&#xff1a; # nmcli con add type bond-slave ifname enp3s0 master mybond0要添加其他从…

反射...

一、反射的定义 二、获取Class对象三种方式 全类名&#xff1a;包名类名。 public class test {public static void main(String [] args) throws ClassNotFoundException {//第一种方式Class class1Class.forName("test02.Student");//第二种方法Class class2Stud…

【区块链】深入解析Proof of Work (PoW): 区块链技术的核心驱动力

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 深入解析 Proof of Work (PoW): 区块链技术的核心驱动力引言一、PoW基本概念1.1…

C++ 判断目标文件是否被占用(独占)(附源码)

在IM软件中发起文件发送时,如果要发送的是某word文件,并且该word文件被office打开,则会提示文件正在被占用无法发送,如下所示: 那文件被占用到底是如何判断出来的呢?其实很简单,调用系统API函数CreateFile,打开该文件(OPEN_EXISTING),传入FILE_SHARE_READ共享读标记…

探索Chrome DevTools的高级技巧与隐藏功能

Chrome DevTools是网页开发者不可或缺的调试工具&#xff0c;它提供了丰富的功能&#xff0c;帮助开发者快速诊断和解决问题。然而&#xff0c;除了常见的功能&#xff0c;如元素检查、网络监控和JavaScript调试之外&#xff0c;DevTools还有许多不为人知的强大功能和技巧。本文…

SAP乘云而上

上周四参加了SAP原厂组织的“SAP乘云而上私享会”&#xff0c;由德勤赞助。活动主要的内容是介绍了RISE with SAP的上云服务包并且参观了SAP Labs。 现阶段对于大中型企业客户&#xff0c;SAP力推的是S/4HANA PCE(Private Cloud Edition)私有云版本&#xff0c;这个版本我在之…

Androidstudio项目加载不出来,显示Connect timed out

Android studio加载不出来所需要的环境依赖,99%的问题都是网络原因 解决办法有两个: 1.科学上网 2.使用国内的镜像 方法一自行解决,下面重点介绍方法二 在项目目录下找到gradle->wrapper->gradle-wrapper.properties 将项目的distributionUrl改为https://mirrors.cl…

从零到发布:npm插件包终极指南

在JavaScript和Node.js的生态系统中&#xff0c;npm&#xff08;Node Package Manager&#xff09;是最重要的包管理工具之一。通过npm&#xff0c;开发者可以共享代码、复用他人的工作成果以及协作开发。本指南将详细介绍如何通过npm发布自己的插件包&#xff0c;以便其他开发…

平安养老险陕西分公司荣获“2021-2023年乡村振兴‘三村工程’先进机构”

5月27日&#xff0c;中国平安成立36周年司庆暨三省推广启动大会顺利召开。会上&#xff0c;平安养老险陕西分公司获“2021-2023年乡村振兴‘三村工程’先进机构”荣誉表彰。 过去三年间&#xff0c;平安养老险陕西分公司始终坚持金融为民&#xff0c;在平安集团、平安养老险的指…

MFC上下文菜单与定时器学习笔记

本博文简单介绍了上下文菜单以及定时器的知识内容&#xff0c;作为笔记发表在csdn上面。 在这里插入图片描述 菜单资源的使用 添加菜单资源加载菜单资源&#xff1a; 注册窗口类时设置菜单创建窗口传参设置菜单在主窗口WM_CREATE消息中利用SetMenu函数设置 加载菜单资…

Python编写和管理装饰器库之wrapt使用详解

概要 在 Python 编程中,装饰器(decorator)是一个非常强大的工具,可以在不修改原函数代码的情况下,增强函数的功能。然而,编写装饰器有时会遇到一些复杂的问题,比如保持被装饰函数的元信息、正确传递参数等。wrapt 库提供了一组工具,帮助开发者更容易地编写和管理装饰器…

深圳比创达电子|EMI电磁干扰行业:挑战到突破,电子产业新未来

随着电子技术的飞速发展&#xff0c;电磁干扰&#xff08;EMI&#xff09;问题日益凸显&#xff0c;成为影响电子设备性能和稳定性的重要因素。EMI电磁干扰行业作为解决这一问题的关键领域&#xff0c;正面临着前所未有的机遇与挑战。 一、引言&#xff1a;EMI电磁干扰行业的崛…

分布式事务AP控制方案(下)

分布式事务控制方案 本篇文章给出一种要求高可用性&#xff08;AP思想&#xff09;的分布式事务控制方案 上篇回顾&#xff1a;点我查看 分布式事务控制方案1、前景回顾2、数据库和缓存的操作3、分布式文件系统1&#xff09;页面静态化2&#xff09;远程调用3&#xff09;调用…

10秒钟docker 安装Acunetix

1、拉取镜像&#xff1a; 2、查看镜像&#xff1a; [rootdns-server ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE quay.io/hiepnv/acunetix latest f8415551b8f4 2 months ago 1.98GB 3、运行镜像&#xff1a; …

优思学院|用ChatGPT快速完成数据分析图表【柏累托图法】

数据分析是很多行业的人不可少的一部分&#xff0c;尤其是质量工程师更是日常的工作。然而&#xff0c;随着科技的进步&#xff0c;人工智能&#xff08;AI&#xff09;将逐渐承担起数据计算的工作&#xff0c;这意味着未来的质量工程师需要具备的不仅仅是计算能力&#xff0c;…

ISO 19115-3:2023 基本概念的 XML模式实现

前言 ISO(国际标准化组织)是由各国标准化机构(ISO 成员机构)组成的全球性联合会。制定国际标准的工作通常由 ISO 技术委员会完成。对某一技术委员会所关注的主题感兴趣的每个成员机构都有权在该委员会中派代表。与 ISO 联络的国际组织、政府和非政府组织也参与工作。ISO 与…

运营商大模型进化之路:策略分野与AI未来的璀璨展望

运营商大模型的进化路线“分野”与AI大模型的璀璨前景 随着人工智能技术的飞速发展&#xff0c;AI大模型已成为推动科技进步和产业变革的重要力量。在这个浪潮中&#xff0c;运营商作为通信行业的巨头&#xff0c;也纷纷投入大模型的研发与应用&#xff0c;探索出各自独特的进化…

性能测试2【搬代码】

1.性能测试脚本完善以及增强 2.jmeter插件安装以及监控使用 3.性能压测场景设置&#xff08;基准、负载、压力、稳定性&#xff09; 4. 无界面压测场景详解 一、性能测试脚本完善以及增强 使用控制器的目的是使我们的脚本更加接近真实的场景 1.逻辑控制器: 【事务控制器】&…

MySQL存储引擎详述:InnoDB为何胜出?

MySQL作为当前最流行的开源关系型数据库之一,其强大的功能和良好的性能使其广泛应用于各种规模的应用系统中。其中,存储引擎的设计理念是MySQL数据库灵活高效的关键所在。 一、什么是存储引擎 存储引擎是MySQL架构的重要组成部分,负责MySQL中数据的存储和提供了视图,存储过程等…