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

DefaultListableBeanFactory

文章目录

    • DefaultListableBeanFactory介绍
    • 继承关系
    • 源码码解析
      • 属性成员
      • getbean方法
      • setAutowireCandidateResolver方法
      • resolveDependency方法
        • doResolveDependency方法
        • findAutowireCandidates 方法
        • determineAutowireCandidate 方法

DefaultListableBeanFactory介绍

BeanFactory是个Factory,也就是IOC容器或对象工厂,而DefaultListableBeanFactory是Bean工厂的一个默认实现,DefaultListableBeanFactory提供了原始的BeanFactory的功能,如:对外提供getBean()方法,维护一张beanDefinitionMap

继承关系

DefaultListableBeanFactory继承关系如下,可以看出DefaultListableBeanFactory还有子类XmlBeanFactory
在这里插入图片描述
接口实现
下图列出了DefaultListableBeanFactory的接口实现和继承图,DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,并且实现BeanFactory接口,提供了基本的BeanFactory功能。

BeanDefinitionRegistry是一个接口,它定义了关于BeanDefinition的注册、移除、查询等一系列的操作。

BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
在这里插入图片描述

源码码解析

属性成员

beanDefinitionMapDefaultListableBeanFactory作为BeanFactory默认是维护这一张beanDefinition的表。

/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

getbean方法

DefaultListableBeanFactory是Bean工厂的一个默认实现,DefaultListableBeanFactory是Bean工厂的一个默认实现。截取DefaultListableBeanFactory中与getBean方法。

可以发现getBean有两种方式获取bean:

  • 根据名称获取Bean,这个方法继承于AbstractBeanFactory
  • 根据类型获取Bean,这个方法实现于DefaultListableBeanFactory,属于扩展了getBean方式
   //---------------------------------------------------------------------
// Implementation of remaining BeanFactory methods
//---------------------------------------------------------------------
//这个方式属于是扩展了getBean的方式,通过类型获取Bean
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {return getBean(requiredType, (Object[]) null);
}@SuppressWarnings("unchecked")
@Override
public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {Assert.notNull(requiredType, "Required type must not be null");//根据类型解析beanObject resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);if (resolved == null) {throw new NoSuchBeanDefinitionException(requiredType);}return (T) resolved;
}

setAutowireCandidateResolver方法

这是一个普通的set方法,为什么我还要介绍它呢,因为这个set方法能启动扩展DefaultListableBeanFactory的功能。通过该方法给DefaultListableBeanFactory扩展自动装配的解析器。

可以通过该方法添加格外的自动装配解析器,如:QualifierAnnotationAutowireCandidateResolver提供@Qualifier注解解析的功能和@Autowire

/*** Set a custom autowire candidate resolver for this BeanFactory to use* when deciding whether a bean definition should be considered as a* candidate for autowiring.*/
public void setAutowireCandidateResolver(AutowireCandidateResolver autowireCandidateResolver) {Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null");if (autowireCandidateResolver instanceof BeanFactoryAware) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);return null;}, getAccessControlContext());}else {((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);}}this.autowireCandidateResolver = autowireCandidateResolver;
}

resolveDependency方法

resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set<String> autowiredBeanNames, TypeConverter typeConverter)方法,找到对应的依赖 Bean,获取 Bean 的实例对象时,构造器注入的参数也是通过该方法获取的,依赖注入底层也是通过该方法实现的,这里我们对该方法一探究竟

