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

【Spring专题】Spring之Bean的生命周期源码解析——阶段二(二)(IOC之属性填充/依赖注入)

目录

  • 前言
    • 阅读准备
    • 阅读指引
    • 阅读建议
  • 课程内容
    • 一、依赖注入方式(前置知识)
      • 1.1 手动注入
      • 1.2 自动注入
        • 1.2.1 XML的autowire自动注入
          • 1.2.1.1 byType:按照类型进行注入
          • 1.2.1.2 byName:按照名称进行注入
          • 1.2.1.3 constructor:按照构造方法进行注入
          • 1.2.1.4 其他
          • 1.2.1.5 XML的autowire自动注入方式总结
        • 1.2.2 @Autowired注解的自动注入
        • 1.2.3 自动注入总结
    • 二、依赖注入过程
      • 2.1 简单回顾
      • 2.2. 概念回顾
      • 2.3 核心方法讲解
    • 三、【寻找注入点】方法讲解
  • 学习总结

前言

阅读准备

由于Spring源码分析是一个前后联系比较强的过程,而且这边分析,也是按照代码顺序讲解的,所以不了解前置知识的情况下,大概率没办法看懂当前的内容。所以,特别推荐看看我前面的文章(自上而下次序):

  • Spring底层核心原理解析【学习难度:★★☆☆☆
  • 手写简易Spring容器过程分析【学习难度:★★☆☆☆
  • Spring之底层架构核心概念解析【学习难度:★★★☆☆,重要程度:★★★★★
  • Bean的生命周期流程图【学习难度:☆☆☆☆☆,重要程度:★★★★★
  • Spring之Bean的生命周期源码解析——阶段一(扫描生成BeanDefinition)【学习难度:★★☆☆☆,重要程度:★★★☆☆
  • Spring之Bean的生命周期源码解析——阶段二(IOC之实例化)【学习难度:★★★★★,重要程度:★★★☆☆

(PS:特别是《Bean的生命周期流程图》,帮大家【开天眼】,先了解下流程。毕竟【通过业务了解代码,远比通过代码了解业务简单的多】!!!!)
(PS:特别是《Bean的生命周期流程图》,帮大家【开天眼】,先了解下流程。毕竟【通过业务了解代码,远比通过代码了解业务简单的多】!!!!)
(PS:特别是《Bean的生命周期流程图》,帮大家【开天眼】,先了解下流程。毕竟【通过业务了解代码,远比通过代码了解业务简单的多】!!!!)

阅读指引

我们在上一节课已经说到过了,本次Spring源码剖析的总入口是new AnnotationConfigApplicationContext(“org.tuling.spring”);,这里就不再重复解释了。本节课要说的内容,是SpringIOC的属性填充/依赖注入,我们这里直接给到入口吧,调用链如下:(调用链比较深,不要纠结细枝末节)

  1. AbstractApplicationContext#refresh:刷新方法,不用在意
  2. AbstractApplicationContext#finishBeanFactoryInitialization:在这里实例化所有剩余的(非lazy-init)单例
  3. DefaultListableBeanFactory#preInstantiateSingletons:在这里实例化所有剩余的(非lazy-init)单例(上面的方法,核心干活的方法就是这里)
  4. DefaultListableBeanFactory#getBean:获取Bean的方法
  5. AbstractBeanFactory#doGetBean:返回指定bean的一个实例,它可以是共享的,也可以是独立的
  6. 上面这个AbstractBeanFactory#doGetBean里面的一段局部代码写的回调方法,如下:
	// 如果是单例创建bean实例if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}});beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}
  1. AbstractAutowireCapableBeanFactory#createBean:这个类的中心方法:创建一个bean实例,填充bean实例,应用后处理器,等等。
  2. AbstractAutowireCapableBeanFactory#populateBean:使用来自bean定义的属性值在给定的BeanWrapper中填充bean实例。

如上面的调用链所示,最后一个方法,才是我们本次要研究的核心方法。

阅读建议

  1. 看源码,切记纠结细枝末节,不然很容易陷进去。正常来说,看主要流程就好了
  2. 遇到不懂的,多看看类注释或者方法注释。Spring这种优秀源码,注释真的非常到位
  3. 如果你是idea用户,多用F11的书签功能。
    • Ctrl + F11 选中文件 / 文件夹,使用助记符设定 / 取消书签 (必备)
    • Shift + F11 弹出书签显示层 (必备)
    • Ctrl +1,2,3…9 定位到对应数值的书签位置 (必备)

