spring注解驱动系列-- BeanPostProcessor与BeanFactoryPostProcessor

ops/2024/9/20 1:26:38/ 标签: spring

一、BeanPostProcessor与BeanFactoryPostProcessor的定义

一、BeanPostProcessor

bean后置处理器,bean创建对象初始化前后进行拦截工作的

二、BeanFactoryPostProcessor 

beanFactory的后置处理器,在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容,所有的bean定义信息已经保存加载到beanFactory,但是bean的实例还未创建。BeanFactoryPostProcessor是BeanFactory的一个钩子接口

二、原理 

一、测试demo

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");int count = beanFactory.getBeanDefinitionCount();String[] names = beanFactory.getBeanDefinitionNames();System.out.println("当前BeanFactory中有"+count+" 个Bean");System.out.println(Arrays.asList(names));}
}@ComponentScan("com.spring.annotate.beans")
@Configuration
public class BeansFactoryConfig {@Beanpublic Blue blue(){return new Blue();}
}@Testvoid contextLoads() {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansFactoryConfig.class);applicationContext.close();}

结果:

二、原理

一、通过idea工具可以查看到spring源码接口,发现它还有一个子接口BeanDefinitionRegistryPostProcessor

二、BeanFactoryPostProcessor接口

@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;

}

从源码上看,这个接口只有一个方法,也就是说spring是通过这个方法对BeanFactory进行增强的

三、BeanDefinitionRegistryPostProcessor接口

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

    /**
     * Modify the application context's internal bean definition registry after its
     * standard initialization. All regular bean definitions will have been loaded,
     * but no beans will have been instantiated yet. This allows for adding further
     * bean definitions before the next post-processing phase kicks in.
     * @param registry the bean definition registry used by the application context
     * @throws org.springframework.beans.BeansException in case of errors
     */
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}
 

此接口也只有一个方法,是为了Bean的注册而生,BeanDefinitionRegistry 是BeanDefinition的注册器,而注册Bean的过程是将满足Bean条件的类解析为BeanDefinition对象然后注册到BeanDefinition注册器中。

总结:

BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor都是扩展Bean的加载方式,当我们需要自定义自己的Bean加载方式时实现BeanDefinitionRegistryPostProcessor接口即可。@Configuration注解的实现就是基于BeanDefinitionRegistryPostProcessor接口完成

四、BeanFactoryPostProcessor 原理

首先我们需要清楚,AbstractApplicationContext类中refresh()是spring加载Bean的核心方法,大部分的处理逻辑都是在这个方法中完成。执行时机是:所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建

@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// Prepare this context for refreshing./*** 准备上下文刷新工作,如设置初始值*/prepareRefresh();// Tell the subclass to refresh the internal bean factory./*** 告诉子类刷新内部beanFactory,返回Bean工厂*/ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context./*** 准备beanFactory,以便于上下文中使用*/prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses./*** 允许在上下文子类中对bean工厂进行后处理。*/postProcessBeanFactory(beanFactory);/*** 开启处理PostProcessors步骤器*/StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");// Invoke factory processors registered as beans in the context./*** 调用BeanFactory的后置处理器*/invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation./**** 注册拦截bean创建的bean处理器*/registerBeanPostProcessors(beanFactory);/*** 处理PostProcessors步骤器*/beanPostProcess.end();// Initialize message source for this context./*** 初始化MessageSource*/initMessageSource();// Initialize event multicaster for this context./*** 初始化Application监听器的管理Bean(ApplicationEventMulticaster)*/initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses./*** 模板模式,刷新Bean的操作,由子类实现具体逻辑*/onRefresh();// Check for listener beans and register them./*** 检查和注册监听器*/registerListeners();// Instantiate all remaining (non-lazy-init) singletons./*** 实例化所有(非惰性初始化)单例*/finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event./*** 发布相应的事件*/finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();contextRefresh.end();}}}

一、 ioc容器创建对象

