Spring源码分析:refresh()

news2024/10/5 16:19:16

refresh()中共有13个方法,分别为

1.prepareRefresh()

容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等

   protected void prepareRefresh() {
		//spring启动时间
		this.startupDate = System.currentTimeMillis();
		//spring标记为未关闭
		this.closed.set(false);
		//spring激活状态
		this.active.set(true);
		//记录日志
		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}
		//点进去会发现没有任何内容,是个方法扩展点。留给子类覆盖,初始化属性资源
		initPropertySources();
		// 创建并获取环境对象,验证需要的属性文件是否都已经放入环境中
		getEnvironment().validateRequiredProperties();
		// 判断刷新前的应用程序监听器集合是否为空,如果为空,则将监听器添加到此集合中
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
		//如果不等于空,则清空集合元素对象
			this.applicationListeners.clear();
	this.applicationListeners.addAll(this.earlyApplicationListeners);
		}
		// 创建刷新前的监听事件集合
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

2.obtainFreshBeanFactory()

obtainFreshBeanFactory方法主要作用:创建BeanFactory对象,并解析xml封装成BeanDefinition对象。(获取新的beanFactory,销毁原有beanFactory、为xml中定义的每个bean生成BeanDefinition等,注意此处是获取新的,销毁旧的,这就是刷新的意义)

补充:如果Spring注册bean采用注解的形式,此方法中AnnotatedBeanDefinitionReader仅仅只是将我们的启动类转化为BeanDefinition注册到spring容器的BeanDefinitionMap中,后续在执行BeanFactoryPostProcessor时,会以此为起点,开始扫描项目中的Controller、Service等等注册到容器中。

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
...
  			//			* 1、创建BeanFactory对象
			//			* 2、xml解析
			//			* 	传统标签解析:bean、import等
			//			* 	自定义标签解析 如:<context:component-scan base-package="com.xiangxue.jack"/>
			//			* 	自定义标签解析流程:
			//			* 		a、根据当前解析标签的头信息找到对应的namespaceUri
			//			* 		b、加载spring所以jar中的spring.handlers文件。并建立映射关系
			//			* 		c、根据namespaceUri从映射关系中找到对应的实现了NamespaceHandler接口的类
			//			* 		d、调用类的init方法,init方法是注册了各种自定义标签的解析类
			//			* 		e、根据namespaceUri找到对应的解析类,然后调用paser方法完成标签解析
			//			*
			//			* 3、把解析出来的xml标签封装成BeanDefinition对象
		protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
			   // 1.刷新 BeanFactory,由AbstractRefreshableApplicationContext实现,初始化beanFactory,并执行加载和解析配置操作
				refreshBeanFactory();
				//返回beanFactory实例
				return getBeanFactory();
		}
...
}


为什么先创建BeanFactory对象,再加载解析xml文件,顺序不能反过来吗?
因为加载解析xml文件,生成的BeanDefinition对象,需要存放在BeanFactory的BeanDefinitionMap中,故需要先创建BeanFactory。

3.prepareBeanFactory(beanFactory)

beanFactory的准备工作,对各种属性进行填充,对 beanFactory 进行功能扩展,如增加 SPEL 支持和属性编辑器等

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        //设置类加载器:存在则直接设置/不存在则新建一个默认类加载器
        beanFactory.setBeanClassLoader(getClassLoader());
 
       //设置EL表达式解析器(Bean初始化完成后填充属性时会用到)
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
 
       //设置属性注册解析器PropertyEditor
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
 
     // 将当前的ApplicationContext对象交给ApplicationContextAwareProcessor类来处理,从而在Aware接口实现类中的注入applicationContext
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
 
        //设置忽略自动装配的接口
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
 
        //注册可以解析的自动装配
        // MessageSource registered (and found for autowiring) as a bean.
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
 
        //如果当前BeanFactory包含loadTimeWeaver Bean,说明存在类加载期织入AspectJ,则把当前BeanFactory交给类加载期BeanPostProcessor实现类LoadTimeWeaverAwareProcessor来处理,从而实现类加载期织入AspectJ的目的。
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // Set a temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
 
        //注册当前容器环境environment组件Bean
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
 
       //注册系统配置systemProperties组件Bean
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
 
       //注册系统环境systemEnvironment组件Bean
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
    }

4.postProcessBeanFactory(beanFactory)

空方法,留给子类扩展

5.invokeBeanFactoryPostProcessors(beanFactory)