// DefaultListableBeanFactory.java
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {// <1> 设置参数名称探测器,例如通过它获取方法参数的名称descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());// <2> 如果依赖类型为 Optional 类型if (Optional.class == descriptor.getDependencyType()) {// 调用 `createOptionalDependency(...)` 方法,先将 `descriptor` 注入表述器封装成 NestedDependencyDescriptor 对象// 底层处理和下面的 `5.2` 相同return createOptionalDependency(descriptor, requestingBeanName);}// <3> 否则,如果依赖类型为 ObjectFactory 或 ObjectProvider 类型else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) {// 返回一个 DependencyObjectProvider 私有内部类对象,并没有获取到实例的 Bean,需要调用其 getObject() 方法获取目标对象return new DependencyObjectProvider(descriptor, requestingBeanName);}// <4> 否则,如果依赖类型为 javax.inject.Provider 类型else if (javaxInjectProviderClass == descriptor.getDependencyType()) {// 返回一个 Jsr330Provider 私有内部类对象,该对象也继承 DependencyObjectProviderreturn new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);}// <5> 否则,通用的处理逻辑else {// <5.1> 先通过 AutowireCandidateResolver 尝试获取一个代理对象,延迟依赖注入则会返回一个代理对象Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);// <5.2> 如果上面没有返回代理对象,则进行处理,调用 `doResolveDependency(...)` 方法if (result == null) {result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);}return result;}
}
doResolveDependency方法
// DefaultListableBeanFactory.java
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {// 设置当前线程的注入点,并返回上次的注入点,属于嵌套注入的一个保护点InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);try {// <1> 针对给定的工厂给定一个快捷实现的方式,暂时忽略// 例如考虑一些预先解析的信息,在进入所有 Bean 的常规类型匹配算法之前,解析算法将首先尝试通过此方法解析快捷方式Object shortcut = descriptor.resolveShortcut(this);if (shortcut != null) {// 返回快捷的解析信息return shortcut;}// 依赖的类型Class<?> type = descriptor.getDependencyType();// <2> 获取注解中的 value 对应的值,例如 @Value、@Qualifier 注解配置的 value 属性值,注意 @Autowired 没有 value 属性配置Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);if (value != null) {if (value instanceof String) {// <2.1> 解析注解中的 value,因为可能是占位符,需要获取到相应的数据String strVal = resolveEmbeddedValue((String) value);BeanDefinition bd = (beanName != null && containsBean(beanName) ?getMergedBeanDefinition(beanName) : null);value = evaluateBeanDefinitionString(strVal, bd);}TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());try {// <2.2> 进行类型转换,并返回return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());}catch (UnsupportedOperationException ex) {// A custom TypeConverter which does not support TypeDescriptor resolution...return (descriptor.getField() != null ?converter.convertIfNecessary(value, type, descriptor.getField()) :converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));}}// <3> 解析复合的依赖对象(Array、Collection、Map 类型),获取该属性元素类型的 Bean 们// 底层和第 `4` 原理一样,这里会将 `descriptor` 封装成 MultiElementDescriptor 类型Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);if (multipleBeans != null) {return multipleBeans;}// <4> 查找与类型相匹配的 Bean 们// 返回结果:key -> beanName;value -> 对应的 BeanMap<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);// <5> 如果一个都没找到if (matchingBeans.isEmpty()) {// <5.1> 如果 @Autowired 配置的 required 为 true,表示必须,则抛出异常if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);}// <5.2> 否则,返回一个空对象return null;}String autowiredBeanName;Object instanceCandidate;// <6> 如果匹配的 Bean 有多个,则需要找出最优先的那个if (matchingBeans.size() > 1) {// <6.1> 找到最匹配的那个 Bean,通过 @Primary 或者 @Priority 来决定,或者通过名称决定autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);if (autowiredBeanName == null) {if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {// <6.2> 如果没有找到最匹配的 Bean,则抛出 NoUniqueBeanDefinitionException 异常return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);}else {// In case of an optional Collection/Map, silently ignore a non-unique case:// possibly it was meant to be an empty collection of multiple regular beans// (before 4.3 in particular when we didn't even look for collection beans).return null;}}// <6.3> 获取到最匹配的 Bean,传值引用给 `instanceCandidate`instanceCandidate = matchingBeans.get(autowiredBeanName);}// <7> 否则,只有一个 Bean,则直接使用其作为最匹配的 Beanelse {// We have exactly one match.Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();autowiredBeanName = entry.getKey();instanceCandidate = entry.getValue();}// <8> 将依赖注入的 Bean 的名称添加至方法入参 `autowiredBeanNames` 集合,里面保存依赖注入的 beanNameif (autowiredBeanNames != null) {autowiredBeanNames.add(autowiredBeanName);}// <9> 如果匹配的 Bean 是 Class 对象,则根据其 beanName 依赖查找到对应的 Beanif (instanceCandidate instanceof Class) {instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);}Object result = instanceCandidate;if (result instanceof NullBean) {if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);}result = null;}if (!ClassUtils.isAssignableValue(type, result)) {throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());}// <10> 返回依赖注入的 Beanreturn result;}finally {// 设置当前线程的注入点为上一次的注入点,因为本次注入结束了ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);}
}
findAutowireCandidates 方法
// DefaultListableBeanFactory.java
protected Map<String, Object> findAutowireCandidates(@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {// <1> 从当前上下文找到该类型的 Bean 们(根据类型)String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, true, descriptor.isEager());// <2> 定义一个 Map 对象 `result`,用于保存符合条件的 BeanMap<String, Object> result = new LinkedHashMap<>(candidateNames.length);/*** <3> 遍历 Spring 内部已处理的依赖对象集合,可以跳到 AbstractApplicationContext#prepareBeanFactory 方法中看看* 会有一下几个内置处理对象:* BeanFactory 类型 -> 返回 DefaultListableBeanFactory* ResourceLoader、ApplicationEventPublisher、ApplicationContext 类型 ->  返回 ApplicationContext 对象*/for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {Class<?> autowiringType = classObjectEntry.getKey();if (autowiringType.isAssignableFrom(requiredType)) {Object autowiringValue = classObjectEntry.getValue();autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);if (requiredType.isInstance(autowiringValue)) {result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);break;}}}// <4> 遍历第 `1` 步找到的 Bean 的名称们for (String candidate : candidateNames) {// <4.1> 如果满足下面两个条件,则添加至 `result` 集合中if (!isSelfReference(beanName, candidate) // 如果不是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)&& isAutowireCandidate(candidate, descriptor)) { // 符合注入的条件addCandidateEntry(result, candidate, descriptor, requiredType);}}// <5> 如果没有找到符合条件的 Bean,则再尝试获取if (result.isEmpty()) {boolean multiple = indicatesMultipleBeans(requiredType);// Consider fallback matches if the first pass failed to find anything...DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();// <5.1> 再次遍历第 `1` 步找到的 Bean 的名称们for (String candidate : candidateNames) {// <5.2> 如果满足下面三个条件,则添加至 `result` 集合中if (!isSelfReference(beanName, candidate) // 如果不是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)&& isAutowireCandidate(candidate, fallbackDescriptor) // 符合注入的条件&& (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) { // 不是复合类型,或者有 @Qualifier 注解addCandidateEntry(result, candidate, descriptor, requiredType);}}// <6> 如果还没有找到符合条件的 Bean,则再尝试获取// 和上面第 `5` 步的区别在于必须是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)if (result.isEmpty() && !multiple) {// Consider self references as a final pass...// but in the case of a dependency collection, not the very same bean itself.for (String candidate : candidateNames) {if (isSelfReference(beanName, candidate)&& (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate))&& isAutowireCandidate(candidate, fallbackDescriptor)) {addCandidateEntry(result, candidate, descriptor, requiredType);}}}}// <7> 返回 `result`,符合条件的 Beanreturn result;
}
determineAutowireCandidate 方法

determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor)方法,找到最匹配的那个依赖注入对象,如下:

@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {Class<?> requiredType = descriptor.getDependencyType();// <1> 尝试获取一个 @Primary 注解标注的 Bean,如果有找到多个则会抛出异常String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);// <2> 如果第 `1` 步找到了则直接返回if (primaryCandidate != null) {return primaryCandidate;}// <3> 尝试找到 @Priority 注解优先级最高的那个 Bean,如果存在相同的优先级则会抛出异常String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);// <4> 如果第 `3` 步找到了则直接返回if (priorityCandidate != null) {return priorityCandidate;}// Fallback// <5> 兜底方法,遍历所有的 Beanfor (Map.Entry<String, Object> entry : candidates.entrySet()) {String candidateName = entry.getKey();Object beanInstance = entry.getValue();// <5.1> 如果满足下面其中一个条件则直接返回if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) // 该 Bean 为 Spring 内部可处理的 Bean,例如 ApplicationContext|| matchesBeanName(candidateName, descriptor.getDependencyName())) { // 名称相匹配return candidateName;}}// <6> 上面都没选出来则返回一个空对象return null;
}

相关文章:

DefaultListableBeanFactory

文章目录 DefaultListableBeanFactory介绍继承关系源码码解析属性成员getbean方法setAutowireCandidateResolver方法resolveDependency方法doResolveDependency方法findAutowireCandidates 方法determineAutowireCandidate 方法 DefaultListableBeanFactory介绍 BeanFactory是…...