二、invokeBeanFactoryPostProcessors(beanFactory);

	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {/*** 执行BeanFactoryPostProcessor,是该方法的处理核心*/PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)/*** 检查和赋初始值*/if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}

  三、PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())方法

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {Set<String> processedBeans = new HashSet<>();/*** 首先调用BeanDefinitionRegistryPostProcessors(如果有)。*/if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;/*** 用于存放BeanFactoryPostProcessor的对象*/List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();/*** 用户存放BeanDefinitionRegistryPostProcessor对象*/List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();/********************************* 下面处理BeanDefinitionRegistryPostProcessor逻辑 *************************************//*** 遍历最原始的BeanFactoryPostProcessor列表,找出BeanDefinitionRegistryPostProcessor和 BeanFactoryPostProcessor* BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口*/for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;/*** 执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry*/registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);}else {regularPostProcessors.add(postProcessor);}}/*** 定义当前找到的BeanDefinitionRegistryPostProcessor临时存储*/List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.// 首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessor。String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();// 接下来,调用实现Ordered的BeanDefinitionRegistryPostProcessor。postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();// 最后,调用所有其他BeanDefinitionRegistryPostProcessor,直到不再出现其他BeanDefinitionRegistryPostProcessor。boolean reiterate = true;while (reiterate) {reiterate = false;postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);reiterate = true;}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();}/*** 批量执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry*/invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);/*** 批量执行BeanFactoryPostProcessor(最开始的BeanFactoryPostProcessor)*/invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}/********************************* 下面处理BeanFactoryPostProcessor逻辑(可能执行上面步骤产生新的BeanFactoryPostProcessor),执行逻辑和BeanDefinitionRegistryPostProcessor一致 *************************************/// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,// Ordered, and the rest.List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// Finally, invoke all other BeanFactoryPostProcessors.List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);// Clear cached merged bean definitions since the post-processors might have// modified the original metadata, e.g. replacing placeholders in values...beanFactory.clearMetadataCache();}/*** 排序BeanFactoryPostProcessor* @param postProcessors* @param beanFactory*/private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {// Nothing to sort?if (postProcessors.size() <= 1) {return;}Comparator<Object> comparatorToUse = null;if (beanFactory instanceof DefaultListableBeanFactory) {comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();}if (comparatorToUse == null) {comparatorToUse = OrderComparator.INSTANCE;}postProcessors.sort(comparatorToUse);}/*** 执行  BeanDefinitionRegistryPostProcessor* @param postProcessors* @param registry* @param applicationStartup*/private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process").tag("postProcessor", postProcessor::toString);postProcessor.postProcessBeanDefinitionRegistry(registry);postProcessBeanDefRegistry.end();}}/*** 执行invokeBeanFactoryPostProcessors* @param postProcessors* @param beanFactory*/private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {for (BeanFactoryPostProcessor postProcessor : postProcessors) {StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process").tag("postProcessor", postProcessor::toString);postProcessor.postProcessBeanFactory(beanFactory);postProcessBeanFactory.end();}}

一、遍历最原始的BeanFactoryPostProcessor,找到BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor,且执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry(registry)方法加载Bean。

二、从BeanFactory中寻找BeanDefinitionRegistryPostProcessorPriorityOrdered(最高优先级的排序)类型Bean,排序后执行postProcessBeanDefinitionRegistry(registry)方法加载Bean。

三、从BeanFactory中寻找BeanDefinitionRegistryPostProcessor未被加载的Ordered(排序)类型Bean,排序后执行postProcessBeanDefinitionRegistry(registry)方法加载Bean。

四、从BeanFactory中寻找出未被加载的BeanDefinitionRegistryPostProcessor类型Bean,然后执行postProcessBeanDefinitionRegistry(registry)方法加载Bean,这一步目的就是处理加载新的BeanDefinitionRegistryPostProcessor的Bean。

五、从BeanFactory中寻找BeanFactoryPostProcessorPriorityOrdered(最高优先级的排序)类型Bean,排序后执行postProcessBeanFactory(beanFactory)方法加载Bean。

六、从BeanFactory中寻找BeanFactoryPostProcessor未被加载的Ordered(排序)的类型Bean,排序后执行postProcessBeanFactory(beanFactory)方法加载Bean。

七、从BeanFactory中寻找出未排序BeanFactoryPostProcessor类型Bean,然后执行postProcessBeanFactory(beanFactory)方法加载Bean。

  • priorityOrderedPostProcessors:放置有优先级排序的接口
  • orderedPostProcessorNames:放置有排序的PostProcessorNames
  • nonOrderedPostProcessorNames:放置普通的PostProcessorNames

五、BeanDefinitionRegistryPostProcessor原理

执行时机:在所有bean定义信息将要被加载,bean实例还未创建的,这个是将要被加载,BeanFactoryPostProcessor 这个是已经被加载,所以BeanDefinitionRegistryPostProcessor是在更前执行

1、BeanDefinition:容器中的每一个bean都会有一个对应的BeanDefinition实例,该实例负责保存bean对象的所有必要信息,包括bean对象的class类型、是否是抽象类、构造方法和参数、其它属性等等。

2、BeanDefinitionRegistry:

BeanDefinition是定义bean的,BeanDefinitionRegistry则是bean定义信息的保存中心,也叫注册中心,保存了bean的所有定义,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例。bean是单例还是多例,bean的类型,bean的ID等信息,都是存在BeanDefinitionRegistry里面。

