SpringBoot源码解析(十):应用上下文AnnotationConfigServletWebServerApplicationContext构造方法

SpringBoot源码解析(十):应用上下文AnnotationConfigServletWebServerApplicationContext构造方法

SpringBoot源码系列文章

SpringBoot源码解析(一):SpringApplication构造方法

SpringBoot源码解析(二):引导上下文DefaultBootstrapContext

SpringBoot源码解析(三):启动开始阶段

SpringBoot源码解析(四):解析应用参数args

SpringBoot源码解析(五):准备应用环境

SpringBoot源码解析(六):打印Banner

SpringBoot源码解析(七):应用上下文结构体系

SpringBoot源码解析(八):Bean工厂接口体系

SpringBoot源码解析(九):Bean定义接口体系

SpringBoot源码解析(十):应用上下文AnnotationConfigServletWebServerApplicationContext构造方法


目录

前言

在前文中,我们了解了应用上下文Bean工厂以及Bean定义的核心组件功能,接下来,我们将深入探讨应用上下文的构造方法。

SpringBoot版本2.7.18SpringApplication的run方法的执行逻辑如下,本文将详细介绍第6小节:创建应用程序上下文
// SpringApplication类方法publicConfigurableApplicationContextrun(String... args){// 记录应用启动的开始时间long startTime =System.nanoTime();// 1.创建引导上下文,用于管理应用启动时的依赖和资源DefaultBootstrapContext bootstrapContext =createBootstrapContext();ConfigurableApplicationContext context =null;// 配置无头模式属性,以支持在无图形环境下运行// 将系统属性 java.awt.headless 设置为 trueconfigureHeadlessProperty();// 2.获取Spring应用启动监听器,用于在应用启动的各个阶段执行自定义逻辑SpringApplicationRunListeners listeners =getRunListeners(args);// 启动开始方法(发布开始事件、通知应用监听器ApplicationListener) listeners.starting(bootstrapContext,this.mainApplicationClass);try{// 3.解析应用参数ApplicationArguments applicationArguments =newDefaultApplicationArguments(args);// 4.准备应用环境,包括读取配置文件和设置环境变量ConfigurableEnvironment environment =prepareEnvironment(listeners, bootstrapContext, applicationArguments);// 配置是否忽略 BeanInfo,以加快启动速度configureIgnoreBeanInfo(environment);// 5.打印启动BannerBanner printedBanner =printBanner(environment);// 6.创建应用程序上下文 context =createApplicationContext();// 设置应用启动的上下文,用于监控和管理启动过程 context.setApplicationStartup(this.applicationStartup);// 7.准备应用上下文,包括加载配置、添加 Bean 等prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);// 8.刷新上下文,完成 Bean 的加载和依赖注入refreshContext(context);// 9.刷新后的一些操作,如事件发布等afterRefresh(context, applicationArguments);// 计算启动应用程序的时间,并记录日志Duration timeTakenToStartup =Duration.ofNanos(System.nanoTime()- startTime);if(this.logStartupInfo){newStartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);}// 10.通知监听器应用启动完成 listeners.started(context, timeTakenToStartup);// 11.调用应用程序中的 `CommandLineRunner` 或 `ApplicationRunner`,以便执行自定义的启动逻辑callRunners(context, applicationArguments);}catch(Throwable ex){// 12.处理启动过程中发生的异常,并通知监听器handleRunFailure(context, ex, listeners);thrownewIllegalStateException(ex);}try{// 13.计算应用启动完成至准备就绪的时间,并通知监听器Duration timeTakenToReady =Duration.ofNanos(System.nanoTime()- startTime); listeners.ready(context, timeTakenToReady);}catch(Throwable ex){// 处理准备就绪过程中发生的异常handleRunFailure(context, ex,null);thrownewIllegalStateException(ex);}// 返回已启动并准备就绪的应用上下文return context;}

源码入口

  • 这里核心内容就是new AnnotationConfigServletWebServerApplicationContext()
// 6.创建应用程序上下文 context =createApplicationContext();
在这里插入图片描述
  • 无参构造