作用:调用Bean工厂的后置处理器

/*
 * BeanDefinitionRegistryPostProcessor
* BeanFactoryPostProcessor
* Bean工厂的后置处理器 、完成对这两个接口的调用
* * */
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        //传入Bean工厂并获取容器中的Bean工厂后置处理器(注意这里Bean工厂后置处理器还没有初始化)
        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 (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }


6.registerBeanPostProcessors(beanFactory)

作用:把实现了 BeanPostProcessor接口的类实例化并注册到工厂.

BeanPostProcessor接口是Spring中一个非常重要的接口,它的接口定义如下:

public interface BeanPostProcessor {

    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
当你实现了这个接口的时候,Spring会保证在每一个bean对象初始化方法调用之前调用postProcessBeforeInitialization方法,在初始化方法调用之后调用postProcessAfterInitialization


public static void registerBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    //获取BeanFactory中注册的类型为BeanPostProcessor.class的bean名称。一般获取到的是实现了BeanPostProcessor接口的Bean
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // BeanPostProcessor的目标计数
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    // 添加BeanPostProcessorChecker(主要用于记录信息)到beanFactory中
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    // 将BeanPostProcessors分为实现了PriorityOrdered接口,Ordered接口、普通的类型
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();

    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            // 如果ppName对应的Bean实例实现了PriorityOrdered接口, 则拿到ppName对应的Bean实例并添加到priorityOrderedPostProcessors
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                //如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,
                // 则将ppName对应的Bean实例添加到internalPostProcessors
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            //如果ppName对应的Bean实例没有实现PriorityOrdered接口, 但是实现了Ordered接口, 则将ppName添加到orderedPostProcessorNames
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }
    // 对priorityOrderedPostProcessors进行排序
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // priorityOrderedPostProcessors
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    // 注册实现Ordered接口的BeanPostProcessors
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    // 排序
    sortPostProcessors(orderedPostProcessors, beanFactory);
    // 注册
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);
    // 注册所有常规的BeanPostProcessors
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
    // 最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾)
    // 排序
    sortPostProcessors(internalPostProcessors, beanFactory);
    // 注册
    registerBeanPostProcessors(beanFactory, internalPostProcessors);
    // 加入ApplicationListenerDetector
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

7.initMessageSource()

主要作用:是初始化国际化文件。

8.initApplicationEventMulticaster()

初始化应用的事件广播器

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    // 判断BeanFactory是否已经存在事件广播器(固定使用beanName=applicationEventMulticaster)
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        // 如果已经存在,则将该bean赋值给applicationEventMulticaster
        this.applicationEventMulticaster =
                beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        if (logger.isDebugEnabled()) {
            logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    } else {
        // 如果不存在,则使用SimpleApplicationEventMulticaster
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        // 并将SimpleApplicationEventMulticaster作为默认的事件广播器,注册到BeanFactory中
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                    APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                    "': using default [" + this.applicationEventMulticaster + "]");
        }
    }
}

9.onRefresh()

空方法,用于子类扩展

10.registerListeners()

注册监听器(在所有注册的bean中查找bean listener,注册到消息广播器中)

protected void registerListeners() {
    // Register statically specified listeners first.
    // 1.通过硬编码调用addApplicationListener方法添加的监听器处理(可以通过自定义ApplicationContextInitializer添加)
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }
 
    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let post-processors apply to them!
    // 2.通过配置文件或注解注入BeanFactory的监听器处理
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }
 
    // Publish early application events now that we finally have a multicaster...
    // 3.使用事件广播器,发布早期应用程序事件到相应的监听器
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

AppicationContext的事件机制是观察者模式的实现,按以下方式可以实现。
首先我们需要自定义一个事件类,此事件类是需要继承ApplicationEvent类
然后我们定义一个监听类,监听类作为一个Spring容器中的bean,同时需要实现ApplicationListner接口
然后我们就可以使用ApplicationContext的实例发布事件,相应监听类的实例(bean)负责监听具体的事件

11.finishBeanFactoryInitialization(beanFactory)

简单来说,就是实例化剩下的非懒加载的单实例对象
(即实例化bean,以及在bean的实例化通过各种各样的后置处理器完成bean的增强。)