3、BeanDefinitionRegistryPostProcessor:它是Spring框架的一个扩展点,用于对Bean定义的注册过程进行干预和定制。继承BeanFactoryPostProcessor接口,并在其基础上扩展了一个新的方法,即:postProcessBeanDefinitionRegistry()方法。

        用途:在Spring容器初始化时,首先会读取应用程序中的配置文件,并解析出所有的Bean定义,然后将这些Bean定义注册到容器中。在这个过程中,BeanDefinitionRegistryProcessor提供了一种机制,允许开发人员在Bean定义注册之前和之后对Bean定义进行自定义处理,例如添加,修改或删除Bean定义等。
        方法详解:

postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry):该方法在所有Bean定义加载完成之后,Bean实例化之前被调用,允许开发人员对Bean定义进行自定义修改,例如添加,修改或删除Bean定义等。
postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory): 该方法是继承自BeanFactoryPostProcessor接口的方法,用于在BeanFactory完成实例化之后对BeanFactory进行后置处理。

一、ioc容器创建

二、调用refresh()方法,执行到里面的invokeBeanFactoryPostProcessors(beanFactory);方法

进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

 三、从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件

	private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {postProcessor.postProcessBeanDefinitionRegistry(registry);}}

1、依次触发所有的postProcessBeanDefinitionRegistry()方法

2、再来触发postProcessBeanFactory()方法,是BeanFactoryPostProcessor里面的方法。 

四、最后到BeanFactoryPostProcessor组件时还会依次触发postProcessBeanFactory()方法 


http://www.ppmy.cn/ops/7754.html

相关文章

计算机网络(王道考研)笔记个人整理——第二章

第二章 物理层主要任务&#xff1a;确定与传输媒体有关的一些特性 机械特性&#xff1a;物理连接的特性 规定物理连接时所采用的规格、接口形状、引线数目、引脚数量和排列情况 电气特性 规定传输二进制位时&#xff0c;线路上信号的电压范围、阻抗匹配、传输速率和距离限制等…

【KingSCADA】通过地址引用和弹窗模板实现设备控制

当相同的设备过多时&#xff0c;要做很多相同的弹窗&#xff0c;这种情况下可以通过地址引用和弹窗模板实现设备控制。 1.变量创建 2.画面开发 以阀门控制为例&#xff0c;只需要做一个阀门控制界面模板 3.地址引用 # 4.实现效果

【网络运维知识】—路由器与交换机区别

【网络运维知识】—路由器与交换机区别 一、路由器&#xff08;Router&#xff09;和交换机&#xff08;Switch&#xff09;对比1.1 功能1.2 转发方式1.3 范围1.4 处理方式 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 路由器&#xff08…

面试高频:HTTPS 通信流程

更多大厂面试内容可见 -> http://11come.cn 面试高频&#xff1a;HTTPS 通信流程 HTTPS 的加密流程 接下来说一下 HTTPS 协议是如何进行通信的&#xff1a; HTTPS 通信使用的 对称加密 非对称加密 两者结合的算法 HTTPS 通信时&#xff0c;会先使用 非对称加密 让通信双…

深入理解计算机网络:从基本原理到实践应用

前言&#xff1a; 计算机网络是现代信息技术的基石&#xff0c;它连接了全球数以亿计的设备&#xff0c;使得信息传输和资源共享成为可能。本文将从计算机网络的基本原理出发&#xff0c;深入探讨其关键技术&#xff0c;并分享一些实践应用的经验。 一、计算机网络的基本原理 1…

【Qt】Qt界面构建与对象管理:从 “Hello World“ 到内存释放

文章目录 1. 通过图形化界面创建控件2. 通过纯代码方式创建控件3. 对象树管理与内存管理小结&#xff1a; 在软件开发中&#xff0c;构建用户界面是至关重要的一步。Qt作为一个跨平台的C框架&#xff0c;提供了强大的界面构建工具和对象树管理机制&#xff0c;使得界面开发变得…

李宏毅2022机器学习/深度学习 个人笔记(1)

本系列用于推导、记录该系列视频中本人不熟悉、或认为有价值的知识点 本篇记录第一讲&#xff08;选修&#xff09;&#xff1a;神奇宝贝分类 如图&#xff0c;为了估算某个样本属于某类的概率&#xff0c;在二分类问题中&#xff0c;我们需要计算红框所示的4个参数&#xff0…

Linux Centos 9保姆级系统安装教程

文章目录 下载Centos 9镜像文件安装Centos 下载Centos 9镜像文件 清华大学源网址https://mirrors.tuna.tsinghua.edu.cn/ 安装Centos 所需软件&#xff1a;VMware Workstation 16 Pro 版本里面没有Centos 9&#xff1b; 这里我们选择Centos 7同样可以使用 用户设置