软件工程面试题(三十二)

1、java程序每天12点打印”hello” public static void main(String[] args) {Date date = new Date(); System.out.println(date.getHours()); while (true) {while (date.getHours() == 12) {if (date.getMinutes() == 0) {if (date.getSeconds() == 0) {System.out.print…...

高频面试题(含笔试高频算法整理)基本总结回顾66

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…...

生成式人工智能(AIGC):内容创作的新引擎与新挑战

在数字化时代&#xff0c;内容创作的需求呈爆炸式增长。无论是社交媒体、新闻媒体、广告营销还是娱乐行业&#xff0c;都急需大量高质量的文本、图像、音频和视频内容。然而&#xff0c;传统的内容创作方式面临着效率低下、成本高昂、创意枯竭等问题。生成式人工智能&#xff0…...

Java 大视界 -- 基于 Java 的大数据分布式计算在气象数据处理与天气预报中的应用进展(176)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

react和vue在开发使用的语法上面有什么区别?

React和Vue在开发使用的语法上有诸多区别&#xff0c;下面从组件定义、数据绑定、事件处理、生命周期钩子等方面详细阐述&#xff1a; 1. 组件定义 React&#xff1a; 函数组件是React推荐的组件定义方式&#xff0c;它本质上是一个JavaScript函数&#xff0c;返回JSX元素。类…...

ReFormX:现代化的 React 表单解决方案 - 深度解析与最佳实践

ReFormX文档 表单开发一直是前端工作中最繁琐却又最常见的任务之一。从简单的登录表单到复杂的多步骤配置页面&#xff0c;开发者往往需要编写大量重复代码&#xff0c;处理繁琐的状态管理、数据验证和联动逻辑。ReFormX 应运而生&#xff0c;它不仅是一个表单组件库&#xff…...

STM32单片机入门学习——第19节: [6-7]TIM编码器接口

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.04.06 STM32开发板学习——第19节: [6-7]TIM编码器接口 前言开发板说明引用解答和科普一…...

Spring 中的 bean 生命周期

&#x1f331; 一、什么是 Bean 生命周期&#xff1f; 在 Spring 容器中&#xff0c;一个 Bean 从“创建 → 初始化 → 使用 → 销毁”&#xff0c;经历了完整的生命周期。 Spring 提供了 多个扩展点 让你可以在这些阶段做事情&#xff0c;比如注入资源、日志记录、连接资源、清…...

Kafka 在 k8s 中的消费者实例

每个 Pod&#xff08;在 K8s 中运行的消费者实例&#xff09;都会作为一个独立的消费者加入到 Kafka 消费者组中。 如果只是将消费者代码在 K8s 中复制多个实例&#xff08;例如通过增加副本数&#xff09;&#xff0c;每个实例都会作为一个独立的消费者加入到 Kafka 消费者组…...

野草云防火墙风险分析及 Docker 使用注意事项

在实际使用野草云服务器部署 Docker 服务过程中&#xff0c;我发现了一个非常容易被忽视但极具风险的安全问题——野草云的防火墙逻辑与 Docker 默认行为之间存在冲突&#xff0c;如果配置不当&#xff0c;可能会导致容器服务被意外暴露在公网&#xff0c;甚至绕过你设置的“拒…...

C++中高精度运算问题

前言&#xff1a;在备赛蓝桥杯时&#xff0c;遇到C处理数值较大的浮点数问题&#xff0c;特此记录一下。 C 的 std::string 类使用动态内存分配&#xff0c;其长度可以根据需要动态增加或减少&#xff0c;自动调整内存大小以适应字符串内容的变化。当字符串长度超过当前分配的…...

开篇 - 配置Unlua+VsCode的智能提示、调试以及学习方法

智能提示 为要绑定Lua的蓝图创建模板文件&#xff0c;这会在Content/Script下生成lua文件 然后点击生成智能代码提示&#xff0c;这会在Plugins/Unlua/Intermediate/生成Intenllisense文件夹 打开VSCode,点击文件->将工作区另存为。生成一个空工作区&#xff0c;放置在工程…...

前端快速入门学习4——CSS盒子模型、浮动、定位

一、盒子模型 所有HTML元素可以看作盒子&#xff0c;在CSS中&#xff0c;"box model"这一术语是用来设计和布局时使用。 CSS盒模型本质上是一个盒子&#xff0c;封装周围的HTML元素&#xff0c;它包括&#xff1a;边距&#xff0c;边框&#xff0c;填充&#xff0c…...

在 ASP.NET Web Forms 项目中,编译后可能找不到 `Login.aspx.cs` 的源码文件的原因?

在 ASP.NET Web Forms 项目中&#xff0c;确实存在一种情况&#xff1a;编译后可能找不到 Login.aspx.cs 的源码文件。以下是对此现象的详细分析和解释&#xff1a; 1. 已知信息 您提供的 Web.config 文件显示这是一个 ASP.NET Web Forms 项目。在 ASP.NET 中&#xff0c;.asp…...

centos7 yum install docker 安装错误

1、错误信息&#xff1a; [rootlocalhost atguigu]# yum install docker 已加载插件&#xff1a;fastestmirror, langpacks Repository base is listed more than once in the configuration Loading mirror speeds from cached hostfile Could not retrieve mirrorlist http:…...

spring mvc异步请求 sse 大文件下载 断点续传下载Range

学习连接 异步Servlet3.0 Spring Boot 处理异步请求&#xff08;DeferredResult 基础案例、DeferredResult 超时案例、DeferredResult 扩展案例、DeferredResult 方法汇总&#xff09; spring.io mvc Asynchronous Requests 官网文档 spring.io webflux&webclient官网文…...

Java项目集成大模型(通译千问)

1&#xff1a;打开阿里云搜索 通义大模型&#xff0c;然后点击丰富开发API接口。 2&#xff1a;可以看到有openAi和DashScope两种模式&#xff0c;我们这次采用DashScope方法&#xff0c;点击DashScope 3&#xff1a;点击获取Apikey 然后点击 前往我得Api-key跳转到控制台&…...

Lisp语言的安全协议

Lisp语言与安全协议的结合 引言 在信息社会的今天&#xff0c;数据的安全性和隐私保护愈发重要。随着网络攻击手段的不断演进&#xff0c;各种安全协议相继被提出与实现。与此同时&#xff0c;Lisp作为一种古老且灵活的计算机编程语言&#xff0c;虽然并不是主流的系统编程语…...

【图像处理基石】什么是自动曝光(AE)?

1. 什么是自动曝光&#xff08;AE&#xff09;&#xff1f; 自动曝光&#xff08;Auto Exposure, AE&#xff09;是一种通过调整相机参数&#xff08;如曝光时间、增益、光圈等&#xff09;使图像亮度达到目标值的技术。其核心是通过实时分析图像亮度&#xff0c;动态优化参数…...

清明假期间

1.思维导图 2.90题 3. #include <iostream> #include <cstring> #include <cstdlib> #include <unistd.h> #include <sstream> #include <vector> #include <memory>using namespace std;class Weapon;class Hero{ private:int hp;…...

el-tabs添加按钮增加点击禁止样式

前置文章 一、vue使用element-ui自定义样式思路分享【实操】 二、vue3&ts&el-tabs多个tab表单校验 现状确认 点击添加按钮&#xff0c;没有点击样式&#xff0c;用户感知不明显没有限制最大的tab添加数量&#xff0c;可以无限添加 调整目标&代码编写 调整目标…...

Elasticsearch DSL 中的 aggs 聚合

一、聚合的概述 Elasticsearch 的 聚合&#xff08;Aggregations&#xff09; 功能用于对数据进行多维分析和统计&#xff0c;支持从简单的指标计算到复杂的分组分析。以下是聚合的基本结构&#xff1a; {"aggs": { // 也可以使用"agg…...

API调用类型全面指南:理解基础知识

在当今快速发展的数字化环境中&#xff0c;API&#xff08;应用程序编程接口&#xff09;是不同软件应用程序能够无缝通信的基石。无论是开发移动应用、集成第三方服务&#xff0c;还是构建强大的Web平台&#xff0c;理解各种API调用类型至关重要。那么&#xff0c;API调用到底…...

华东师范​地面机器人融合空中无人机视角的具身导航!KiteRunner:语言驱动的户外环境合作式局部-全局导航策略

作者&#xff1a;Shibo Huang 1 ^{1} 1, Chenfan Shi 1 ^{1} 1, Jian Yang 2 ^{2} 2, Hanlin Dong 1 ^{1} 1, Jinpeng Mi 3 ^{3} 3, Ke Li 2 ^{2} 2, Jianfeng Zhang 1 ^{1} 1, Miao Ding 4 ^{4} 4, Peidong Liang 5 ^{5} 5, Xiong You 2 ^{2} 2, Xian Wei 1 ^{1} 1单位&#x…...

Ansible(6)——管理变量

目录 一、Ansible 变量&#xff1a; 1、什么是变量&#xff1a; 2、变量可能包含的值&#xff1a; 3、变量命名&#xff1a; 4、定义变量&#xff1a; 二、Playbook 中的变量&#xff1a; 1、在 Playbook 中定义变量&#xff1a; &#xff08;1&#xff09;最简单的定…...

Git常用问题收集

gitignore 忽略文件夹 不生效 有时候我们接手别人的项目时&#xff0c;发现有的忽略不对想要修改&#xff0c;但发现修改忽略.gitignore后无效。原因是如果某些文件已经被纳入版本管理在.gitignore中忽略路径是不起作用的&#xff0c;这时候需要先清除本地缓存&#xff0c;然后…...

构建高效多标签选择组件:从设计到实现

在现代Web应用中&#xff0c;多标签选择功能已成为常见需求&#xff0c;特别是在内容分类、文章标签、用户兴趣选择等场景。本文将深入解析一个完整的多标签选择实现方案&#xff0c;涵盖交互设计、核心功能和优化技巧。 组件功能概述 这个多标签选择组件提供以下核心功能&am…...

4.1论文阅读

一&#xff1a;PhDnet&#xff1a;一种用于遥感图像的新型物理感知去雾网络&#xff08;A novel physic-aware dehazing network for remote sensing images&#xff09; 论文链接 只是粗略读了一下&#xff0c;关于遥感图像去雾&#xff0c;圆形U--net&#xff0c;加入了物理…...

【渗透测试】Vulnhub靶机-HA: Armour-详细通关教程

下载地址&#xff1a;https://www.vulnhub.com/entry/ha-armour,370/ 目录 前言 信息收集 tftp获取&#xff08;spiderman&#xff09; 查看.htpasswd&#xff08;ant-man&#xff09; ssh欢迎信息提示&#xff08;hulkbuster&#xff09; 反弹shell 提权&#xff08;i…...

Flask使用MySQL数据库通过Flask-SQLAlchemy 迁移数据库,实际更新文件,但是提示没有检测到数据更新。

本地写了一个model的用户类&#xff0c;数据库连接信息正确&#xff0c;执行下面2条命令进行数据库迁移。 flask db migrate 生成迁移文件 flask db upgrade 执行迁移文件的升级 发现执行完后&#xff1a;提示没有检测到数据的更新 PS C:\Users\mu> flask db migrate IN…...

【leetcode100】前K个高频元素

1、题目描述 给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2]示例 2: 输入: nums [1], k 1 输出: [1] 2、初始思路 2.1 思路 全排列&#xf…...

内网渗透-MySQL提权

MySQL提权 mysql的权限提升通常有两种&#xff1a; UDF提权&#xff08;常用&#xff09; 写文件提权启动项提权mof提权一、UDF提权 UDF 全称为user defined function&#xff0c;用户自定义函数 用户可以添加自定义的新函数到Mysql中&#xff0c;以达到功能的扩充&#xf…...

Hibernate核心方法总结

Session中的核心方法梳理 1、save方法 这个方法表示将一个对象保存到数据库中&#xff0c;可以将一个不含OID的new出来的临时对象转换为一个处于Session缓存中具有OID的持久化对象。 需要注意的是&#xff1a;在save方法前设置OID是无效的但是也不会报错&#xff0c;在save方…...

DevOps 与持续集成(CI/CD)

1. DevOps 概述 DevOps(Development + Operations)是一种软件开发方法,强调开发(Dev)与运维(Ops)协作,通过自动化工具提高软件交付效率。其目标是: ✅ 提高部署速度 —— 频繁发布新版本 ✅ 减少人为错误 —— 通过自动化降低运维风险 ✅ 增强可观测性 —— 监控和日…...

下一代AI App架构:前端生成,后端消失

过去十年&#xff0c;Web 和 App 的开发范式基本稳定&#xff1a;前端负责交互体验&#xff0c;后端负责业务逻辑和数据管理。即使是“无服务架构”也只是将后端“拆散”而非“消失”。 但随着 AI 原生应用的兴起&#xff0c;特别是 大模型本地化、小模型部署、WebAssembly、L…...

告别过去,奔向未来

人生就是一个不断雕刻自己的过程&#xff01;一路走来&#xff0c;我们经历过酸甜苦辣咸&#xff0c;迷茫过&#xff0c;跌倒过&#xff0c;懈怠过……但是&#xff0c;我想说这又何妨&#xff01;一个成功人士的经历必定是跌跌宕宕&#xff0c;起起伏伏的。关键是我们要做到&a…...

AF3 Recycling机制

在 AlphaFold3中,输入数据的特征加工中生成了recycling 维度的数据,主要通过ensembled_transform_fns函数抽样得到不同的扰动的MSA、template特征等,类似于数据增强的作用。在数据集的加载和模型的训练中利用了这一维度的数据,增强了模型的稳定性和鲁棒性,避免单一预测结果…...

notepad++8.6.4安装及细节

notepad8.6.4下载安装&#xff08;附安装包&#xff09; 一、安装包下载1.1方法一&#xff1a;官网下载&#xff08;点击跳转&#xff09;1.2方法二&#xff1a;网盘链接分享8.6.4版本 二、安装过程细节2.1这里的组件建议全部勾选。点击“下一步”。2.2 勾选①&#xff1a;可以…...

谁该处理我的请假?——责任链模式

谁该处理我的请假&#xff1f;——责任链模式 一、生活中的责任链&#xff1a;请假审批流程二、责任链模式的核心特点三、代码实现&#xff1a;请假审批责任链四、工作中的实际应用场景五、框架中的经典应用六、模式本质理解 一、生活中的责任链&#xff1a;请假审批流程 想象…...

【NLP应用场景全解】自然语言处理如何改变世界?

自然语言处理作为人工智能的重要分支&#xff0c;正在加速改变各行各业。根据Statista预测&#xff0c;到2025年&#xff0c;全球NLP市场规模将达到438亿美元。本文将系统梳理NLP的主要应用场景&#xff0c;结合最新技术趋势&#xff0c;帮助你了解NLP技术的落地现状与未来发展…...

Hive 中书写SQL注意的地方

1.1 关于 DDL &#xff08;1&#xff09;创建带有主键约束的 Hive 表时报错。 Hive 目前还没有严格支持“主键约束”&#xff0c;创建带有主键约束的 HIVE 表时报了如下错误&#xff1a; SemanticException [Error 10326]: Invalid Constraint: syntax ENABLE/ENFORCED featu…...

Ubuntu 下 无界面环境 多进程/多线程 使用DrissionPage

使用wget “https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb” -O chrome.deb 安装chrome # !/usr/bin/python3 # -*- coding:utf-8 -*- """ author: JHC000abcgmail.com file: dp.py time: 2025/2/20 20:22 desc:wget "htt…...

Opencv计算机视觉编程攻略-第十节 估算图像之间的投影关系

目录 1. 计算图像对的基础矩阵 2. 用RANSAC 算法匹配图像 3. 计算两幅图像之间的单应矩阵 4. 检测图像中的平面目标 图像通常是由数码相机拍摄的&#xff0c;它通过透镜投射光线成像&#xff0c;是三维场景在二维平面上的投影&#xff0c;这表明场景和它的图像之间以及同一…...

RocketMQ 01

今天是2025/04/06 21:31 day 18 总路线请移步主页Java大纲相关文章 今天进行RocketMQ 1,2 个模块的归纳 首先是RocketMQ 的相关内容概括的思维导图 1. 核心组件 1.1 NameServer 核心功能 服务发现&#xff1a;作为轻量级注册中心&#xff0c;管理所有 Broker 的地址和路由信…...

牛客周赛———字符串

题目如下 思路&#xff08;贪心&#xff09; >和<的位置是固定不变的&#xff0c;所以先处理这两个符号&#xff0c;然后再遍历一遍检查‘Z’&#xff0c;如果不符合条件将Z的位置改变正负性使其满足条件&#xff0c;然后遍历的时候记数答案就行了&#xff0c;注意s的首…...

在Hive中,将数据从一个表查询并插入到另一个表

1. 确认目标表结构 确保目标表已存在且结构与查询结果匹配。若不存在&#xff0c;需先创建&#xff1a; CREATE TABLE target_table ( id INT, name STRING ) PARTITIONED BY (dt STRING) STORED AS ORC; 2. 选择插入方式 覆盖插入&#xff08;替换现有数据&#xff0…...

优雅实现级联选择器:CascadeSelect 类设计与实现

在现代Web开发中&#xff0c;级联选择器是一种常见的UI组件&#xff0c;它能够有效地组织和展示层级数据。本文将深入解析一个功能完善的级联选择器实现——CascadeSelect类&#xff0c;展示如何用面向对象的方式构建可复用的UI组件。 组件概述 CascadeSelect是一个二级下拉框…...

26考研 | 王道 | 数据结构 | 第五章 树

第五章 树 5.1. 树的概念 5.1.1. 树的基本定义 树:n(n>0)个节点的有限集合&#xff0c;是一种逻辑结构&#xff0c;当n0时为空树&#xff0c;且非空树满足: 有且仅有一个特定的称为根的节点当n>1时&#xff0c;其余结点可分为m (m >0) 个互不相交的有限集合&#x…...

Spring 怎么解决循环依赖问题?

Spring 循环依赖&#xff08;circular dependency&#xff09; 指的是多个 Bean 之间的相互依赖&#xff0c;比如&#xff1a; A 依赖 B&#xff0c;B 又依赖 A&#xff1b;或者 A → B → C → A 这种嵌套循环依赖。 这是一个常见又棘手的问题&#xff0c;但 Spring 是可以解…...