如果想实例化,前提是不能是抽象类,不能是接口,非懒加载, 而且针对FactoryBean还有不同的处理模式

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// Initialize conversion service for this context.
    // 为上下文初始化类型转换器
	if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
			beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
		beanFactory.setConversionService(
				beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
	}

    // 检查上下文中是否存在类型转换器
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
	}
    // 尽早初始化LoadTimeWeaverAware bean,以便尽早注册它们的转换器。
	// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		getBean(weaverAwareName);
	}

	// Stop using the temporary ClassLoader for type matching.
    // 禁止使用临时类加载器进行类型匹配
	beanFactory.setTempClassLoader(null);

	// Allow for caching all bean definition metadata, not expecting further changes
    // 允许缓存所有的bean的定义数据
	beanFactory.freezeConfiguration();

	// Instantiate all remaining (non-lazy-init) singletons.
    // 准备实例化bean
	beanFactory.preInstantiateSingletons();
}

在这里插入图片描述

该方法中使用反射创建了bean实例;然后调用populateBean()方法填充属性,将各个属性值注入,其中可能存在依赖于其他bean的属性,则会递归初始化依赖的bean;执行aware接口所对应的方法;然后执行BeanPostProcessor:before,init-method方法,BeanPostProcessor:after方法。

12.finishRefresh()

完成刷新过程,通知声明周期处理器LifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人

将这12个方法,按作用简单划分一下:

1 为准备环境
2 3 4 5 6 为准备 BeanFactory
7 8 9 10 12 为准备 ApplicationContext
11 为初始化 BeanFactory 中非延迟单例 bean

在这里插入图片描述

https://blog.csdn.net/weixin_47061482/article/details/115406213
https://segmentfault.com/a/1190000020494692

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

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

相关文章

01 Redis的特性+下载安装启动+Redis自动启动+客户端连接

1.1 NoSQL NoSQL&#xff08;“non-relational”&#xff0c; “Not Only SQL”&#xff09;&#xff0c;泛指非关系型的数据库。 键值存储数据库 &#xff1a; 就像 Map 一样的 key-value 对。如Redis文档数据库 &#xff1a; NoSQL 与关系型数据的结合&#xff0c;最像关系…

Python如何获取程序打包后的目录,如何获取管理员权限

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 实现步骤 📒📝 获取程序打包后所在目录📝 获取管理员权限⚓️ 相关链接 ⚓️📖 介绍 📖 Python 是一种功能强大的编程语言,本篇文章将介绍Python如何获取程序打包后所在目录,以及如何获取管理员权限并执行需要管理…

【深度学习】sdxl中的 tokenizer tokenizer_2 区别

代码仓库&#xff1a; https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/tree/main 截图&#xff1a; 为什么有两个分词器 tokenizer 和 tokenizer_2&#xff1f; 在仔细阅读这些代码后&#xff0c;我们了解到 tokenizer_2 主要是用于 refiner 模型的。 #…

javax.servlet.http包

javax.servlet.http包 javax.srvlet.http包是对javax.servlet包的扩展。该包的类和接口处理使用HTTP进行通信的servlet。这些servlet也称为HTTP Servlet。您需要扩展HttpServlet类来开发HTTP Servlet。javax.servlet.http包经常使用的接口包括: HttpServletRequest接口HttpSe…

Windows10上通过MSYS2编译FFmpeg 6.1.1源码操作步骤

1.从github上clone代码&#xff0c;并切换到n6.1.1版本&#xff1a;clone到D:\DownLoad目录下 git clone https://github.com/FFmpeg/FFmpeg.git git checkout n6.1.1 2.安装MSYS2并编译FFmpeg源码: (1).从https://www.msys2.org/ 下载msys2-x86_64-20240113.exe &#…

x-cmd pkg | shtris - 命令行俄罗斯方块游戏

目录 简介首次用户技术特点竞品和相关作品进一步阅读 简介 shtris 是一个由 shell 脚本&#xff0c;参考 俄罗斯方块指南 (2009) 实现的俄罗斯方块游戏。 首次用户 使用 x shtris 即可自动下载并使用 在终端运行 eval "$(curl https://get.x-cmd.com)" 即可完成 x …

[TCP协议]基于TCP协议的字典服务器

目录 1.TCP协议简介: 2.TCP协议在Java中封装的类以及方法 3.字典服务器 3.1服务器代码: 3.2客户端代码: 1.TCP协议简介: TCP协议是一种有连接,面向字节流,全双工,可靠的网络通信协议.它相对于UDP协议来说有以下几点好处: 1.它是可靠传输,相比于UDP协议,传输的数据更加可靠…