Elasticsearch:使用向量化和 FFI/madvise 加速 Lucene

作者&#xff1a;来自 Elastic Chris Hegarty 在 Lucene 领域&#xff0c;我们一直热切地采用新版本 Java 的功能。这些功能使 Lucene 更接近 JVM 和底层硬件&#xff0c;从而提高了性能和稳定性。这使得 Lucene 保持现代化和具有竞争力。 Lucene 的下一个主要版本&#xff0…

RIME-SVM,基于RIME寒冰优化算法优化SVM支持向量机回归预测 (多输入单输出)-附代码

支持向量机&#xff08;SVM&#xff09; 支持向量机&#xff08;SVM&#xff09;是一种广泛用于分类和回归的强大监督学习算法。在回归任务中&#xff0c;特别是在SVM被用作支持向量回归&#xff08;SVR&#xff09;时&#xff0c;目标是找到一个函数&#xff0c;这个函数在给…

Apache Hadoop 输入格式示例

目录 TextInputFormat 示例 SequenceFileInputFormat 示例 总结 TextInputFormat 示例 描述: TextInputFormat 是 Hadoop 中使用最广泛的输入格式之一&#xff0c;适用于纯文本文件。它将文件按行划分&#xff0c;把每一行的起始偏移量作为键&#xff08;key&#xff09;&am…

JDBC学习

DriverManager&#xff08;驱动管理类&#xff09; Drivermanager的作用有&#xff1a; 1.注册驱动&#xff1b; 2.获取数据库连接 Class.forName("com.mysql.cj.jdbc.Driver"); 这一行的作用就是注册Mysql驱动&#xff08;把我们下载的jar包加载到内存里去&…

实现 Android 设备屏幕录制的批处理脚本

在本文中&#xff0c;我们将介绍如何使用批处理脚本来实现在 Android 设备上进行屏幕录制&#xff0c;并将录制的视频文件传输到计算机上。这个脚本利用了 Windows 的批处理脚本和 Android 的 adb 工具。 背景 在进行 Android 应用开发、教学演示或问题排查时&#xff0c;我们…

毕业设计——基于ESP32的智能家居系统(语音识别、APP控制)

ESP32嵌入式单片机实战项目 一、功能演示二、项目介绍1、功能演示2、外设介绍 三、资料获取 一、功能演示 多种控制方式 ① 语音控制 ②APP控制 ③本地按键控制 ESP32嵌入式单片机实战项目演示 二、项目介绍 1、功能演示 这一个基于esp32c3的智能家居控制系统&#xff0c;能实…

使用51单片机控制T0和T1分别间隔1秒2秒亮灭逻辑

#include <reg51.h>sbit LED1 P1^0; // 设置LED1灯的接口 sbit LED2 P1^1; // 设置LED2灯的接口unsigned int cnt1 0; // 设置LED1灯的定时器溢出次数 unsigned int cnt2 0; // 设置LED2灯的定时器溢出次数// 定时器T0 void Init_Timer0() {TMOD | 0x01;; // 定时器…

三、Flask模型基础

ORM 创建模型 # exts.py&#xff1a;插件管理 # 扩展的第三方插件 # 1.导入第三方插件 from flask_sqlalchemy import SQLAlchemy # ORM插件 from flask_migrate import Migrate # 2. 初始化 db SQLAlchemy() # ORM migrate Migrate() # 数据迁移 # 3. 和app对象绑定 def…

Flink的安装、项目创建、任务打包和部署完整实现,任务实现使用JAVA语言

Flink资源下载地址 Flink安装包下载地址 一、本地模式安装Flink 1、在Linux服务上&#xff0c;创建flink文件夹 mkdir flink 2、上传文件并解压 tar -zxvf flink-1.14.6-bin-scala_2.11.tgz 解压完成后&#xff0c;如图&#xff1a; 3、启动Flink 进入到解压目录下&#x…

Css切换不同窗口

代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>Title</title></head><style>/*label {*//* display: block;*//*}*/* {padding: 0;margin: 0;}body {height: 100vh;backgroun…

设计模式之原型模式

1、简单介绍 原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;它通过复制现有的实例来创建新对象&#xff0c;而不是通过调用类的构造函数来创建新实例。这种模式适用于需要快速复制大量相同或相似对象&#xff0c;或者创建对象需要消耗大量…

【图论 单源最短路】100276. 最短路径中的边

本文时间知识点 单源最短路 图论知识汇总 LeetCode100276. 最短路径中的边 给你一个 n 个节点的无向带权图&#xff0c;节点编号为 0 到 n - 1 。图中总共有 m 条边&#xff0c;用二维数组 edges 表示&#xff0c;其中 edges[i] [ai, bi, wi] 表示节点 ai 和 bi 之间有一条…