课程内容

一、依赖注入方式(前置知识)

在Spring中,属性注入的方式分为两种,分别是:【手动注入】和【自动注入】。

1.1 手动注入

在XML中定义Bean时,就是手动注入,因为是程序员手动给某个属性指定了值。如下:

<bean name="userService" class="com.luban.service.UserService"><property name="orderService" ref="orderService"/>
</bean>

有经验的同学应该知道,上面这种底层是通过setXxx方法进行注入的。另外,还有一种方式,是通过构造方法进行注入的,如下:

<bean name="userService" class="com.luban.service.UserService"><constructor-arg index="0" ref="orderService"/>
</bean>

所以手动注入的底层也就是分为两种:【set方法注入】和【构造方法注入】。

1.2 自动注入

自动注入又分为两种:【XML的autowire自动注入】和【@Autowired注解的自动注入】。

1.2.1 XML的autowire自动注入

在XML中,我们可以在定义一个Bean时去指定这个Bean的自动注入模式,它有如下几种方式:

1.2.1.1 byType:按照类型进行注入

byType注入方式,底层是基于setXxx方法实现的,所以setter方法不能少。这里说的类型是【入参】的类型。
Spring在通过byType的自动填充属性时流程是:

  1. 获取到set方法中的唯一参数的参数类型,并且根据该类型去容器中获取bean
  2. 如果找到多个,会报错

使用示例如下:

<bean id="userService" class="com.luban.service.UserService" autowire="byType"/>
    public void setOrderService(OrderService orderService) {this.orderService = orderService;}

如上示例的类型,就是指入参orderService的类型OrderService

1.2.1.2 byName:按照名称进行注入

byType注入方式,底层是基于setXxx方法实现的,所以setter方法不能少。这里说的【名称】,是指setXxx后面的Xxx部分。
所以,Spring在通过byName的自动填充属性时流程是:

  1. 找到所有set方法所对应的Xxx部分的名字
  2. 根据Xxx部分的名字去获取bean

使用示例如下:

    <bean id="userXmlBean" class="org.tuling.spring.xml.bean.UserXmlBean" autowire="byName"/><bean id="walletXmlBean" class="org.tuling.spring.xml.bean.WalletXmlBean"/>

如上,我们定义了userXmlBean的自动注入类型是byName,并且定义了一个名字叫walletXmlBean的bean。

public class UserXmlBean {private WalletXmlBean wallet;public void printProperty() {System.out.println(wallet);}public void setWalletXmlBean(WalletXmlBean param) {this.wallet = param;}
}

如上,我们定义了一个UserXmlBean ,他有成员变量WalletXmlBean wallet。同时给他声明了一个成员方法printProperty()用来打印它的成员属性的地址。

测试代码:

public class MyXmlApplicationContextTest {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");UserXmlBean userXmlBean = (UserXmlBean)context.getBean("userXmlBean");userXmlBean.printProperty();}// 系统输出:// org.tuling.spring.xml.bean.WalletXmlBean@1d16f93d
}

如上,UserXmlBeanWalletXmlBean类型的属性出现了2个名称,一个是成员变量wallet,另一个是setter方法入参中的param,但是一点都不妨碍我们byName注入。因为,根据byName的规则,寻找的是setXxx后面的Xxx部分。还不够信服是吗?我们改一下UserXmlBean里面的setter方法,如下:

    public void setWalletXmlBean123(WalletXmlBean param) {this.wallet = param;}

这个时候再去调用,输出null

1.2.1.3 constructor:按照构造方法进行注入

constructor表示通过构造方法注入,其实这种情况就比较简单了,没有byType和byName那么复杂。
如果是constructor,那么就可以不写set方法了,当某个bean是通过构造方法来注入时,spring利用构造方法的参数信息从Spring容器中去找bean,找到bean之后作为参数传给构造方法,从而实例化得到一个bean对象,并完成属性赋值(属性赋值的代码得程序员来写)。
(PS:我们这里先不考虑一个类有多个构造方法的情况,后面单独讲推断构造方法。我们这里只考虑只有一个有参构造方法。)
其实构造方法注入相当于byType+byName。Spring在通过byName的自动填充属性时流程是:

  1. 通过构造方法中的参数类型去找bean,如果对应的类型只有一个bean,那就是它了;
  2. 如果找到多个会根据参数名确定
  3. 如果最后根据参数名都无法确定,则报错