在ubuntu上在安装Squid代理服务器

Squid 是一个代理和缓存服务器&#xff0c;它将请求转发到所需的目的地&#xff0c;同时保存请求的内容&#xff0c;当你再次请求相同内容时&#xff0c;他可以向你提供缓冲内容&#xff0c;从而提高访问速度。Squid代理服务器目前支持的协议有&#xff1a;http、SSL、DNS、FTP…

【机组】单元模块的软件简介和安装

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《机组 | 模块单元实验》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 目录 【软件简介和安装】 1 性能特…

JVM篇:垃圾回收算法

标记清除 通过遍历GC Root后得到不再被引用的对象&#xff0c;对没被引用的对象做一个标记处理&#xff0c;然后对其进行清除。 优点&#xff1a;速度快 缺点&#xff1a;会产生内存碎片&#xff0c;可能会导致空闲的内存足够保存对象&#xff0c;但由于不连续而保存失败。 标…

Linux操作系统运维-用户与用户组管理

Linux操作系统运维-用户与用户组管理 用户种类与标识查看 超级用户&#xff08;root&#xff09;&#xff1a;可以不受限制地执行所有操作&#xff0c;拥有系统最高权限&#xff0c;修改系统设置与管理用户均需要root权限系统用户&#xff08;system&#xff09;&#xff1a;…

S275智慧煤矿4G物联网网关:矿山开采的未来已来

随着经济发展煤矿需求不断激增&#xff0c;矿山矿井普遍处于偏远山区&#xff0c;生产管理、人员安全、生产效率是每个矿山矿井都需要考虑的问题&#xff0c;利用网关对现场终端设备连接组网&#xff0c;实现智慧煤矿远程管理。 各矿山矿井分布范围比较广泛&#xff0c;户外环…

Leetcode541反转字符串Ⅱ(java实现)

我们今天分享的题目是字符串反转的进阶版反转字符串Ⅱ。 我们首先来看题目描述&#xff1a; 乍一看题目&#xff0c;有种懵逼的感觉&#xff0c;不要慌&#xff0c;博主来带着你分析题目&#xff0c;题目要求&#xff1a; 1. 每隔2k个字符&#xff0c;就对2k字符中的前k个字符…

【mongoDB】创建用户账号和权限

使用use database_name 命令创建或切换到一个数据库 查看用户 show users 输入该命令后&#xff0c;无数据表示该数据库没有用户 创建用户 user:" freedom " 表示用户名为freedom pwd:" 123456 ” 表示密码为123456 roles:[" root "] …

pcl之滤波器(三)

pcl滤波器 pcl一共是有十二个主要模块&#xff0c;详细了解可以查看官网。https://pcl.readthedocs.io/projects/tutorials/en/latest/#basic-usage 今天学习一下pcl的滤波器模块。 滤波器模块&#xff0c;官网一共是提供了6个例程&#xff0c;今天看第五个、第六个。 从一…

CSS设置单行文字水平垂直居中的方法

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>单行文字水平垂直居中</title><style>div {/* 给div设置宽高 */width: 400px;height: 200px;margin: 100px auto;background-color: red;/…

【深度学习每日小知识】Bias 偏差

计算机视觉是人工智能的一个分支&#xff0c;它使机器能够解释和分析视觉信息。然而&#xff0c;与任何人造技术一样&#xff0c;计算机视觉系统很容易受到训练数据产生的偏差的影响。计算机视觉中的偏见可能会导致不公平和歧视性的结果&#xff0c;从而使社会不平等长期存在。…

[GYCTF2020]Ezsqli1

打开环境&#xff0c;下面有个提交表单 提交1&#xff0c;2有正确的查询结果&#xff0c;3以后都显示Error Occured When Fetch Result. 题目是sql&#xff0c;应该考察的是sql注入 简单fuzz一下 发现information_schema被过滤了&#xff0c;猜测是盲注了。 测试发现只要有东…

【MySQL】学习如何通过DML更新数据库的数据

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-QIqURn9fNFMjLD9l {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

火车票车票查询-Python

一、相关代码 # Time: 2024/1/22 20:24 # Author: 马龙强 # File: 实现12306查票购票.py # software: PyCharm """网址&#xff1a;https://www.12306.cn/index/ 数据&#xff1a;车次信息 查票链接&#xff1a;https://kyfw.12306.cn/otn/leftTicket/queryE?…