Spring容器的心脏:深度解析refresh()手段(上)

news/2025/11/7 18:05:04/文章来源:https://www.cnblogs.com/yxysuanfa/p/19200541

在 Spring 框架的广袤世界中,有一个方法堪称整个 IoC 容器的“创世”基石。它,就是 ApplicationContext.refresh()。无论你使用的是传统的 XML 配置,还是现代化的 Spring Boot,最终都会汇集到这个方法上,由它来点燃整个应用上下文的生命之火。这个方法看似只是一个简单的 refresh 调用,但其内部却隐藏着一个精密而复杂的启动流程。今天,我们将深入其中,一同揭开这十二个标准步骤的神秘面纱,探究 Spring 容器从初始化到就绪的完整诞生记。

准备阶段 - 环境准备与前期检查

this.startupShutdownLock.lock();
this.startupShutdownThread = Thread.currentThread();
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 主要步骤:
prepareRefresh();                    // 准备刷新
obtainFreshBeanFactory();           // 获取BeanFactory
prepareBeanFactory(beanFactory);    // 准备BeanFactory

首先我们来看看第一阶段准备阶段所干的事情,准备阶段主要是为BeanFactory进行环境的准备和工厂的初始化。首先获取当前的lock锁用来保证整个执行过程中的线程安全,其次获取当前执行的线程,目的是将当前启动线程进行绑定,后续容器关闭的时候需要对当前线程进行校验是否为启动线程,也就是说要保证整个容器操作的线程一致性。

这行看似简单的代码实际上是Spring容器生命周期线程安全的重要保障。它确保了:

  1. 启动和关闭操作的线程一致性

  2. 防止意外的跨线程关闭操作

  3. 为容器生命周期提供可靠的线程追踪

随后的第一个方法则是prepareRefresh

prepareRefresh