使用示例如下:

    <bean id="userXmlBean" class="org.tuling.spring.xml.bean.UserXmlBean" autowire="constructor"/><bean id="walletXmlBean123" class="org.tuling.spring.xml.bean.WalletXmlBean"/><bean id="walletXmlBean" class="org.tuling.spring.xml.bean.WalletXmlBean"/>

bean示例:

public class UserXmlBean {private WalletXmlBean wallet;public void printProperty() {System.out.println(wallet);}public UserXmlBean(WalletXmlBean walletXmlBean) {this.wallet = walletXmlBean;}
}

具体的调用跟错误方式这边就不介绍了,大家回头自己试试吧

1.2.1.4 其他

其他,诸如:

  • default:表示默认值,我们一直演示的某个bean的autowire,而也可以直接在<beans>标签中设置autowire,如果设置了,那么<bean>标签中设置的autowire如果为default,那么则会用<beans>标签中设置的autowire
  • no:表示关闭autowire,不自动注入
1.2.1.5 XML的autowire自动注入方式总结

那么XML的自动注入底层其实也就是:

  1. set方法注入
  2. 构造方法注入

1.2.2 @Autowired注解的自动注入

@Autowired注解,本质上也是byType和byName的结合。它是先byType,如果找到多个则byName。这个跟xml构造方式注入原理如出一辙。就是:

  1. 先根据类型去找bean,如果对应的类型只有一个bean,那就是它了;
  2. 如果找到多个会根据属性名确定
  3. 如果最后根据属性名都无法确定,则报错

@Autowired注解可以写在:

  1. 属性上:先根据属性类型去找Bean,如果找到多个再根据属性名确定一个(属性注入)
  2. 构造方法上:先根据方法参数类型去找Bean,如果找到多个再根据参数名确定一个(构造方法注入)
  3. set方法上:先根据方法参数类型去找Bean,如果找到多个再根据参数名确定一个(set方法注入)

1.2.3 自动注入总结

可以发现XML中的自动注入是挺强大的,那么问题来了,为什么我们平时都是用的@Autowired注解呢?而没有用上文说的这种自动注入方式呢?
其实啊,@Autowired注解相当于XML中的autowire属性的注解方式的替代。从本质上讲,@Autowired注解提供了与autowire相同的功能,但是拥有更细粒度的控制和更广泛的适用性。
XML中的autowire控制的是整个bean的所有属性,而@Autowired注解是直接写在某个属性、某个set方法、某个构造方法上的。
再举个例子,如果一个类有多个构造方法,那么如果用XML的autowire=constructor,你无法控制到底用哪个构造方法,而你可以用@Autowired注解来直接指定你想用哪个构造方法。
同时,用@Autowired注解,还可以控制,哪些属性想被自动注入,哪些属性不想,这也是细粒度的控制。

二、依赖注入过程

2.1 简单回顾

依赖注入的过程,大体上其实能分为以下三步的:【寻找注入点】、【填充属性】、【填充属性后】。但其实,【寻找注入点】这个过程,会在两个地方被调用。第一个就是箭头所向,【实例化】阶段【BeanDefinition后置处理】那个地方。怎么理解呢?因为,【寻找注入点】的实现类就是【BeanDefinition后置处理】中的一个
在这里插入图片描述
上面说的概念多少有点绕。简单来说,【寻找注入点】就是寻找被@Autowird@Value@Inject@Resource注解修饰的属性、方法等等。

2.2. 概念回顾

在这个【实例化】过程中,涉及到了一些Spring底层设计的概念,我在上一个笔记里面有大概介绍过Spring底层概念的一些讲解,不记得的同学记得回去翻一翻。
主要涉及的概念有:

  • BeanDefinition(设计图纸):BeanDefinition表示Bean定义,BeanDefinition中存在很多属性用来描述一个Bean的特征
  • MergedBeanDefinitionPostProcessor:合并BeanDefinition后置处理器。但这里其实主要说的是AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor。他俩有什么作用呢?前者是处理Spring内部定义的@Autowired@Value自动注入注解;后者是处理jdk定义的@Resource注解。既然都说到这了,那你们猜猜用到的是什么方法?嘿,不就是MergedBeanDefinitionPostProcessor里面定义的方法嘛,赶紧去翻翻看。

