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容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
源码码解析
属性成员
beanDefinitionMap
:DefaultListableBeanFactory
作为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
干货分享,感谢您的阅读! (暂存篇---后续会删除,完整版和持续更新见高频面试题基本总结回顾(含笔试高频算法整理)) 备注:引用请标注出处,同时存在的问题请在相关博客留言…...
生成式人工智能(AIGC):内容创作的新引擎与新挑战
在数字化时代,内容创作的需求呈爆炸式增长。无论是社交媒体、新闻媒体、广告营销还是娱乐行业,都急需大量高质量的文本、图像、音频和视频内容。然而,传统的内容创作方式面临着效率低下、成本高昂、创意枯竭等问题。生成式人工智能࿰…...
Java 大视界 -- 基于 Java 的大数据分布式计算在气象数据处理与天气预报中的应用进展(176)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
react和vue在开发使用的语法上面有什么区别?
React和Vue在开发使用的语法上有诸多区别,下面从组件定义、数据绑定、事件处理、生命周期钩子等方面详细阐述: 1. 组件定义 React: 函数组件是React推荐的组件定义方式,它本质上是一个JavaScript函数,返回JSX元素。类…...
ReFormX:现代化的 React 表单解决方案 - 深度解析与最佳实践
ReFormX文档 表单开发一直是前端工作中最繁琐却又最常见的任务之一。从简单的登录表单到复杂的多步骤配置页面,开发者往往需要编写大量重复代码,处理繁琐的状态管理、数据验证和联动逻辑。ReFormX 应运而生,它不仅是一个表单组件库ÿ…...
STM32单片机入门学习——第19节: [6-7]TIM编码器接口
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.04.06 STM32开发板学习——第19节: [6-7]TIM编码器接口 前言开发板说明引用解答和科普一…...
Spring 中的 bean 生命周期
🌱 一、什么是 Bean 生命周期? 在 Spring 容器中,一个 Bean 从“创建 → 初始化 → 使用 → 销毁”,经历了完整的生命周期。 Spring 提供了 多个扩展点 让你可以在这些阶段做事情,比如注入资源、日志记录、连接资源、清…...
Kafka 在 k8s 中的消费者实例
每个 Pod(在 K8s 中运行的消费者实例)都会作为一个独立的消费者加入到 Kafka 消费者组中。 如果只是将消费者代码在 K8s 中复制多个实例(例如通过增加副本数),每个实例都会作为一个独立的消费者加入到 Kafka 消费者组…...
野草云防火墙风险分析及 Docker 使用注意事项
在实际使用野草云服务器部署 Docker 服务过程中,我发现了一个非常容易被忽视但极具风险的安全问题——野草云的防火墙逻辑与 Docker 默认行为之间存在冲突,如果配置不当,可能会导致容器服务被意外暴露在公网,甚至绕过你设置的“拒…...
C++中高精度运算问题
前言:在备赛蓝桥杯时,遇到C处理数值较大的浮点数问题,特此记录一下。 C 的 std::string 类使用动态内存分配,其长度可以根据需要动态增加或减少,自动调整内存大小以适应字符串内容的变化。当字符串长度超过当前分配的…...
开篇 - 配置Unlua+VsCode的智能提示、调试以及学习方法
智能提示 为要绑定Lua的蓝图创建模板文件,这会在Content/Script下生成lua文件 然后点击生成智能代码提示,这会在Plugins/Unlua/Intermediate/生成Intenllisense文件夹 打开VSCode,点击文件->将工作区另存为。生成一个空工作区,放置在工程…...
前端快速入门学习4——CSS盒子模型、浮动、定位
一、盒子模型 所有HTML元素可以看作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用。 CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距,边框,填充,…...
在 ASP.NET Web Forms 项目中,编译后可能找不到 `Login.aspx.cs` 的源码文件的原因?
在 ASP.NET Web Forms 项目中,确实存在一种情况:编译后可能找不到 Login.aspx.cs 的源码文件。以下是对此现象的详细分析和解释: 1. 已知信息 您提供的 Web.config 文件显示这是一个 ASP.NET Web Forms 项目。在 ASP.NET 中,.asp…...
centos7 yum install docker 安装错误
1、错误信息: [rootlocalhost atguigu]# yum install docker 已加载插件: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 处理异步请求(DeferredResult 基础案例、DeferredResult 超时案例、DeferredResult 扩展案例、DeferredResult 方法汇总) spring.io mvc Asynchronous Requests 官网文档 spring.io webflux&webclient官网文…...
Java项目集成大模型(通译千问)
1:打开阿里云搜索 通义大模型,然后点击丰富开发API接口。 2:可以看到有openAi和DashScope两种模式,我们这次采用DashScope方法,点击DashScope 3:点击获取Apikey 然后点击 前往我得Api-key跳转到控制台&…...
Lisp语言的安全协议
Lisp语言与安全协议的结合 引言 在信息社会的今天,数据的安全性和隐私保护愈发重要。随着网络攻击手段的不断演进,各种安全协议相继被提出与实现。与此同时,Lisp作为一种古老且灵活的计算机编程语言,虽然并不是主流的系统编程语…...
【图像处理基石】什么是自动曝光(AE)?
1. 什么是自动曝光(AE)? 自动曝光(Auto Exposure, AE)是一种通过调整相机参数(如曝光时间、增益、光圈等)使图像亮度达到目标值的技术。其核心是通过实时分析图像亮度,动态优化参数…...
清明假期间
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表单校验 现状确认 点击添加按钮,没有点击样式,用户感知不明显没有限制最大的tab添加数量,可以无限添加 调整目标&代码编写 调整目标…...
Elasticsearch DSL 中的 aggs 聚合
一、聚合的概述 Elasticsearch 的 聚合(Aggregations) 功能用于对数据进行多维分析和统计,支持从简单的指标计算到复杂的分组分析。以下是聚合的基本结构: {"aggs": { // 也可以使用"agg…...
API调用类型全面指南:理解基础知识
在当今快速发展的数字化环境中,API(应用程序编程接口)是不同软件应用程序能够无缝通信的基石。无论是开发移动应用、集成第三方服务,还是构建强大的Web平台,理解各种API调用类型至关重要。那么,API调用到底…...
华东师范地面机器人融合空中无人机视角的具身导航!KiteRunner:语言驱动的户外环境合作式局部-全局导航策略
作者: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 变量: 1、什么是变量: 2、变量可能包含的值: 3、变量命名: 4、定义变量: 二、Playbook 中的变量: 1、在 Playbook 中定义变量: (1)最简单的定…...
Git常用问题收集
gitignore 忽略文件夹 不生效 有时候我们接手别人的项目时,发现有的忽略不对想要修改,但发现修改忽略.gitignore后无效。原因是如果某些文件已经被纳入版本管理在.gitignore中忽略路径是不起作用的,这时候需要先清除本地缓存,然后…...
构建高效多标签选择组件:从设计到实现
在现代Web应用中,多标签选择功能已成为常见需求,特别是在内容分类、文章标签、用户兴趣选择等场景。本文将深入解析一个完整的多标签选择实现方案,涵盖交互设计、核心功能和优化技巧。 组件功能概述 这个多标签选择组件提供以下核心功能&am…...
4.1论文阅读
一:PhDnet:一种用于遥感图像的新型物理感知去雾网络(A novel physic-aware dehazing network for remote sensing images) 论文链接 只是粗略读了一下,关于遥感图像去雾,圆形U--net,加入了物理…...
【渗透测试】Vulnhub靶机-HA: Armour-详细通关教程
下载地址:https://www.vulnhub.com/entry/ha-armour,370/ 目录 前言 信息收集 tftp获取(spiderman) 查看.htpasswd(ant-man) ssh欢迎信息提示(hulkbuster) 反弹shell 提权(i…...
Flask使用MySQL数据库通过Flask-SQLAlchemy 迁移数据库,实际更新文件,但是提示没有检测到数据更新。
本地写了一个model的用户类,数据库连接信息正确,执行下面2条命令进行数据库迁移。 flask db migrate 生成迁移文件 flask db upgrade 执行迁移文件的升级 发现执行完后:提示没有检测到数据的更新 PS C:\Users\mu> flask db migrate IN…...
【leetcode100】前K个高频元素
1、题目描述 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2]示例 2: 输入: nums [1], k 1 输出: [1] 2、初始思路 2.1 思路 全排列…...
内网渗透-MySQL提权
MySQL提权 mysql的权限提升通常有两种: UDF提权(常用) 写文件提权启动项提权mof提权一、UDF提权 UDF 全称为user defined function,用户自定义函数 用户可以添加自定义的新函数到Mysql中,以达到功能的扩充…...
Hibernate核心方法总结
Session中的核心方法梳理 1、save方法 这个方法表示将一个对象保存到数据库中,可以将一个不含OID的new出来的临时对象转换为一个处于Session缓存中具有OID的持久化对象。 需要注意的是:在save方法前设置OID是无效的但是也不会报错,在save方…...
DevOps 与持续集成(CI/CD)
1. DevOps 概述 DevOps(Development + Operations)是一种软件开发方法,强调开发(Dev)与运维(Ops)协作,通过自动化工具提高软件交付效率。其目标是: ✅ 提高部署速度 —— 频繁发布新版本 ✅ 减少人为错误 —— 通过自动化降低运维风险 ✅ 增强可观测性 —— 监控和日…...
下一代AI App架构:前端生成,后端消失
过去十年,Web 和 App 的开发范式基本稳定:前端负责交互体验,后端负责业务逻辑和数据管理。即使是“无服务架构”也只是将后端“拆散”而非“消失”。 但随着 AI 原生应用的兴起,特别是 大模型本地化、小模型部署、WebAssembly、L…...
告别过去,奔向未来
人生就是一个不断雕刻自己的过程!一路走来,我们经历过酸甜苦辣咸,迷茫过,跌倒过,懈怠过……但是,我想说这又何妨!一个成功人士的经历必定是跌跌宕宕,起起伏伏的。关键是我们要做到&a…...
AF3 Recycling机制
在 AlphaFold3中,输入数据的特征加工中生成了recycling 维度的数据,主要通过ensembled_transform_fns函数抽样得到不同的扰动的MSA、template特征等,类似于数据增强的作用。在数据集的加载和模型的训练中利用了这一维度的数据,增强了模型的稳定性和鲁棒性,避免单一预测结果…...
notepad++8.6.4安装及细节
notepad8.6.4下载安装(附安装包) 一、安装包下载1.1方法一:官网下载(点击跳转)1.2方法二:网盘链接分享8.6.4版本 二、安装过程细节2.1这里的组件建议全部勾选。点击“下一步”。2.2 勾选①:可以…...
谁该处理我的请假?——责任链模式
谁该处理我的请假?——责任链模式 一、生活中的责任链:请假审批流程二、责任链模式的核心特点三、代码实现:请假审批责任链四、工作中的实际应用场景五、框架中的经典应用六、模式本质理解 一、生活中的责任链:请假审批流程 想象…...
【NLP应用场景全解】自然语言处理如何改变世界?
自然语言处理作为人工智能的重要分支,正在加速改变各行各业。根据Statista预测,到2025年,全球NLP市场规模将达到438亿美元。本文将系统梳理NLP的主要应用场景,结合最新技术趋势,帮助你了解NLP技术的落地现状与未来发展…...
Hive 中书写SQL注意的地方
1.1 关于 DDL (1)创建带有主键约束的 Hive 表时报错。 Hive 目前还没有严格支持“主键约束”,创建带有主键约束的 HIVE 表时报了如下错误: 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. 检测图像中的平面目标 图像通常是由数码相机拍摄的,它通过透镜投射光线成像,是三维场景在二维平面上的投影,这表明场景和它的图像之间以及同一…...
RocketMQ 01
今天是2025/04/06 21:31 day 18 总路线请移步主页Java大纲相关文章 今天进行RocketMQ 1,2 个模块的归纳 首先是RocketMQ 的相关内容概括的思维导图 1. 核心组件 1.1 NameServer 核心功能 服务发现:作为轻量级注册中心,管理所有 Broker 的地址和路由信…...
牛客周赛———字符串
题目如下 思路(贪心) >和<的位置是固定不变的,所以先处理这两个符号,然后再遍历一遍检查‘Z’,如果不符合条件将Z的位置改变正负性使其满足条件,然后遍历的时候记数答案就行了,注意s的首…...
在Hive中,将数据从一个表查询并插入到另一个表
1. 确认目标表结构 确保目标表已存在且结构与查询结果匹配。若不存在,需先创建: CREATE TABLE target_table ( id INT, name STRING ) PARTITIONED BY (dt STRING) STORED AS ORC; 2. 选择插入方式 覆盖插入(替换现有数据࿰…...
优雅实现级联选择器:CascadeSelect 类设计与实现
在现代Web开发中,级联选择器是一种常见的UI组件,它能够有效地组织和展示层级数据。本文将深入解析一个功能完善的级联选择器实现——CascadeSelect类,展示如何用面向对象的方式构建可复用的UI组件。 组件概述 CascadeSelect是一个二级下拉框…...
26考研 | 王道 | 数据结构 | 第五章 树
第五章 树 5.1. 树的概念 5.1.1. 树的基本定义 树:n(n>0)个节点的有限集合,是一种逻辑结构,当n0时为空树,且非空树满足: 有且仅有一个特定的称为根的节点当n>1时,其余结点可分为m (m >0) 个互不相交的有限集合&#x…...
Spring 怎么解决循环依赖问题?
Spring 循环依赖(circular dependency) 指的是多个 Bean 之间的相互依赖,比如: A 依赖 B,B 又依赖 A;或者 A → B → C → A 这种嵌套循环依赖。 这是一个常见又棘手的问题,但 Spring 是可以解…...