protected void prepareRefresh() {// Switch to active.this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);if (logger.isDebugEnabled()) {if (logger.isTraceEnabled()) {logger.trace("Refreshing " + this);}else {logger.debug("Refreshing " + getDisplayName());}}// Initialize any placeholder property sources in the context environment.initPropertySources();// Validate that all properties marked as required are resolvable:// see ConfigurablePropertyResolver#setRequiredPropertiesgetEnvironment().validateRequiredProperties();// Store pre-refresh ApplicationListeners...if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);}else {// Reset local application listeners to pre-refresh state.this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}// Allow for the collection of early ApplicationEvents,// to be published once the multicaster is available...this.earlyApplicationEvents = new LinkedHashSet<>();}

我们可以看到首先设置了两个spring容器的标志位,随后initPropertySources方法它的核心作用在于初始化和管理应用运行时所依赖的环境属性源(PropertySources)。在AbstractApplicationContext中是一个空方法而是留给子类去实现这个方法。

initPropertySources

其中主要功能则是添加自定义属性源

@Override
protected void initPropertySources() {// 获取标准环境对象ConfigurableEnvironment env = getEnvironment();// 创建自定义属性源(例如从数据库、远程配置中心读取)Map myProperties = new HashMap<>();myProperties.put("jdbc.url", "jdbc:mysql://localhost:3306/myapp");myProperties.put("api.key", "secret-key-123");// 将自定义属性源添加到环境的最前面(最高优先级)env.getPropertySources().addFirst(new MapPropertySource("myCustomPropertySource", myProperties));System.out.println("自定义属性源已加载,JDBC URL: " + env.getProperty("jdbc.url"));
}

验证必需属性 && 属性源优先级调整

@Override
protected void initPropertySources() {ConfigurableEnvironment env = getEnvironment();// 验证这些必需属性是否已设置,如果没有则抛出异常env.getRequiredProperty("database.url"); // 如果不存在,会抛出 IllegalStateExceptionenv.getRequiredProperty("security.oauth2.client-id");// 或者使用更灵活的方式if (!env.containsProperty("mandatory.config")) {throw new IllegalStateException("必须在启动前设置 'mandatory.config' 属性");}
}
@Override
protected void initPropertySources() {ConfigurableEnvironment env = getEnvironment();MutablePropertySources propertySources = env.getPropertySources();// 将系统环境变量移到系统属性之前PropertySource systemEnv = propertySources.remove("systemEnvironment");if (systemEnv != null) {propertySources.addAfter("systemProperties", systemEnv);}
}

initPropertySources() 方法是 Spring 环境准备阶段的关键扩展点,主要承担三大职责:

  1. 属性源定制 - 添加自定义的属性来源

  2. 属性验证 - 确保必需配置的存在性

  3. 优先级控制 - 调整属性查找顺序

保存监听器状态并初始化早期事件收集机制

		// Store pre-refresh ApplicationListeners...if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);}else {// Reset local application listeners to pre-refresh state.this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}// Allow for the collection of early ApplicationEvents,// to be published once the multicaster is available...this.earlyApplicationEvents = new LinkedHashSet<>();

在容器刷新伊始,通过保存监听器的初始快照和创建临时事件缓冲区,为Spring事件机制建立一个安全的启动状态,确保在完整的事件广播器就绪之前,所有的监听器状态和早期事件都能得到妥善管理和后续处理。

简单来说,它就像为Spring的事件系统设置了一个安全的"启动准备区":保存好监听器的初始阵容,同时准备好一个临时储物柜来存放过早产生的事件,等到事件广播器这个"舞台"搭建完成后,再让演员(监听器)就位、把暂存的道具(事件)搬上舞台正式演出。

  1. 状态保存 - 保存应用监听器的初始状态,支持容器多次刷新

  2. 事件缓冲 - 为广播器初始化前产生的事件提供临时存储

  3. 时序保障 - 解决 Spring 启动过程中的依赖时序问题

  4. 容错处理 - 确保在复杂的启动过程中事件机制仍能正常工作

维度earlyApplicationListenersapplicationListeners
生效时机容器初始化早期(refresh() 方法初期)容器完全初始化后(refresh() 方法完成后)
监听事件类型早期内部事件(如环境准备、Bean 定义加载等)常规事件(如容器刷新、关闭、自定义事件等)
注册来源主要由 Spring 内部注册主要由用户自定义注册(也可包含内部监听器)
容器状态依赖不依赖容器完全初始化,可在早期阶段工作依赖容器完成初始化,确保 Bean 等资源可用

总结

因此prepareRefresh主要作用是准备容器刷新的前期工作,包括初始化上下文环境、验证必要的系统属性是否存在、初始化早期事件监听器集合(earlyApplicationListeners)并保存容器启动时的活跃标志,为后续的 Bean 定义加载、容器初始化等核心流程奠定基础,确保容器能在一个就绪的状态下开始刷新操作。

obtainFreshBeanFactory

obtainFreshBeanFactory() 方法是 Spring 容器 refresh() 流程中的关键步骤,主要作用是获取一个 “新鲜” 的(即最新状态的)BeanFactory

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();return getBeanFactory();}

而我们看到整个方法实际上只执行了两个业务逻辑刷新BeanFactory和获取BeanFactory

	protected final void refreshBeanFactory() throws BeansException {if (hasBeanFactory()) {destroyBeans();closeBeanFactory();}try {DefaultListableBeanFactory beanFactory = createBeanFactory();beanFactory.setSerializationId(getId());customizeBeanFactory(beanFactory);loadBeanDefinitions(beanFactory);this.beanFactory = beanFactory;}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);}}

在这个refreshBeanFactory方法中首先则是判断当前容器是否含有BeanFactory,如果有则会对其进行销毁和清除,然后重新new一个新的BeanFactory,随后设置一些属性。其中最重要的则是loadBeanDefinitions这个方法,这个方法的作用则是加载所有的beanDefinition到本容器中去。

在 Spring Boot 中,loadBeanDefinitions方法的调用主要围绕 **AnnotatedBeanDefinitionReader** 展开,它是处理注解驱动配置(Spring Boot 的默认配置方式)的核心BeanDefinitionReader。其他BeanDefinitionReader(如XmlBeanDefinitionReader)仅在特定场景(如引入 XML 配置)中被使用,并非默认主选。