CommonAnnotationBeanPostProcessor接口定义如下:

 /*** 这个后置处理器通过继承InitDestroyAnnotationBeanPostProcessor和InstantiationAwareBeanPostProcessor注解,* 获得了对@PostConstruct和@PreDestroy的支持。* 另外,这个类的核心处理元素是@Resource注解*/
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessorimplements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {// 具体代码就不贴了。学到这里大家应该知道如何通过【接口】继承、实现来猜测类能力了吧
}

AutowiredAnnotationBeanPostProcessor接口定义如下:

// 继承类跟CommonAnnotationBeanPostProcessor 如出一辙,唯一不同的是,继承了功能更强大的
// SmartInstantiationAwareBeanPostProcessor(InstantiationAwareBeanPostProcessor子类)
// 实现这个类,是为了实现里面的推断构造方法
public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

2.3 核心方法讲解

本节【属性注入】,将会分两个部分来讲。第一部分是:【寻找注入点】;剩下的是第二部分。
先说第一部分,第一部分主要涉及【3个类,7个核心方法】。
第二部分,待定…

三、【寻找注入点】方法讲解

学习总结

相关文章:

【Spring专题】Spring之Bean的生命周期源码解析——阶段二(二)(IOC之属性填充/依赖注入)

目录 前言阅读准备阅读指引阅读建议 课程内容一、依赖注入方式&#xff08;前置知识&#xff09;1.1 手动注入1.2 自动注入1.2.1 XML的autowire自动注入1.2.1.1 byType&#xff1a;按照类型进行注入1.2.1.2 byName&#xff1a;按照名称进行注入1.2.1.3 constructor&#xff1a;…...

线程|线程的使用、四种实现方式

1.线程的实现方式 1.用户级线程 开销小&#xff0c;用户空间就可以创建多个。缺点是&#xff1a;内核无法感知用户级多个线程的存在&#xff0c;把其当作只有一个线程&#xff0c;所以只会提供一个处理器。 2.内核级线程 相对于用户级开销稍微大一点&#xff0c;可以利用多…...

Facebook 应用未启用:这款应用目前无法使用,应用开发者已得知这个问题。

错误&#xff1a;Facebook 应用未启用:这款应用目前无法使用&#xff0c;应用开发者已得知这个问题。应用重新启用后&#xff0c;你便能登录。 「应用未经过审核或未发布」&#xff1a; 如果一个应用还没有经过Facebook的审核或者开发者尚未将应用发布&#xff0c;那么它将无法…...

(十八)大数据实战——Hive的metastore元数据服务安装

前言 Hive的metastore服务作用是为Hive CLI或者Hiveserver2提供元数据访问接口。Hive的metastore 是Hive元数据的存储和管理组件&#xff0c;它负责管理 Hive 表、分区、列等元数据信息。元数据是描述数据的数据&#xff0c;它包含了关于表结构、存储位置、数据类型等信息。本…...

ubuntu 22.04 LTS 在 llvm release/17.x 分支上编译 cookbook llvm example Chapter 02

一&#xff0c;从源码编译 llvm 下载源码&#xff1a; $ git clone https://github.com/llvm/llvm-project.git 创建 对应 commit id分支&#xff1a; $ cd llvm-project $ git checkout 5b78868661f42a70fa30 -b 17.x.greater 源码成功编译 llvm-project commit id&…...

【仿写tomcat】三、通过socket读取http请求信息

仿写tomcat 建立Socket连接获取连接信息查看HTTP信息 建立Socket连接 这里我们也是创建一个专门管理socket的类 package com.tomcatServer.socket;import java.io.*; import java.net.ServerSocket;/*** 套接字存储** author ez4sterben* date 2023/08/15*/ public class Soc…...

Hive的窗口函数与行列转换函数及JSON解析函数

1. 系统内置函数 查看系统内置函数&#xff1a;show functions ; 显示内置函数的用法&#xff1a; desc function lag; – lag为函数名 显示详细的内置函数用法: desc function extended lag; 1.1 行转列 行转列是指多行数据转换为一个列的字段。 Hive行转列用到的函数 con…...

CSS中的z-index属性有什么作用?如何控制元素在层叠上下文中的显示顺序?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ z-index 属性的作用及控制元素层叠顺序作用 ⭐ 控制元素层叠顺序⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff0…...

