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

深入理解Spring框架几个重要扩展接口

本文介绍Spring框架的几个日常开发重要扩展接口,方便日常项目中按需扩展使用。

一、Processor 系列接口

用途: Processor 系列接口包括 BeanPostProcessor 和 BeanFactoryPostProcessor,它们的设计目的是在 Spring 容器启动过程中对 Bean 和 BeanFactory 进行自定义处理,实现一些额外的逻辑。加深理解SpringBean的生命周期理解,以及扩展更多自定义实现。

BeanPostProcessor该接口目前有两个方法:

  • postProcessBeforeInitialization 该在初始化方法之前调用。

  • postProcessAfterInitialization 该方法再初始化方法之后调用。

源码如下:

public interface BeanPostProcessor {/*** Apply this {@code BeanPostProcessor} to the given new bean instance <i>before</i> any bean* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}* or a custom init-method). The bean will already be populated with property values.* The returned bean instance may be a wrapper around the original.* <p>The default implementation returns the given {@code bean} as-is.* @param bean the new bean instance* @param beanName the name of the bean* @return the bean instance to use, either the original or a wrapped one;* if {@code null}, no subsequent BeanPostProcessors will be invoked* @throws org.springframework.beans.BeansException in case of errors* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet*/@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}/*** Apply this {@code BeanPostProcessor} to the given new bean instance <i>after</i> any bean* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}* or a custom init-method). The bean will already be populated with property values.* The returned bean instance may be a wrapper around the original.* <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean* instance and the objects created by the FactoryBean (as of Spring 2.0). The* post-processor can decide whether to apply to either the FactoryBean or created* objects or both through corresponding {@code bean instanceof FactoryBean} checks.* <p>This callback will also be invoked after a short-circuiting triggered by a* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,* in contrast to all other {@code BeanPostProcessor} callbacks.* <p>The default implementation returns the given {@code bean} as-is.* @param bean the new bean instance* @param beanName the name of the bean* @return the bean instance to use, either the original or a wrapped one;* if {@code null}, no subsequent BeanPostProcessors will be invoked* @throws org.springframework.beans.BeansException in case of errors* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet* @see org.springframework.beans.factory.FactoryBean*/@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}}
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {/*** Apply this BeanPostProcessor <i>before the target bean gets instantiated</i>.* The returned bean object may be a proxy to use instead of the target bean,* effectively suppressing default instantiation of the target bean.* <p>If a non-null object is returned by this method, the bean creation process* will be short-circuited. The only further processing applied is the* {@link #postProcessAfterInitialization} callback from the configured* {@link BeanPostProcessor BeanPostProcessors}.* <p>This callback will be applied to bean definitions with their bean class,* as well as to factory-method definitions in which case the returned bean type* will be passed in here.* <p>Post-processors may implement the extended* {@link SmartInstantiationAwareBeanPostProcessor} interface in order* to predict the type of the bean object that they are going to return here.* <p>The default implementation returns {@code null}.* @param beanClass the class of the bean to be instantiated* @param beanName the name of the bean* @return the bean object to expose instead of a default instance of the target bean,* or {@code null} to proceed with default instantiation* @throws org.springframework.beans.BeansException in case of errors* @see #postProcessAfterInstantiation* @see org.springframework.beans.factory.support.AbstractBeanDefinition#getBeanClass()* @see org.springframework.beans.factory.support.AbstractBeanDefinition#getFactoryMethodName()*/@Nullabledefault Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {return null;}/*** Perform operations after the bean has been instantiated, via a constructor or factory method,* but before Spring property population (from explicit properties or autowiring) occurs.* <p>This is the ideal callback for performing custom field injection on the given bean* instance, right before Spring's autowiring kicks in.* <p>The default implementation returns {@code true}.* @param bean the bean instance created, with properties not having been set yet* @param beanName the name of the bean* @return {@code true} if properties should be set on the bean; {@code false}* if property population should be skipped. Normal implementations should return {@code true}.* Returning {@code false} will also prevent any subsequent InstantiationAwareBeanPostProcessor* instances being invoked on this bean instance.* @throws org.springframework.beans.BeansException in case of errors* @see #postProcessBeforeInstantiation*/default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true;}/*** Post-process the given property values before the factory applies them* to the given bean, without any need for property descriptors.* <p>Implementations should return {@code null} (the default) if they provide a custom* {@link #postProcessPropertyValues} implementation, and {@code pvs} otherwise.* In a future version of this interface (with {@link #postProcessPropertyValues} removed),* the default implementation will return the given {@code pvs} as-is directly.* @param pvs the property values that the factory is about to apply (never {@code null})* @param bean the bean instance created, but whose properties have not yet been set* @param beanName the name of the bean* @return the actual property values to apply to the given bean (can be the passed-in* PropertyValues instance), or {@code null} which proceeds with the existing properties* but specifically continues with a call to {@link #postProcessPropertyValues}* (requiring initialized {@code PropertyDescriptor}s for the current bean class)* @throws org.springframework.beans.BeansException in case of errors* @since 5.1* @see #postProcessPropertyValues*/@Nullabledefault PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)throws BeansException {return null;}/*** Post-process the given property values before the factory applies them* to the given bean. Allows for checking whether all dependencies have been* satisfied, for example based on a "Required" annotation on bean property setters.* <p>Also allows for replacing the property values to apply, typically through* creating a new MutablePropertyValues instance based on the original PropertyValues,* adding or removing specific values.* <p>The default implementation returns the given {@code pvs} as-is.* @param pvs the property values that the factory is about to apply (never {@code null})* @param pds the relevant property descriptors for the target bean (with ignored* dependency types - which the factory handles specifically - already filtered out)* @param bean the bean instance created, but whose properties have not yet been set* @param beanName the name of the bean* @return the actual property values to apply to the given bean (can be the passed-in* PropertyValues instance), or {@code null} to skip property population* @throws org.springframework.beans.BeansException in case of errors* @see #postProcessProperties* @see org.springframework.beans.MutablePropertyValues* @deprecated as of 5.1, in favor of {@link #postProcessProperties(PropertyValues, Object, String)}*/@Deprecated@Nullabledefault PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {return pvs;}}

 