// AnnotatedBeanDefinitionReader.java
@Override
public int loadBeanDefinitions(Class... componentClasses) {Assert.notEmpty(componentClasses, "At least one component class must be specified");int count = 0;for (Class componentClass : componentClasses) {// 注册单个注解类,本质是加载其BeanDefinitionif (registerBean(componentClass)) {count++;}}
}
// 内部调用registerBean,最终触发doRegisterBean解析注解并注册
private boolean registerBean(Class beanClass) {doRegisterBean(beanClass, null, null, null, null);return true;
}

Spring 容器无法直接识别外部配置(如 @Component 注解、applicationContext.xml 中的 <bean> 标签),loadBeanDefinitions 的本质就是充当 “翻译官” 和 “注册员”:

  1. 读取外部配置源:从指定的配置位置(如类路径、文件系统、注解扫描路径等)读取 Bean 的配置信息。
  2. 解析为 BeanDefinition:将配置信息(如 Bean 的类名、作用域、依赖关系、初始化方法等)解析为 Spring 内部标准的 BeanDefinition 对象(可理解为 “Bean 的元数据模板”,包含了创建 Bean 所需的所有信息)。
  3. 注册到 BeanFactory:将解析后的 BeanDefinition 通过 BeanFactory 的 registerBeanDefinition() 方法注册到工厂中,后续容器可通过 BeanFactory 查找、创建 Bean 实例。

loadBeanDefinitions 并非单一实现,而是通过不同的 BeanDefinitionReader(Bean 定义读取器) 适配多种配置方式

配置方式对应的 BeanDefinitionReader核心解析逻辑
XML 配置(如 <bean>XmlBeanDefinitionReader解析 XML 文件中的 <bean> 标签、<context:component-scan> 等标签,提取 Bean 元数据。
注解配置(如 @ComponentAnnotatedBeanDefinitionReader + ClassPathBeanDefinitionScanner1. 扫描指定包路径下的类;2. 识别带有 @Component@Service 等注解的类;3. 自动生成对应的 BeanDefinition
Java 配置类(如 @ConfigurationConfigurationClassBeanDefinitionReader解析 @Configuration 类中的 @Bean 方法,将每个 @Bean 方法转换为一个 BeanDefinition

总结

因此整个obtainFreshBeanFactory执行的逻辑则是,如果含有BeanFactory则销毁原来的并且重写创建一个新的BeanFactory,进行属性赋值随后调用loadBeanDefinitions 来完成BeanDefinition的加载,而这个BeanDefinition加载则是依靠BeanDefinitionReader来对一个个Bean进行封装为BeanDefinition。

prepareBeanFactory

在 Spring 框架中,prepareBeanFactory 是 AbstractApplicationContext 类中的一个核心方法,用于在容器初始化阶段对 BeanFactory(Spring 的核心 bean 容器)进行预处理和配置,为后续的 bean 定义加载、bean 实例化及依赖注入等操作奠定基础。

// AbstractApplicationContext.java
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 1. 设置BeanFactory的类加载器(默认使用当前上下文的类加载器)beanFactory.setBeanClassLoader(getClassLoader());// 2. 设置表达式解析器(用于解析SpEL表达式,如@Value("#{systemProperties['user.name']}"))beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));// 3. 注册属性编辑器注册表(用于将配置中的字符串转换为对应类型,如日期字符串→Date对象)beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// 4. 添加ApplicationContextAwareProcessor后置处理器:// 用于处理实现了Aware接口的bean(如EnvironmentAware、ResourceLoaderAware等),// 在bean初始化时自动注入对应的上下文资源(如环境变量、资源加载器)beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 5. 忽略某些接口的自动依赖注入:// 这些接口的实现类依赖由ApplicationContextAwareProcessor手动注入,无需BeanFactory自动处理beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// 6. 注册默认的依赖解析规则:// 当bean依赖以下类型时,自动注入容器自身的实例beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// 7. 添加ApplicationListenerDetector后置处理器:// 用于检测实现了ApplicationListener接口的bean,并将其注册到容器的事件发布器中beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// 8. 如果存在LoadTimeWeaver(用于类加载时织入,如AspectJ),则配置BeanFactory支持它if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// 设置临时类加载器,用于织入期间的类加载beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// 9. 注册默认的环境相关bean(如果尚未注册):// 如environment(环境变量)、systemProperties(系统属性)、systemEnvironment(系统环境变量)if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}
}

查看源码我们可以看到

首先是在BeanFactory当中设置了类加载器classloader,目的是为BeanFactory指定用于加载 bean 类定义的类加载器(ClassLoader)。

随后则是加入了表达式解析器和编辑器注册表这两个类的作用则是保证BeanFactory可以识别 Spring 表达式语言(SpEL)和将配置中的字符串转换为目标类型(如DateResource等),归根结底则是为了支持注解(及其他配置方式)在依赖注入时的功能实现—— 前者用于解析表达式,后者用于处理类型转换,二者是注解生效的 “基础设施”,但不负责 “识别注解” 本身。

然后则是addBeanPostProcessor添加了一个后置处理器,这个后置处理器ApplicationContextAwareProcessor的作用则是处理开发者自定义实现的Aware接口的实现类

之后则是调用了一系列的ignoreDependencyInterface方法用对于实现了上述Aware接口的 bean,不要对这些接口的方法进行自动依赖注入,目的是为了确保Aware接口的依赖注入逻辑由专门的处理器统一管理,避免注入混乱,保证bean.setXxx(...)回调的正确性,若BeanFactory对这些接口进行 “自动依赖注入”(比如通过类型匹配寻找依赖),会与ApplicationContextAwareProcessor的手动注入冲突,导致重复注入或错误

随后则是有一系列的registerResolvableDependency方法,

registerResolvableDependency(Class<?> type, Object value)的逻辑是:当容器中存在 bean 需要注入type类型的依赖时,无需从容器中查找该类型的 bean,直接使用value作为注入值

beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));随后则是注册事件监听器检测器到BeanFactory中去

  • ApplicationListenerDetector是一个BeanPostProcessor(后置处理器),会在 bean 初始化后执行:
    1. 检查 bean 是否实现了ApplicationListener
    2. 若是,则将其添加到ApplicationContext的事件发布器(ApplicationEventMulticaster)中,使其能接收并处理事件。
 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// 设置临时类加载器,用于织入期间的类加载beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}

当容器中存在LoadTimeWeaver(类加载时织入器)时,配置BeanFactory支持类加载阶段的字节码增强(如 AOP 切面织入、AspectJ 编译期增强)。支持需要在类加载阶段进行字节码增强的场景(如 AOP 的 “加载时织入”),扩展 Spring 的动态代理能力。

if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
// ... 注册systemProperties、systemEnvironment、applicationStartup

BeanFactory注册 4 个核心环境相关的单例 bean,供其他 bean 注入使用。提供 “开箱即用” 的环境配置访问能力,其他 bean 可通过@Autowired Environment env@Value("${systemProperties.user.name}")等方式直接使用这些核心配置对象,简化配置获取逻辑。

总结

prepareBeanFactory 方法的整体作用可以总结为:为 BeanFactory 构建完整的 “基础运行环境”,通过配置核心能力、规范依赖规则、注册关键组件,使其从一个 “空白容器” 升级为能够支撑 Spring 核心功能(如注解驱动、依赖注入、事件机制等)的 “功能完备的 bean 管理中心”。具体可归纳为以下 5 点核心作用:

  1. 配置基础能力组件为 BeanFactory 装配类加载器、SpEL 表达式解析器、属性编辑器等 “基础设施”,确保其能完成类加载、表达式求值、类型转换等基础操作(例如解析 @Value 注解中的表达式、将配置字符串转换为 Date 等类型)。

  2. 规范依赖注入规则

    • 明确 Aware 接口的依赖由专门处理器(ApplicationContextAwareProcessor)手动注入,避免 BeanFactory 自动注入冲突;
    • 注册容器核心组件(BeanFactoryApplicationContext 等)的依赖解析规则,让 bean 能便捷注入容器自身资源。
  3. 激活容器扩展机制注册事件监听器检测器(ApplicationListenerDetector),自动识别并激活 ApplicationListener 接口的事件监听能力,支撑 Spring 的事件发布与订阅机制(如容器刷新、关闭等事件的处理)。

  4. 支持高级功能扩展配置 LoadTimeWeaver 相关支持,为类加载时的字节码增强(如 AOP 织入、AspectJ 增强)提供基础,扩展容器的动态代理与切面能力。

  5. 注册核心环境组件内置 Environment(环境配置)、系统属性、系统环境变量等核心对象作为单例 bean,供其他 bean 直接注入使用,简化配置访问与环境交互。

registerResolvableDependency 和 registerSingleton的区别

  • registerResolvableDependency(Class<?> type, Object value)用于注册 “依赖解析规则”:当容器需要注入type类型的依赖时,直接使用value作为注入值,而无需从容器中查找该类型的 bean。它本质是 **“定向依赖映射”**,不将value注册为容器中的正式 bean,仅用于解决特定类型的依赖注入。

  • registerSingleton(String beanName, Object singletonObject)用于向容器注册一个正式的单例 bean:将singletonObjectbeanName为标识注册到容器中,使其成为容器管理的 bean,可通过getBean(beanName)获取,也会参与依赖注入、生命周期管理等。

维度registerResolvableDependencyregisterSingleton
注册内容注册 “类型→对象” 的映射规则,不将value作为 bean 管理注册一个正式的单例 bean,singletonObject是容器中的 bean
是否为正式 beanvalue不被视为容器中的 bean,不会出现在getBeanNamesForType等结果中singletonObject是正式 bean,可通过getBean获取
依赖注入场景仅影响 “type类型依赖” 的注入,其他场景(如按名称获取)不受影响既可以按类型注入,也可以按名称获取,完全参与 bean 生命周期
主要用途解决 “容器核心组件(如BeanFactoryApplicationContext)的依赖注入”,避免手动注册这些组件为 bean注册系统级别的单例 bean(如Environment、系统属性等),供应用直接使用

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

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

    相关文章

    原神概率模型假说

    众所周知,原神是一款由米哈游自主研发的开放世界冒险游戏 在原神等游戏中我们常常被抽卡概率所困扰,以至于人们研究出了种种玄学抽卡不歪的方法,在此我也提出一个猜想: 从米哈游的角度考虑,他肯定想要赚取更多的钱…

    距离高考一年纪念文章

    这个周是高考前的最后一个周了,周二晚上第二节晚自习后就看到高三楼那边开始玩灯,整个楼的灯都在开开关关,更是有人从窗上往下扔纸飞机,后来看到很多同学都跑到高三楼下去围观,拿着手电筒进行着一些人类难以理解的…

    #深度学习基础:神经网络基础与PyTorch - 实践

    #深度学习基础:神经网络基础与PyTorch - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &q…

    忘了哪个地方忘了哪次考试创新题调整法

    简明题干:在这样第一象限的这个三角形内 ( 含边界 ) 内有 \(n\) 个点,其中第 \(i\) 个点记为 \((x_i,y_i)\),现将这 \(n\) 个点划分成两个集合 \(A,B\),记 \(A\) 集合中的点的横坐标之和为 \(X(A)\),\(B\) 集合中…

    2025 年最新推荐充电桩源头厂家排行榜:高新技术认证企业领衔,权威测评优选品质之选电动车充电桩/家用充电桩/超级充电桩公司推荐

    引言 随着新能源汽车保有量持续攀升,充电桩作为关键配套基础设施,市场需求呈爆发式增长,行业却面临产品质量参差不齐、技术水平差异大等问题。近期,行业权威协会开展充电桩源头厂家专项测评,从资质认证、技术实力…

    external_url 高可用相同 主从复制 不同。

    external_url 是 Harbor 的外部访问地址。主从配置相同 external_url:如果是高可用集群:这是正确且必需的配置。所有实例共享后端状态(数据库、Redis、存储),并通过负载均衡器对外。如果是主从复制:这是错误的配…

    P3830 [SHOI2012] 随机树

    P3830 [SHOI2012] 随机树 题目 题目描述 一棵含 \(n\) 个叶结点的二叉树可以通过如下方式生成。初始时只有根结点。首先,将根结点展开(本题中的“展开”是指给一个叶结点添上左、右两个子结点): 然后,等概率地随机…

    NORDIC蓝牙6.0新品NRF54L15多协议超低功耗高性能BLE芯片

    NORDIC蓝牙6.0新品NRF54L15多协议超低功耗高性能BLE芯片NRF54L15,NRF54L10,NRF54L05 是NORDIC推出的高性能,多协议,低功耗BLE6.0芯片 产品简介 增强的多协议支持 nRF54L 系列支持低功耗蓝牙、蓝牙 Mesh、Thread、M…

    国产SUB-1G芯片DP4363F支持119-1050mhz超低功耗

    国产SUB-1G芯片DP4363F支持119-1050mhz超低功耗DP4363是一款高性能、低电流的收发器,覆盖了从119MHZ到1050MHz的频段。它是系列完整发射器、接收器和收发器产品中的组成部分,适用于各种广泛的应用场景。该设备具有卓…

    elasticsearch-head-chrome插件

    https://files.cnblogs.com/files/stubborn-dude/elasticsearch-head-chrome插件.zip?t=1762508308&download=true

    NOIP 模拟赛 3 比赛总结

    分数:\(100 + 60 + 0 + 10 = 170\) T4 最终结果没取模,挂了 60 分!永康喵喵又翻车了! T1 一道不太水的水题。 这道题要求满足 \(1 \le i < j < k < l \le n\) 且 \(a_i \oplus a_j \oplus a_k \oplus a_l…

    2025年云南GEO优化公司权威推荐榜单:seo优化/网站seo优化/百家号源头公司精选

    在生成式AI技术重塑搜索生态的背景下,GEO已成为企业抢占智能流量入口的核心战略。据行业数据显示,2025年中国GEO市场规模已突破200亿元,年复合增长率高达67%,超过78%的企业将其纳入核心增长战略。云南作为西南地区…

    易基因:中国海洋大学隋正红团队揭示m6A修饰调控植物生长和光合作用的表观转录机制|项目文章

    大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 近日,中国海洋大学海洋生物遗传学与育种教育部重点实验室朱智梅博士为第一作者,隋正红教授为通讯作者在《Harmful Algae》期刊发表题为“Effects o…

    ORACLE游标序列化

    ORACLE游标序列化 ORACLE中可以直接调用接口,需要把数据构造成xml格式,方便请求参数构造.比如在使用select utl_http.request(http://www.baidu.com) from dual可以访问百度页面 1. 使用DBMS_XMLGEN序列化 declarectx …

    iqoo手机关掉视频彩铃

    打开中国联通APP 搜索视频彩铃找到 我的彩铃功能,并且关闭视频彩铃功能不久之后,会收到关闭成功的短信通知。本文来自博客园,作者:imzhi,转载请注明原文链接:https://www.cnblogs.com/imzhi/p/19200523

    2025低烟无卤/UL3302/UL3767/UL4413辐照线厂家推荐明秀电子,品质卓越!

    2025低烟无卤/UL3302/UL3767/UL4413辐照线厂家推荐明秀电子,品质卓越! 随着全球安全环保标准的不断提升,低烟无卤线缆市场正迎来爆发式增长。据统计数据显示,2024年全球低烟无卤线缆市场规模已突破300亿美元,预计…

    企业品牌管理:它是什么以及如何掌握它

    公司最有价值的资产并非总是其产品或服务,往往是其品牌。强大的企业品牌能够塑造消费者认知、培养忠诚度并推动长期业务成功。它超越了简单的标识和标语,影响着从客户到投资者等所有利益相关者对公司的整体看法。有效…

    Http压缩编码导致数据乱码

    在一次项目上线时,发现部分接口请求失败,但是无返回数据是会成功的问题。 开始排查 一开始以为是通信加解密导致的问题,但是部分接口可以,部分接口报错,又排除了这个选项。 于是考虑是网关问题,还是服务端代码问…

    未来出行智慧车联网与智慧交通方案 NRF9151

    ​随着5G、物联网(IoT)、人工智能(AI)和大数据技术的快速发展,车联网(IoV)与智慧交通已成为智慧城市建设的重要组成部分。通过智能芯片与先进通信技术的应用,车联网与智慧交通正在深刻改变人们的出行方式,推动…

    32

    所学时间:9时间 博客量:1 代码量:1oo 所学知识:人机交互实验,机器学习