c语言——字符转ASCLL码

//字符转ASCLL码 #include<stdio.h> #include<stdlib.h> int main() {char c;printf("输入字符&#xff1a;");scanf("%c",&c);printf(" %c 的ASCLL为: %d \n",c,c);system("pause");return 0;}...

ardupilot开发 --- 安装与调参篇

解锁电机前的安全检查 Pre-arm Safety Checks 安全检查包括&#xff1a;是否未校准、配置或传感器数据是否正确等等&#xff0c;某一项不通过则不允许解锁电机&#xff1b; 目的&#xff1a;防止炸机&#xff1b; 如何禁用这些安全检查&#xff1f;配置 ARMING_CHECK&#xff…...

BC108 矩阵交换

描述 KiKi有一个矩阵&#xff0c;他想知道经过k次行变换或列变换后得到的矩阵。请编程帮他解答。 输入描述 第一行包含两个整数n和m&#xff0c;表示一个矩阵包含n行m列&#xff0c;用空格分隔。 (1≤n≤10,1≤m≤10) 从2到n1行&#xff0c;每行输入m个整数&#xff08;范围-…...

如何发现系统改进点,优化点,提高点,新系统 边界感不要太强

技术人员规划能力&#xff0c;如何规划新的系统_技术规划能力_个人渣记录仅为自己搜索用的博客-CSDN博客 1. 协作中, 双方系统对接, 边界感不要太强. 肯定会不爽, 不爽的点里可以挖掘改进点 肯定会有很多冲突,对方技能欠缺, 对方耽误你的时间, 可以想下有没有什么方案是可…...

5G无人露天矿山解决方案

1、5G无人露天矿山解决方案背景 ①2010.10&#xff0c;国家安监总局《金属非金属地下矿山安全避险“六大系统”安装使用和监督检查暂行规定》 ②2016.03&#xff0c;国家发改委《能源技术革命创新行动计划&#xff08;2016-2030&#xff09;》&#xff0c;2025 年重点煤矿区采…...

Datawhale Django入门组队学习Task01

Task01 一.创建虚拟环境 python -m venv django_learn &#xff08;django_learn那里是自己定的环境名字&#xff09; 之前一直用conda管理虚拟环境&#xff0c;没咋用过virtualenv&#xff0c;然后我的powershell之前也设置了默认启动了base环境&#xff0c;然后输入activat…...

【第二阶段】kotlin的函数类型作为返回类型

fun main() {//调用,返回的是一个匿名类型&#xff0c;所以info就是一个匿名函数val infoshow("",0)//info接受的返回值为匿名类型&#xff0c;此时info就是一个匿名函数println(info("kotlin",20)) }//返回类型为一个匿名函数的返回类型fun show(name:Str…...

C++之ostream与ifstream读写文件操作(一百八十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…...

Unity - 从PackageManager中安装内置工具

1.MemoryProfiler 内存分析工具 add from git url &#xff1a;com.unity.memoryprofiler 使用地址记录&#xff1a;unity3d内存分析工具memory profiler_unity3d memory profile_Marco&GalaxyDragon的博客-CSDN博客 理解Unity Memory Profiler - 知乎...

wsl安装Linux kali

目录 1.启用“Hyper-V”和“~子系统” 2.启用虚拟化 3.安装发行版 4.升级原有系统到WSL2 5.kali换源与更新升级并安装工具集 6.kali安装图形界面~GUI 7.kali安装中文界面与中文输入法 8.wsl~kali位置迁移 1.启用“Hyper-V”和“~子系统” 打开控制面板---->>程序…...

ProtoBuf3语法详解

目录&#xff1a; 需求&#xff1a;字段规则消息类型的定义与使用通讯录2.0的写⼊实现TestRead.java(通讯录2.0)TestRead.java(通讯录2.0) 另⼀种验证⽅法--toString()enum类型升级通讯录⾄2.1版本Any类型oneof类型map类型默认值更新消息保留字段reserved未知字段选项option 通…...

尚硅谷css3笔记

目录 一、新增长度单位 二、新增盒子属性 1.border-box 怪异盒模型 2.resize 调整盒子大小 3.box-shadow 盒子阴影 案例&#xff1a;鼠标悬浮盒子上时&#xff0c;盒子有一个过度的阴影效果 三、新增背景属性 1.background-origin 设置背景图的原点 2.background-clip 设置背…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...