案例一获取当前项目启动过程中所有的实现扩展实现类。

ConfigurableApplicationContext context = SpringApplication.run(SkywalkApplication.class, args);
String[] beanNames = context.getBeanNamesForType(BeanPostProcessor.class, true, false);
for(String bean:beanNames){System.out.println("实现后置处理器:"+bean);
}

运行如下:

案例二:监控Bean的初始化信息例如最耗时的Bean。

package com.boot.skywalk.processor;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;/*** 通用的Bean的后置处理器统计最耗时的Bean*/
@Component
public class CommonBeanPostProcessor implements BeanPostProcessor {/*** 初始化前的Map,Bean->时间点*/private static final Map<String,Long> BEGIN_INIT_MAP=new ConcurrentHashMap<>();/*** 初始化后的Map,Bean->时间点*/private static final Map<String,Long> INIT_COST_MAP=new ConcurrentHashMap<>();/*** 最耗时的Bean*/private static final int TOP_COST_INIT_BEAN=3;/*** Bean初始化之前* @param bean* @param beanName* @return* @throws BeansException*/@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {BEGIN_INIT_MAP.putIfAbsent(beanName, System.currentTimeMillis());return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {Long initPoint = BEGIN_INIT_MAP.get(beanName);INIT_COST_MAP.put(beanName, System.currentTimeMillis()-initPoint);return bean;}/*** 流式获取3,List返回Map.collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue())* @return*/public Map<String,Long> getTopCostInitBean(){Map<String, Long> result = INIT_COST_MAP.entrySet()// 降序排列.stream().sorted((a,b)-> (int) (b.getValue()-a.getValue()))// 转换Map或者是List<Object[]>.limit(TOP_COST_INIT_BEAN).collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));return result;}
 CommonBeanPostProcessor beanPostProcessor= context.getBean(CommonBeanPostProcessor.class);Map<String, Long> topCostInitBean = beanPostProcessor.getTopCostInitBean();topCostInitBean.forEach((key,value)->{System.out.println(key+":"+value+"ms");});

运行截图,可以据此数据来分析项目中哪些Bean可以设置为延迟加载,提高项目启动速度。

BeanFactoryPostProcessor:

Spring 在容器启动时,会检测容器中是否存在实现了 BeanFactoryPostProcessor 接口的 Bean,并在 BeanFactory 实例化之后、Bean 实例化之前调用其相应的方法。通过实现 BeanFactoryPostProcessor 接口,我们可以在容器启动时对 BeanFactory 进行配置,如修改 Bean 的定义、添加 Bean 的属性值等

@FunctionalInterface
public interface BeanFactoryPostProcessor {/*** Modify the application context's internal bean factory after its standard* initialization. All bean definitions will have been loaded, but no beans* will have been instantiated yet. This allows for overriding or adding* properties even to eager-initializing beans.* @param beanFactory the bean factory used by the application context* @throws org.springframework.beans.BeansException in case of errors*/void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;}

二、Aware 接口

Aware 接口的设计目的是增强 Bean 对容器的感知能力,使 Bean 能够更方便地与容器进行交互,获取容器中的特定资源或实例。

Spring提供了大量以 Aware 命名的接口,如BeanNameAware、BeanFactoryAware、ApplicationContextAware等。

这些接口定义了回调方法,通过这些回调方法,Spring容器可以将容器中的一些资源、状态、环境信息注入到Bean中。

例如:ApplicationContextAware

org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces

首先会判断对象是否属于 Aware接口类型,接着根据不同的Aware接口实现类,调用不同的实现类的逻辑。 

