认识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,一经查实,立即删除!

相关文章

btstack协议栈实战篇--GATT Client - Discover Primary Services

btstack协议栈---总目录-CSDN博客 这个示例展示了如何使用 GATT 客户端 API 来发现第一个其服务的已发现设备的主要服务及其特征。 在 HCI 和 GATT 客户端数据包处理器之间划分逻辑处理。HCI 数据包处理器负责找到远程设备、连接到它,并启动第一个 GATT 客户端…

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

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

vue阶段复习基础知识以及简单的按钮绑定相关的知识!

vue阶段复习 理论练习 请简述Vue、Node.js、Vscode是什么&#xff0c;以及有什么关系 1.vue是一个轻量级、比较灵活的且支持组件开发的网络框架 2.node.js是让JavaScript运行在服务器上的一种环境 3.Vscode是一款有着丰富插件的代码编辑器 4.vscode就如同画布&#xff0c;node…

排查Spring条件注解未能生效的常见原因

在撰写关于排查Spring条件注解未能生效的文章时&#xff0c;可以按照以下结构进行组织&#xff1a; 标题&#xff1a; 解决Spring条件注解不生效的问题&#xff1a;常见原因与解决方案 引言&#xff1a; 简要介绍Spring条件注解&#xff08;如Conditional&#xff09;的用途&…

网卡聚合链路配置

创建名为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++ 虚函数表 vtable

目录 1.测试代码2.查看虚函数表Widget 虚函数表虚函数表 参考 本篇文章通过小实验来了解了解虚函数表&#xff0c;测试环境 ubuntu16 gcc 5.4.0 1.测试代码 测试代码中定义了两个类&#xff0c;后面将会查看这两个类的虚函数表 #include <iostream> using namespace s…

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;这个版本我在之…

Windows Docker Desktop 安装 postgres

Docker Desktop安装 postgres 12.6 数据库 step docker pull postgres:12.6提前创建F:/D-dockerData/postgres-12.6/data 文件夹用于bind mountdocker run docker run --name postgres-12.6 \-e POSTGRES_PASSWORD123456 \-p 5432:5432 \-v F:/D-dockerData/postgres-12.6/d…

react 0至1 【jsx】

1.函数调用 // 项目的根组件 // App -> index.js -> public/index.html(root)const count 100function getName () {return test }function App () {return (<div className"App">this is App{/* 使用引号传递字符串 */}{this is message}{/* 识别js变…

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

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

http网络服务器

wwwroot(目录)/index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>比特就业课</title>…

从零到发布: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;在平安集团、平安养老险的指…

注解 - @CookieValue

注解简介 在今天的每日一注解中&#xff0c;我们将探讨CookieValue注解。CookieValue是Spring框架中的一个注解&#xff0c;用于将HTTP请求中的Cookie值绑定到控制器方法的参数上。 注解定义 CookieValue注解用于从HTTP请求中的Cookie提取值&#xff0c;并将其绑定到控制器方…

Linux系统sort排序与uniq去重

Linux系统sort排序与uniq去重 工作中数据太多太杂&#xff0c;不便于查看分析。这时是可以采用sort将数据排序&#xff0c;同时可以配合uniq命令进行去重。 场景&#xff1a;云平台中&#xff0c;日常工作包含巡检工作&#xff0c;是通过事先编写好的巡检脚本去检测云平台的和…

阿赵UE引擎C++编程学习笔记——查找和控制Actor

大家好&#xff0c;我是阿赵。   在使用Unity引擎的时候&#xff0c;经常会用到的一个功能是通过GameObject.Find去查找场景里面的对象。这次变成在UE引擎里面做同样的事情&#xff0c;这篇文章主要做的事情有2个&#xff0c;第一是从场景里面找到特定的Actor&#xff0c;第二…