publicclassAnnotationConfigServletWebServerApplicationContextextendsServletWebServerApplicationContextimplementsAnnotationConfigRegistry{// 用于读取注解的Bean定义读取器privatefinalAnnotatedBeanDefinitionReader reader;// 用于扫描类路径并注册Bean定义的扫描器privatefinalClassPathBeanDefinitionScanner scanner;...// 无参构造函数publicAnnotationConfigServletWebServerApplicationContext(){// 初始化注解Bean定义读取器this.reader =newAnnotatedBeanDefinitionReader(this);// 初始化类路径Bean定义扫描器this.scanner =newClassPathBeanDefinitionScanner(this);}...}

AnnotationConfigServletWebServerApplicationContext类图如下,其实就是应用上下文核心接口Application的实现类,那么注解Bean定义读取器类路径Bean定义扫描器构造传入的this即Application。

在这里插入图片描述

一、初始化注解Bean定义读取器

publicclassAnnotatedBeanDefinitionReader{// Bean定义注册表,用于管理和注册Bean定义privatefinalBeanDefinitionRegistry registry;// 条件评估器,用于判断是否满足某些条件privateConditionEvaluator conditionEvaluator;// 构造方法,接收BeanDefinitionRegistry作为参数publicAnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry){// 调用带有Environment参数的构造方法,环境对象通过注册表自动创建this(registry,getOrCreateEnvironment(registry));}// 构造方法,接收BeanDefinitionRegistry和Environment作为参数publicAnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry,Environment environment){// 校验参数,确保注册表和环境不为空Assert.notNull(registry,"BeanDefinitionRegistry must not be null");Assert.notNull(environment,"Environment must not be null");// 初始化Bean定义注册表this.registry = registry;// 初始化条件评估器this.conditionEvaluator =newConditionEvaluator(registry, environment,null);// 注册注解配置处理器,用于处理注解配置AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}...}

1、BeanDefinitionRegistry(Bean定义注册接口)

这里的Bean定义注册表BeanDefinitionRegistry就是AnnotatedBeanDefinitionReader构造传入的AnnotationConfigServletWebServerApplicationContext

BeanDefinitionRegistry是Spring容器中用于管理Bean定义的核心接口,支持动态注册移除查询别名管理,常用于扩展和动态操作容器内的 Bean 定义。

// 此接口是 Bean 定义注册的核心,用于动态管理 Bean 定义(注册、移除、查询等)publicinterfaceBeanDefinitionRegistryextendsAliasRegistry{// 向注册表中注册一个新的 BeanDefinitionvoidregisterBeanDefinition(String beanName,BeanDefinition beanDefinition)throwsBeanDefinitionStoreException;// 移除给定名称的 BeanDefinitionvoidremoveBeanDefinition(String beanName)throwsNoSuchBeanDefinitionException;// 返回给定名称的 BeanDefinitionBeanDefinitiongetBeanDefinition(String beanName)throwsNoSuchBeanDefinitionException;// 检查此注册表是否包含具有给定名称的 BeanDefinition。booleancontainsBeanDefinition(String beanName);// 返回此注册表中定义的所有 Bean 的名称String[]getBeanDefinitionNames();// 返回注册表中定义的 Bean 的数量。intgetBeanDefinitionCount();// 确定给定的 Bean 名称是否已经在此注册表中使用(即是否有本地 Bean 或别名注册了此名称)booleanisBeanNameInUse(String beanName);}/** * 管理别名的通用接口(提供了注册、删除、查询别名的方法) * * 别名是一种机制,用于为已有的名称提供额外的标识, * 通常用于配置中增加灵活性,例如为同一个 Bean 定义多个名称 */publicinterfaceAliasRegistry{// 为给定的名称注册一个别名voidregisterAlias(String name,String alias);// 从注册表中删除指定的别名voidremoveAlias(String alias);// 确定给定的名称是否被定义为别名(而不是实际注册的组件名称)booleanisAlias(String name);// 返回给定名称的所有别名(如果定义了别名)String[]getAliases(String name);}

2、获取环境对象Environment

// AnnotatedBeanDefinitionReader类方法privatestaticEnvironmentgetOrCreateEnvironment(BeanDefinitionRegistry registry){// 校验注册表对象不为空Assert.notNull(registry,"BeanDefinitionRegistry must not be null");// 如果注册表实现了EnvironmentCapable接口,则直接获取其中的Environmentif(registry instanceofEnvironmentCapable){return((EnvironmentCapable) registry).getEnvironment();}// 如果注册表不具备Environment,则创建并返回一个标准的Environment对象returnnewStandardEnvironment();}

在创建应用上下文之前,SpringBoot源码解析(五):准备应用环境中有详细介绍应用环境Environment的初始化。

在这里插入图片描述

3、注册注解配置处理器

在这里插入图片描述
publicstaticSet<BeanDefinitionHolder>registerAnnotationConfigProcessors(BeanDefinitionRegistry registry,@NullableObject source){// 获取默认的ListableBeanFactory对象// 这里获取到的就是应用上下文中AnnotationConfigServletWebServerApplicationContext的// 父类GenericApplicationContext的构造中new DefaultListableBeanFactory()DefaultListableBeanFactory beanFactory =unwrapDefaultListableBeanFactory(registry);if(beanFactory !=null){// AnnotationAwareOrderComparator:这是一个带有注解感知的比较器,用来排序Bean的依赖// 它比标准的比较器多了对@Order注解的支持,可以确保按照注解指定的优先级排序依赖关系if(!(beanFactory.getDependencyComparator()instanceofAnnotationAwareOrderComparator)){ beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}// ContextAnnotationAutowireCandidateResolver:这个解析器是用于处理基于注解的自动注入(例如@Autowired注解)// 它负责在自动注入过程中,决定哪些Bean可以作为自动注入的候选者if(!(beanFactory.getAutowireCandidateResolver()instanceofContextAnnotationAutowireCandidateResolver)){ beanFactory.setAutowireCandidateResolver(newContextAnnotationAutowireCandidateResolver());}}// 创建一个 LinkedHashSet 用于存储 BeanDefinitionHolder// BeanDefinitionHolder: 用于持有 BeanDefinition 及其名称和别名Set<BeanDefinitionHolder> beanDefs =newLinkedHashSet<>(8);// 注册 ConfigurationClassPostProcessor,用于处理 @Configuration 注解if(!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)){RootBeanDefinition def =newRootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source);// 注册后置处理器就是将Bean定义添加到bean工厂beanDefinitionMap缓存中,下面细说 beanDefs.add(registerPostProcessor(registry, def,CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}// 注册 AutowiredAnnotationBeanPostProcessor,用于处理 @Autowired 注解if(!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)){RootBeanDefinition def =newRootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def,AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}// 如果 JSR-250 支持存在,注册 CommonAnnotationBeanPostProcessor,用于处理 @Resource 等注解if(jsr250Present &&!registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)){RootBeanDefinition def =newRootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def,COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));}// 如果 JPA 支持存在,注册 PersistenceAnnotationBeanPostProcessor,用于处理 JPA 相关的注解// JPA是一个 Java 标准规范,用于简化对象与关系数据库之间的映射和数据持久化操作if(jpaPresent &&!registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)){RootBeanDefinition def =newRootBeanDefinition();try{ def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader()));}catch(ClassNotFoundException ex){thrownewIllegalStateException("Cannot load optional framework class: "+PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);} def.setSource(source); beanDefs.add(registerPostProcessor(registry, def,PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));}// 注册 EventListenerMethodProcessor,用于处理 @EventListener 注解if(!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)){RootBeanDefinition def =newRootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def,EVENT_LISTENER_PROCESSOR_BEAN_NAME));}// 注册 DefaultEventListenerFactory 是事件监听器的工厂类,它实际负责创建监听器对象并将其注册到 Spring 的事件发布机制中// 当 EventListenerMethodProcessor 找到带有 @EventListener 注解的方法时,它会通过 DefaultEventListenerFactory 创建该方法对应的监听器if(!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)){RootBeanDefinition def =newRootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def,EVENT_LISTENER_FACTORY_BEAN_NAME));}// 返回所有注册的 BeanDefinitionHolderreturn beanDefs;}

3.1、获取默认Bean工厂

这里的registry就是注解应用上下文AnnotationConfigServletWebServerApplicationContext,从上面的类图可知GenericApplicationContext是父类之一。

// AnnotationConfigUtils类方法@NullableprivatestaticDefaultListableBeanFactoryunwrapDefaultListableBeanFactory(BeanDefinitionRegistry registry){if(registry instanceofDefaultListableBeanFactory){return(DefaultListableBeanFactory) registry;}elseif(registry instanceofGenericApplicationContext){return((GenericApplicationContext) registry).getDefaultListableBeanFactory();}else{returnnull;}}
在这里插入图片描述

DefaultListableBeanFactory是Spring框架中的一个核心类,负责管理创建应用上下文中的所有Bean,提供了Bean定义的注册、查找和生命周期管理功能。

publicclassDefaultListableBeanFactoryextendsAbstractAutowireCapableBeanFactoryimplementsConfigurableListableBeanFactory,BeanDefinitionRegistry,Serializable{// ==================== 核心属性 ====================// 存储所有注册的 BeanDefinition,键为 beanName,值为对应的 BeanDefinitionprivatefinalMap<String,BeanDefinition> beanDefinitionMap =newConcurrentHashMap<>(256);// 记录所有注册的beanName,保持注册顺序(通过配置文件、注解、或约定方式将 Bean 注册到容器中,由 Spring 自动完成)privatevolatileList<String> beanDefinitionNames =newArrayList<>(256);...}
获取到默认Bean工厂以后,设置了两个重要属性

AnnotationAwareOrderComparator:这是一个带有注解感知的比较器,用来排序Bean的依赖。它比标准的比较器多了对@Order注解的支持,可以确保按照注解指定的优先级排序依赖关系。

ContextAnnotationAutowireCandidateResolver:这个解析器是用于处理基于注解的自动注入(例如@Autowired注解)。它负责在自动注入过程中,决定哪些Bean可以作为自动注入的候选者。

3.2、注册后置处理器(注册Bean定义)

上面创建了很多RootBeanDefinition,这些Bean定义只做Spring内部使用,用于处理注解配置
  • ConfigurationClassPostProcessor,用于处理@Configuration@Bean@Import@ComponentScan等注解
  • AutowiredAnnotationBeanPostProcessor,用于处理@Autowired@Value注解
  • CommonAnnotationBeanPostProcessor,用于处理@PostConstruct@PreDestroy@Resource注解
  • EventListenerMethodProcessor,用于处理@EventListener注解
创建完RootBeanDefinition后,还需要将其添加到应用上下文缓存

Bean定义的角色设置为2,表示框架内部的实现类,用户无需关心,平常我们创建的组件默认角色就是0,用于实现具体的业务逻辑。

// AnnotationConfigUtils类方法privatestaticBeanDefinitionHolderregisterPostProcessor(BeanDefinitionRegistry registry,RootBeanDefinition definition,String beanName){ definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);// 注册Bean定义 registry.registerBeanDefinition(beanName, definition);returnnewBeanDefinitionHolder(definition, beanName);}

BeanDefinitionRegistry registry是应用上下文,调用注册Bean定义方法registerBeanDefinition,实际就是调用默认Bean工厂的注册Bean定义的方法,上面有提到默认Bean工厂DefaultListableBeanFactory核心属性beanDefinitionMap就是存储所有注册的BeanDefinition

在这里插入图片描述

二、初始化类路径Bean定义扫描器

1、注册默认注解过滤器

通过ClassPathBeanDefinitionScanner的构造方法,最终跳转到最后一个构造方法,核心操作是注册默认的注解扫描过滤器

在这里插入图片描述

注册默认的注解过滤器,确保在组件扫描时,能够识别特定的注解。添加@Component注解的过滤器,允许扫描带有@Component注解的类,@Controller@Service@Repository也会被扫描到。

// ClassPathScanningCandidateComponentProvider类方法protectedvoidregisterDefaultFilters(){// 添加 @Component 注解的过滤器,允许扫描带有 @Component 注解的类this.includeFilters.add(newAnnotationTypeFilter(Component.class));// @Component 是 Spring 框架的通用组件注解(只关心这个就可以)// @ManagedBean 是 Java EE 的托管 Bean 注解// 而 @Named 是 CDI(Jakarta EE)的标准化注解// 获取类加载器ClassLoader cl =ClassPathScanningCandidateComponentProvider.class.getClassLoader();try{// 尝试加载 javax.annotation.ManagedBean 注解类,如果存在,添加为过滤器this.includeFilters.add(newAnnotationTypeFilter(((Class<?extendsAnnotation>)ClassUtils.forName("javax.annotation.ManagedBean", cl)),false)); logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");}catch(ClassNotFoundException ex){// 如果 JSR-250 API 未找到,跳过该注解支持}try{// 尝试加载 javax.inject.Named 注解类,如果存在,添加为过滤器this.includeFilters.add(newAnnotationTypeFilter(((Class<?extendsAnnotation>)ClassUtils.forName("javax.inject.Named", cl)),false)); logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");}catch(ClassNotFoundException ex){// 如果 JSR-330 API 未找到,跳过该注解支持}}

2、自定义包扫描

此方法将在后续通过传入包路径调用,并返回注册的Bean定义集合。具体源码后续调用时候详细

protectedSet<BeanDefinitionHolder>doScan(String... basePackages){// 检查 basePackages 是否为空,如果为空则抛出异常Assert.notEmpty(basePackages,"At least one base package must be specified");// 用于存储扫描到的 Bean 定义Set<BeanDefinitionHolder> beanDefinitions =newLinkedHashSet<>();// 遍历传入的每个包路径进行扫描for(String basePackage : basePackages){// 查找当前包路径下符合条件的候选组件Set<BeanDefinition> candidates =findCandidateComponents(basePackage);// 遍历候选组件for(BeanDefinition candidate : candidates){// 获取该 Bean 定义的作用域元数据,并设置作用域ScopeMetadata scopeMetadata =this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName());// 生成 Bean 的名称String beanName =this.beanNameGenerator.generateBeanName(candidate,this.registry);// 如果候选 Bean 是 AbstractBeanDefinition 类型,进行后处理if(candidate instanceofAbstractBeanDefinition){postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);}// 如果候选 Bean 是 AnnotatedBeanDefinition 类型,处理注解配置if(candidate instanceofAnnotatedBeanDefinition){AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);}// 如果当前 Bean 名称和定义符合要求,则继续处理if(checkCandidate(beanName, candidate)){// 创建一个 BeanDefinitionHolder 来包装 Bean 定义和 Bean 名称BeanDefinitionHolder definitionHolder =newBeanDefinitionHolder(candidate, beanName);// 根据作用域元数据,可能应用代理模式 definitionHolder =AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder,this.registry);// 将处理好的 Bean 定义添加到集合中 beanDefinitions.add(definitionHolder);// 将 Bean 定义注册到容器中registerBeanDefinition(definitionHolder,this.registry);}}}// 返回所有注册的 Bean 定义return beanDefinitions;}

总结

本文详细介绍了SpringBoot应用上下文AnnotationConfigServletWebServerApplicationContext的构造方法中初始化两个重要组件:一是注解Bean定义读取器,创建一些特殊Bean定义(Spring内部使用,也叫后置处理器),用于处理@Configuration、@Autowired等注解;二是类路径Bean定义扫描器,用于扫描给定路径下的@Component注解组件,将其转换为Bean定义。

Read more

Lychee-Rerank部署教程:国产化信创环境(统信UOS+申威CPU)适配方案

Lychee-Rerank部署教程:国产化信创环境(统信UOS+申威CPU)适配方案 1. 项目简介与背景 Lychee-Rerank是一个专门用于检索相关性评分的本地工具,它基于成熟的推理逻辑和Qwen2.5-1.5B模型开发而成。这个工具的核心功能是帮助用户评估查询语句与文档内容之间的匹配程度,为文档检索和排序提供量化依据。 在实际应用中,我们经常需要从大量文档中快速找到与特定查询最相关的内容。传统的关键词匹配方法往往不够精准,而基于深度学习的相关性评分能够更好地理解语义层面的关联。Lychee-Rerank正是为了解决这个问题而设计,它能够在完全离线的环境下运行,确保数据隐私和安全。 该工具特别适配了国产化信创环境,包括统信UOS操作系统和申威CPU架构,为国内用户提供了完整的本地化解决方案。无论是企业知识库检索、文档管理系统,还是学术研究中的文献筛选,Lychee-Rerank都能提供准确可靠的相关性评分服务。 2. 环境准备与依赖安装 2.1 系统要求 在开始部署之前,请确保您的系统满足以下基本要求: * 操作系统:统信UOS 20及以上版本 * CP

Java Web 网上服装商城系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

Java Web 网上服装商城系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

系统架构设计### 摘要 随着互联网技术的快速发展和电子商务的普及,网上服装商城已成为消费者购买服装的主要渠道之一。传统的线下服装销售模式受限于时间和空间,难以满足现代消费者多样化和便捷化的需求。网上服装商城系统通过互联网平台打破了地域限制,提供了24小时不间断的购物体验,同时降低了商家的运营成本。此外,大数据分析和个性化推荐技术的应用进一步提升了用户的购物体验和商家的销售效率。关键词:电子商务、服装商城、互联网技术、个性化推荐、大数据分析。 本系统采用SpringBoot2作为后端框架,结合Vue3前端框架,实现了前后端分离的开发模式,提升了系统的可维护性和扩展性。数据库选用MySQL8.0,通过MyBatis-Plus简化了数据操作,提高了开发效率。系统功能包括用户管理、商品分类与展示、购物车管理、订单处理、支付接口集成以及后台管理模块。用户可以通过注册登录浏览商品,加入购物车并完成支付;管理员则可以对商品、订单和用户信息进行管理。系统还集成了第三方支付接口,确保交易的安全性和便捷性。关键词:SpringBoot2、Vue3、MyBatis-Plus、MySQL8.0、支付接口

Qwen3-Reranker-0.6B效果展示:多轮对话历史融合Query的动态重排序能力

Qwen3-Reranker-0.6B效果展示:多轮对话历史融合Query的动态重排序能力 你是不是遇到过这种情况:向一个智能助手提问,它第一次回答得不太对,你补充了更多信息,或者换了个说法又问了一遍,结果它还是给你一堆和第一次差不多的、不太相关的文档?问题可能就出在“重排序”这个环节上。 传统的重排序模型,通常只盯着你最新提出的那个问题(Query)和一堆候选文档(Document)看,然后给它们打分、排序。它就像一个健忘的图书管理员,你每次来借书,他都只记得你刚才说的最后一句话,完全忘了你之前问过什么、聊过什么。这在多轮对话里,效果就会大打折扣。 今天,我们就来实际看看,一个能“记住”对话历史的轻量级重排序模型——Qwen3-Reranker-0.6B,是如何工作的。它不仅能理解你当前的问题,还能巧妙地融合之前的对话历史,让最终的文档排序更精准、更智能。 1. 什么是“融合对话历史”的重排序? 简单来说,这就像你和朋友聊天。如果你只说“它怎么样?”,朋友肯定一头雾水。但如果你之前聊过“

【GitHub项目推荐--Happy Coder:Claude Code的移动端与Web客户端】⭐⭐⭐

简介 Happy Coder 是一个为Claude Code和Codex设计的移动端和Web客户端,支持实时语音功能、端到端加密,功能齐全。该项目由slopus团队开发,旨在让开发者能够随时随地监控和控制他们的AI编程助手。 🔗 GitHub地址 : https://github.com/slopus/happy 📱 核心价值 : 移动访问 · 实时监控 · 端到端加密 · 多设备切换 · 开源透明 项目背景 : * 移动办公 :远程工作需求增长 * AI编程 :AI编程助手普及 * 设备切换 :多设备协同需求 * 隐私安全 :代码安全需求 * 开发者工具 :开发者工具创新 项目特色 : * 📱 移动访问 :手机访问Claude Code * ⚡ 实时同步 :实时状态同步 * 🔐 端到端加密 :完全加密保护 * 🔔 推送通知 :智能推送提醒 * 🔄 设备切换 :无缝设备切换 技术亮点 : * 加密技术 :端到端加密 * 实时通信 :实时数据同步