	private void invokeAwareInterfaces(Object bean) {if (bean instanceof EnvironmentAware) {((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());}if (bean instanceof EmbeddedValueResolverAware) {((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);}if (bean instanceof ResourceLoaderAware) {((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);}if (bean instanceof ApplicationEventPublisherAware) {((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);}if (bean instanceof MessageSourceAware) {((MessageSourceAware) bean).setMessageSource(this.applicationContext);}if (bean instanceof ApplicationStartupAware) {((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());}if (bean instanceof ApplicationContextAware) {((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);}}

案例一:通过Aware接口获取ApplicationContext和BeanFactory访问容器中其他Bean。

先看相关接口源码,比较简单。

public interface ApplicationContextAware extends Aware {/*** Set the ApplicationContext that this object runs in.* Normally this call will be used to initialize the object.* <p>Invoked after population of normal bean properties but before an init callback such* as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}* or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},* {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and* {@link MessageSourceAware}, if applicable.* @param applicationContext the ApplicationContext object to be used by this object* @throws ApplicationContextException in case of context initialization errors* @throws BeansException if thrown by application context methods* @see org.springframework.beans.factory.BeanInitializationException*/void setApplicationContext(ApplicationContext applicationContext) throws BeansException;}
public interface BeanFactoryAware extends Aware {/*** Callback that supplies the owning factory to a bean instance.* <p>Invoked after the population of normal bean properties* but before an initialization callback such as* {@link InitializingBean#afterPropertiesSet()} or a custom init-method.* @param beanFactory owning BeanFactory (never {@code null}).* The bean can immediately call methods on the factory.* @throws BeansException in case of initialization errors* @see BeanInitializationException*/void setBeanFactory(BeanFactory beanFactory) throws BeansException;}
@Service
public class HomeApplicationContextAwareService implements ApplicationContextAware {private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext=applicationContext;}public void  getBean(){Home home = (Home)applicationContext.getBean("home");home.test();}
}
@Service
public class HomeBeanFactoryAwareService implements BeanFactoryAware {private BeanFactory beanFactory;@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory=beanFactory;}public void getBean(){Home bean = (Home) beanFactory.getBean("home");bean.test();}
}

三、ImportSelector 接口

用途: ImportSelector 接口的设计目的是允许在配置类中根据条件动态选择需要导入的其他配置类,以实现模块化和条件化配置。

常见应用场景:

  1. 根据不同的环境条件选择性地导入不同的配置类。
  2. 实现特定模块的自动配置功能,根据用户的配置情况动态加载相应的配置类。

源码如下

public interface ImportSelector {/*** Select and return the names of which class(es) should be imported based on* the {@link AnnotationMetadata} of the importing @{@link Configuration} class.* @return the class names, or an empty array if none*/String[] selectImports(AnnotationMetadata importingClassMetadata);/*** Return a predicate for excluding classes from the import candidates, to be* transitively applied to all classes found through this selector's imports.* <p>If this predicate returns {@code true} for a given fully-qualified* class name, said class will not be considered as an imported configuration* class, bypassing class file loading as well as metadata introspection.* @return the filter predicate for fully-qualified candidate class names* of transitively imported configuration classes, or {@code null} if none* @since 5.2.4*/@Nullabledefault Predicate<String> getExclusionFilter() {return null;}}

案例一:注入指定的Bean

public class ConfigurationImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{EmailService.class.getName(),MessageService.class.getName(),PhoneService.class.getName()};}
}
@Import(ConfigurationImportSelector.class)
@Configuration
public class ServiceConfiguration {
}
public interface ConfigurationService {void doService();
}
public class EmailService implements ConfigurationService{@Overridepublic void doService() {System.out.println("Email Service");}
}
public class MessageService implements ConfigurationService{@Overridepublic void doService() {System.out.println("Message Service");}
}
public class EmailService implements ConfigurationService{@Overridepublic void doService() {System.out.println("Email Service");}
}

案例二:SpringBoot的底层Import注解实现的自动配置扫描实现

跟进入。

点进去,这些自动配置的类都要注入到Spring容器中。 

相关文章:

深入理解Spring框架几个重要扩展接口

本文介绍Spring框架的几个日常开发重要扩展接口&#xff0c;方便日常项目中按需扩展使用。 一、Processor 系列接口 用途&#xff1a; Processor 系列接口包括 BeanPostProcessor 和 BeanFactoryPostProcessor&#xff0c;它们的设计目的是在 Spring 容器启动过程中对 Bean 和…...

使用dotnet-counters和dotnet-dump 分析.NET Core 项目内存占用问题

在.NET Core 项目部署后&#xff0c;我们往往会遇到内存占用越来越高的问题&#xff0c;但是由于项目部署在Linux上&#xff0c;因此无法使用VS的远程调试工具来排查内存占用问题。那么这篇文章我们大家一起来学习一下如何排查内存占用问题。 首先&#xff0c;我们来看一下应用…...

1282:最大子矩阵

题目&#xff1a; 已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵&#xff0c;你的任务是找到最大的非空(大小至少是1 1)子矩阵。 比如&#xff0c;如下4 4的矩阵 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 的最大子矩阵是 9 2 -4 1 -1 8 这个子矩阵的大小是15。 …...

C++编程语言:抽象机制:特殊运算符(Bjarne Stroustrup)

第19章 特殊运算符(Special Operators) 目录 19.1 引言 19.2 特殊运算符(Special Operators) 19.2.1 下标运算符(Subscripting) 19.2.2 函数调用运算符(Function Call) 19.2.3 解引用(Dereferencing) 19.2.4 递增和递减(Increment and Decrement) 19…...

图片无损放大工具Topaz Gigapixel AI v7.4.4 绿色版

Topaz A.I. Gigapixel是这款功能齐全的图象无损变大运用&#xff0c;应用可将智能机拍摄的图象也可以有着专业相机的高质量大尺寸作用。你可以完美地放大你的小照片并大规模打印&#xff0c;它根本不会粘贴。它具有清晰的效果和完美的品质。 借助AIGigapixel&#xff0c;您可以…...

Vue中计算属性computed—(详解计算属性vs方法Methods,包括案例+代码)

文章目录 计算属性computed3.1 概述3.2 使用3.3 计算属性vs方法Methods3.4 计算属性的完整写法 计算属性computed 3.1 概述 基于现有的数据&#xff0c;计算出来的新属性。 依赖的数据变化&#xff0c;自动重新计算 语法&#xff1a; 声明在 computed 配置项中&#xff0c;…...

Python程序设计 内置函数 日志模块

logging(日志) 日志记录是程序员工具箱中非常有用的工具。它可以帮助您更好地理解程序的流程&#xff0c;并发现您在开发过程中可能没有想到的场景。 日志为开发人员提供了额外的一组眼睛&#xff0c;这些眼睛不断关注应用程序正在经历的流程。它们可以存储信息&#xff0c;例…...

中标麒麟v5安装qt512.12开发软件

注意 需要联网操作 遇到问题1&#xff1a;yum提示没有可用软件包问题 终端执行如下命令 CentOS7将yum源更换为国内源保姆级教程 中标麒麟V7-yum源的更换&#xff08;阿里云源&#xff09; wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Cento…...

每日算法一练:剑指offer——数组篇(3)

1.报数 实现一个十进制数字报数程序&#xff0c;请按照数字从小到大的顺序返回一个整数数列&#xff0c;该数列从数字 1 开始&#xff0c;到最大的正整数 cnt 位数字结束。 示例 1: 输入&#xff1a;cnt 2 输出&#xff1a;[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,1…...

Java代码说明设计模式

以下是使用 Java 代码分别说明设计模式中的工厂模式、抽象工厂模式&#xff08;这里推测你可能想说的是抽象工厂模式而非虚拟工厂模式&#xff09;、建造者模式和观察者模式。 一、工厂模式 工厂模式是一种创建对象的设计模式&#xff0c;它提供了一种创建对象的方式&#xf…...

Golang笔记_day06

一、GMP 调度器 1、调度器理解思路 理解golang的调度器要从进程到协程演进来说明&#xff1a; 进程--->线程--->协程---> golang的协程&#xff08;goroutine&#xff09; 从上图可以看出&#xff0c;进程到多线程到协程&#xff0c;最终目的就是为了提高CPU的利用率…...

「从零开始的 Vue 3 系列」:第十一章——跨域问题解决方案全解析

前言 本系列将从零开始&#xff0c;系统性地介绍 Vue 3 的常用 API&#xff0c;逐步深入每个核心概念与功能模块。通过详尽的讲解与实战演示&#xff0c;帮助大家掌握 Vue 3 的基础与进阶知识&#xff0c;最终具备独立搭建完整 Vue 3 项目的能力。 第十一章&#xff1a;跨域问…...

C语言结构体数组 java静动数组及问题

1. &#xff08;1&#xff09;先声明&#xff0c;后定义&#xff1a;如上一天 //&#xff08;2&#xff09;.声明时直接定义 #define N 5 typedef struct student { int num; int score; }STU; int main(void) { STU class3[N] { {10,90},{14,70},{8,95} }; …...

uniapp项目结构基本了解

基本结构的解释 App.vue&#xff1a;应用的根组件&#xff0c;定义全局布局和逻辑。pages/&#xff1a;存放各个页面的 .vue 文件&#xff0c;定义应用的具体页面和功能模块。main.js&#xff1a;应用入口文件&#xff0c;初始化应用&#xff0c;挂载 App.vue。manifest.json&…...

常见Web知识1

List item 常见Web知识1 JSON&#xff1a; JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人类阅读和编写&#xff0c;同时也易于机器解析和生成。它通常用于客户端和服务器之间的数据传输。 JSON 结构 JSON 主要由两…...

新版idea菜单栏展开与合并

新版idea把菜单栏合并了看着很是不习惯&#xff0c;找了半天原来在这里展开 ① 点击文件 -> 设置 ② 点击外观与行为 -> 外观 -> 合并主菜单和窗口标题 然后确定&#xff0c;重启即可...

聊聊Go语言的异常处理机制

背景 最近因为遇到了一个panic问题&#xff0c;加上之前零零散散看了些关于程序异常处理相关的东西&#xff0c;对这块有点兴趣&#xff0c;于是整理了一下golang对于异常处理的机制。 名词介绍 Painc golang的内置方法&#xff0c;能够改变程序的控制流。 当函数调用了pan…...

复习:如何理解 React 中的 fiber

React 中的 Fiber 可以理解为 React 16 引入的一种新的协调(reconciliation)引擎,旨在提高 React 应用的性能和响应性。以下是对 React Fiber 的详细解释: 一、Fiber 的定义与背景 Fiber 是对 React 核心算法的一次重新实现,它将渲染工作分解成一系列小的任务单元,这些任…...

10分钟了解腾讯云混元大模型AIGC系列产品

前言 其实说到AIGC&#xff0c;作为开发者&#xff0c;大家其实已经见怪不怪了&#xff0c;那么AIGC是什么&#xff0c;这里我再简单科普一下。 AIGC的全称是Artificial Intelligence Generated Content &#xff08;人工智能生成内容&#xff09;或者说叫生成式人工智能&…...

Unity发送Http

本篇实现在Unity中发送Http请求。 讲解Get&#xff0c;Post&#xff0c;用于在Unity中进行数据对接。 一、Get IEnumerator Get() {string url "";//链接UnityWebRequest request UnityWebRequest.Get(url);//创建UnityWebRequest实例并设置请求方式为Getyield …...

微服务开发-Nacos服务治理

注册中心原理 流程如下&#xff1a; 服务启动时就会注册自己的服务信息&#xff08;服务名、IP、端口&#xff09;到注册中心&#xff1b;调用者可以从注册中心订阅想要的服务&#xff0c;获取服务对应的实例列表&#xff08;1个服务可能多实例部署&#xff09;&#xff1b;调…...

鸿蒙开发:两个重磅更新,鸿蒙版微信要来了!

从媒体消息中&#xff0c;其实我们已经知道&#xff0c;华为纯血鸿蒙系统&#xff08;HarmonyOS NEXT&#xff09;于10月8日正式开启了公测&#xff0c;对应的官方文档&#xff0c;大家可以看到已由原来的Beta版本更新到了Release&#xff0c;NEXT终于迎来了正式版本。 文档更新…...

es kibana .logstash离线集群安装

es离线集群安装 下载对应的版本一般看你客户端引用的是什么版本我这里下载的是7.6.2 官方下载地址&#xff1a;https://www.elastic.co/cn/downloads/elasticsearch 源码安装-环境准备&#xff1a;在etc/hosts文件添加3台主机 node-001 192.168.1.81 node-002 19…...

Java项目-基于springboot框架的基于协同过滤算法商品推荐系统项目实战(附源码+文档)

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…...

JAVA使用easyExcel导出数据到EXCEl,导出数据不全问题解决

JAVA使用easyExcel导出数据到EXCEl,导出数据不全问题解决 问题描述解决思路一解决思路二温馨提示 问题描述 JAVA使用easyExcel导出数据到EXCEl,导出数据不全问题。 导出的excel部分列有数据&#xff0c;好几列没有数据 解决思路一 从网上百度查询&#xff0c;大多数的解决思路…...

2-130 基于经验模态分解(EMD)的信号分解

基于经验模态分解&#xff08;EMD&#xff09;的信号分解。通过仿真信号构造待分解信号&#xff0c;经过分解后得到信号希尔伯特时频图&#xff0c;可视化展示不同分解信号频率段。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&#xff1a;2-130 基于经验模态分解&…...

openlayers 测量功能实现(测距测面)- vue3

一、配置openlayer环境 借鉴&#xff1a;Vue 3 OpenLayers 的简单使用_vue3 openlayers-CSDN博客 二、代码如下&#xff08;测距、测面和清除&#xff09; measurs.js: import {ref} from vue; import Draw from ol/interaction/Draw import VectorSource from ol/source/…...

各种语言的序列化与反序列化(C/C++ c# Python Javascript Java)

序列化是指将程序中的对象转换为字节序列的过程&#xff0c;使得对象的状态可以在网络上传输或存储到文件中。反序列化则是将字节序列恢复为程序中的对象的过程。这两个过程是数据持久化和远程通信中的关键步骤。 1. C 序列化与反序列化 在 C 中&#xff0c;标准库没有提供内…...

RHCE笔记

第二章&#xff1a;时间服务器 东八区&#xff1a;UTC8CST(北京时间) 应用层的时间协议&#xff1a;NTP&#xff08;网络时间协议&#xff09;&#xff1a;udp/端口&#xff1a;123 Chrony软件&#xff1a;由chronyd&#xff08;客户端&#xff09;和chronyc&#xff08;服务…...

Android 设置控件为圆形

Android的圆形控件 对于所有的View有效 在开发的过程中&#xff0c;肯定需要实现一个圆形的控件&#xff0c;而且不是绘制一个圆形&#xff0c;那么怎么弄呢&#xff0c;在Android5.0后&#xff0c;有一个类ViewOutlineProvider&#xff0c;可以实现这个功能&#xff0c;应该是…...