Spring學習筆記:Spring的基于注解的XML的詳細配置

按照劉Java的順序,應該是從基于XML的DI開始接著上面的關于IoC容器裝配。主要介紹學習Spring的XML基于注解的詳細配置。

第一步是搭建一個Spring的基礎工程(maven管理),通過IoC機制獲取IoC容器的對象。

創建maven工程并在pom文件并添加依賴:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>liujavaspringioc</groupId><artifactId>com.zp.liu</artifactId><version>1.0-SNAPSHOT</version><properties><spring-framework.version>5.2.8.RELEASE</spring-framework.version></properties><dependencies><!--spring 核心組件所需依賴--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring-framework.version}</version><scope>compile</scope></dependency></dependencies></project>

添加這一個依賴就可以了,這個spring-context是spring framework的坐標依賴,引入它其他的framework的核心依賴就會引入進來。

添加配置文件

在resource下創建一個配置文件,命名建議spring-context.xml或者applicationContext.xml.(這個resource目錄是maven工程自帶的,在src下面,不要自己建,這也是maven工程的一個特點,規范了工程的目錄結構。)

IoC容器

Spring的核心機制是IoC(Inversion of Control),控制反轉。

就是將對象的創建和屬性設置set的方式反轉,不再是人來直接創建。
以前是開發人員創建對象,為對象賦值。現在有了Spring,就把對象和屬性的創建和管理由Spring來管理,Spring來處理對象生命周期,屬性控制以及其他對象之間的關系,這樣類和類之間就結耦,這些類實例還能做到復用。‘’

IoC也是DI的意思,dependcy injection 依賴注入,就是對象獲取它需要依賴的對象的方式,不是主動去找,而是被動通過IoC容器來找到對應的依賴,給這些被依賴的注入進來。

Spring中管理的對象的容器稱為IoC容器,IoC容器負責實例化,配置和裝配Bean。
(org.Springframework.beans和orgSpringframework.context包是Spring IoC容器的基礎)

IoC容器是一個抽象的概念,具體代碼的實現,最頂層是BeanFactory接口和他的實現類,對應就是他的IoC容器的實現。
BeanFactory僅作為IoC容器的超級接口,真正可用的容器不會用它,真正的容器的實現是對應的一系列的實現類,BeanFactory最主要的兩個容器的實現,DefaultListableBeanFactory和ApplicationContext。

DefaultListableBeanFactory

DefaultListableBeanFactory是IoC容器的真正實現,也是原始的默認的IoC容器實現,通常作為自定義的BeanFactory的父類的。通過Resource來加載Spring的xml文件,Bean信息回加載到IoC容器,啟動IoC容器就可以使用getBean方法從IoC容器中獲取Bean對象。

DefalutListableBeanFactory加載Bean的方式稱為‘懶加載’,懶加載就是只有容器啟動才會把配置文件的配置信息加載到容器,但是不會創建對象,getBean才會創建所需要的對象。
(懶加載就是容器啟動只讀取配置信息,getBean的時候才去創建對象。)

XMLBeanFactory容器,繼承了DefaulyListableBeanFzctory,是集本身就是對DefaultListableBeanFactory和XMLBeanDefintionReader的封裝調用。

Spring中還有一個XMLBeanFactory,繼承了DefaultBeanListableBeanFactory,實際上XMLBeanfactory是XMLBeanDefinitionReader和XMLBeanFactory的封裝,但是在Spring3.1以后就被棄用。

DefaultBeanListableFactory和BeanXMLFactory都只適合單體應用IoC容器。(現在基本都是分布式,這種單體應用就不適用了。)

ApplicationContext接口

這時候ApplicationContext這個目前用的最多的IoC容器,ApplicationContext時BeanFactory的子接口,繼承了BeanFactory所有的功能,實例化Bean組裝和配置。他自己又有單獨的AOP集成,消息資源處理(i18n,國際化),事件發布以及應用層的context的上下文。

Spring推薦我們用ApplicationContext做容器
ApplicationContext是非消極加載的,就是在容器一啟動,就把配置所有的默認對象創建起來,并放在容器里。

(一啟動就加載就是餓加載。getBean的時候才加載就是懶加載。對比餓漢模式和懶漢模式)

Bean
我們經常說Bean,意思就是交給容器管理的對象就是Bean。或者換個說法,Bean是SpringIoC容器實例化,管理,組裝和配置的對象。

還有一個我們經常說的元數據,也有說配置元數據。就是我們定義的Bean的信息以及他的依賴關系,這個配置元數據,可以XML,可以是注釋,也可以是Java代碼(構造器)來表示。

(1)基于XML的配置,現在在被替代
(2)基于注解的配置,從Spring2.5開始,對應的注解@Autowired,@PostConstruct,@PreDestory等
(3)基于Java的配置,從Spring3開始,可以用Java文件替代XML配置Bean,比如@Configuration,@Bean,@import和@dependOn注解

定義的配置元數據,加載到Spring容器里,會被轉換成BeanDefinition,BeanDefinition會記錄所有解析道Bean的定義。這種的好處就是沒必要,沒必要用到配置信息解析一遍配置數據。用到配置數據就不用再去解析一遍配置數據。

三者關系是這個鏈條:
配置元數據 (xml <bean …> ,注解,Java配置文件) -----》
BeanDefinition(指導容器的Bean實例化對象)-----》
Bean(容器生成管理的對象)

BeanDefinition包含以下信息:
(1)包限定類名,通常定義Bean的實現類
(2)Bean所限定的包的全限定類名,表示Bean的實際類型
(3)Bean行為的配置元素,用于說明Bean在容器中的作用范圍,生命周期限定函數
(4)對Bean所需要其他依賴的Bean類的引用,這些引用也被叫做依賴項和協作者。
(5)在新創建的對象設置其他屬性,連接池中Bean的線程數
(6)其他屬性

配置元數據被加載成BeanDefinition被容器加載,然后在容器啟動中,IoC容器啟動中來完成依賴注入。

基于XML的Bean裝配

XML是配置元數據的最基礎的配置,Spring為bean的配置提供多個標簽和多個屬性。
標簽作為和其他標簽的容器,作為文檔中的根元素。

多個XML的配置文件

可以用多個配置文件,區分不同的模塊。
(1)在使用ApplicationContext的時候,在構造函數中傳遞多個XM文件配置文件位置參數
(2)除了構造函數,還可以在XML配置文件,使用一個或者多個標簽將其他的XML配置文件導入到一個配置文件中。

構造器加載配置文件方式:

@Test
public void constructor() {//構造函數傳遞多個參數ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml","spring-config2.xml");System.out.println(Arrays.toString(ac.getBeanDefinitionNames()));
}

import引入文件:

<import resource="spring-config2.xml"/>
命名Bean

在IoC容器中,name和id屬性可以為Bean命名,id是全局唯一,name可以有多個。

<bean id="helloSpring" name="helloSpring helloSpring3" class="com.spring.core.HelloSpring"/>

實例化Bean
XML文件,bena標簽他不是對象,只是一個描述創建一個Bean的方式。

IoC容器在幫我們實例化bean對象的方法包括構造器、靜態工廠、實例工廠三種,我們可以指定實例化方式。

(1)構造函數實例化
到多數情況下,IoC容器使用構造器來創建Bean的實例,底層是基于反射的機制,使用無參構造器或者對應的參數的構造器。

內部類的實例化,在XML配置一個類的內部類,只需要在class中指明內部類的全路徑類名。

也可以使用$將內部類名與外部類名分開(如果嵌套超過兩層的內部類,那么就必須使用 $。另外,對于type屬性,則同樣需要使用 $)。

在HelloSpring類創建兩個內部類

public static class StaticInnerClass {public StaticInnerClass() {System.out.println("靜態內部類初始化");}
}public class InnerClass {public InnerClass() {System.out.println("內部類初始化");}
}

XML配置文件配置內部類

<!--靜態內部類的初始化,和外部類一樣的。 使用.或者$將內部類名與外部類名分開都行-->
<bean class="com.spring.core.HelloSpring.StaticInnerClass"/>
<bean class="com.spring.core.HelloSpring.StaticInnerClass"/><bean class="com.spring.core.HelloSpring$StaticInnerClass"/>
<bean class="com.spring.core.HelloSpring$StaticInnerClass"/><!--非靜態內部類的初始化需要依賴外部類對象-->
<bean name="helloSpring " class="com.spring.core.HelloSpring"/><bean class="com.spring.core.HelloSpring.InnerClass"><!--屬性依賴注入,后面會講--><constructor-arg ref="helloSpring"/>
</bean>
<bean class="com.spring.core.HelloSpring$InnerClass"><!--屬性依賴注入,后面會講--><constructor-arg ref="helloSpring"/>
</bean>

(2)靜態工廠方法實例化
工廠模式的應用,我們創建對象讓Spring去調用,通過Spring標簽嵌入。調用一次創建方式,將創建的對象放入容器中去管理。既然是靜態工廠,這個對象不會實例化。

靜態工廠,bean標簽中的class屬性不再是獲取bean,使用factory-bean屬性指定獲取Bean的對象的工廠方法名稱。

靜態方法類

/*** @author lx*/
public class HelloSpringStaticFactory {private static HelloSpring helloSpring = new HelloSpring();/*** 靜態工廠方法** @return 返回HelloSpring實例*/public static HelloSpring getHelloSpring() {System.out.println("靜態工廠方法");return helloSpring;}public HelloSpringStaticFactory() {System.out.println("靜態工廠不會初始化");}
}

XML配置文件配置靜態工廠

<!--class表示靜態工廠的全路徑類名-->
<!--factory-method表示靜態工廠方法-->
<bean name="helloSpring" class="com.spring.core.HelloSpringStaticFactory" factory-method="getHelloSpring"/>

靜態工廠方法違背了Spring的初衷,因為我們還是要編寫代碼new對象,但是適用于那種需要對一個集合進行實例化的情況,因為集合的實例化如果使用配置文件編寫的話,那也挺麻煩的。

(3)實例工廠方法實例化
實例工廠本身要實例化工廠類,隨后從工廠實例的非靜態方法中調用方法獲取所需的bean。

使用factory-bean屬性指定實例工廠的方式的名字(對比靜態工廠是指定方法,實例化工廠指定名字。),factory bean雖然代表一個工廠,但是其實例仍然交給Spring管理,另外Spring中還有一個FactoryBean,這只是一個類不是一個東西。

實例工廠類

/*** @author lx*/
public class HelloSpringInstanceFactory {private static HelloSpring helloSpring = new HelloSpring();/*** 靜態工廠方法** @return 返回HelloSpring實例*/public  HelloSpring getHelloSpring() {System.out.println("實例工廠方法");return helloSpring;}public HelloSpringInstanceFactory() {System.out.println("實例工廠會初始化");}
}

XML配置文件

<!--實例化工廠-->
<bean id="helloSpringInstanceFactory" class="com.spring.core.HelloSpringInstanceFactory"/>
<!--factory-bean表示實例工廠的名字-->
<!--factory-method表示實例工廠方法-->
<bean name="helloSpring" factory-bean="helloSpringInstanceFactory" factory-method="getHelloSpring"/>

基于XML的依賴裝配

依賴項注入,是指對象通過僅僅通過構造函數參數,工廠方法的參數或工廠方法構造返回對象實例后,在其上設置屬性來定義其依賴的其他對象。
隨后,在IoC容器創建Bean,會自動注入這個Bean的依賴項。這個過程和之前那種創建Bean,主動通過構造器和setter方法設置依賴項是相反的。(意思就是之前主動注入,和之前那個自己構造器和setter來注入依賴。一個是無感知的被動,一個是要自己主動注入。這就是控制反轉,控制就是誰來注入,反轉就是這個控制轉給別的人。)

IoC就是把Bean交給容器來管理,另一方面有些Bean沒有被配置元信息,但是他卻被別的要管理的Bean依賴,也就是有依賴關系存在。我不想手動去配置這個Bean的配置信息,怎么辦?

這就需要DI,依賴注入來幫助注入依賴項。不再需要主動去查找這些Bean的,直接交給DI來完成。

和前面的IoC的Bean的實例化不同(xml,注解,或者Java代碼 另一方面 構造器,靜態工廠方法,工廠方法類),DI的實例化構造方式只有兩種,一個是構造器另一個是setter方法。

(1)構造器依賴注入
構造器的依賴注入,實際上就是依靠構造函數參數來完成,每一個參數都是一個依賴項,你可以把這個構造器理解成一個靜態工廠方法來實例化依賴項。

Ioc的實例化Bean的構造器代碼

/*** @author lx* 構造器依賴注入*/
public class SimpleConstructorBased {/*** 依賴的兩個屬性*/private String property1;private String property2;/*** 測試構造器依賴注入*/public SimpleConstructorBased(String property1, String property2) {this.property1 = property1;this.property2 = property2;System.out.println("構造器依賴注入");}@Overridepublic String toString() {return "SimpleConstructorBased{" +"property1='" + property1 + '\'' +", property2='" + property2 + '\'' +'}';}
}

XML的配置

<!--構造函數屬性注入-->
<bean id="simpleConstructorBased" class="com.spring.core.SimpleConstructorBased"><!--一個constructor-arg表示一個屬性--><constructor-arg value="v1"/><constructor-arg value="v2"/>
</bean>

要注意要用到子標簽<construct - arg>,一個標簽就是一個依賴注入的依賴項。

指定參數名
想一下有一個這樣的場景,一個是同樣參數個數的構造器而且參數是基本類型的兩個構造器,Spring能不能區分出來呢?

實際上不能,在項目開發中也會發現Spring涉及到的基本類型的都是包裝類,Spring是有一點區分不了基本類型,因為這些基本類型都不是Object的子類,又在中間處理成String,你怎么做反射這些。再加上參數個數又一樣,Spring就會隨便第一個,這個第一個可能不是我們想要的。

這時候我們怎么辦,就需要在在這個子標簽里,設置name屬性來制定實例化用哪個。

<bean id="simpleConstructorBased2" 
class="com.spring.core.SimpleConstructorBased2"><constructor-arg value="1" name="property1"/><constructor-arg value="true" name="property3"/>
</bean>

測試Java代碼

/*** @author lx* 構造器依賴注入*/
public class SimpleConstructorBased2 {/*** 依賴的兩個屬性*/private int property1;private String property2;private boolean property3;/*** 測試構造器依賴注入1*/public SimpleConstructorBased2(int property1, String property2) {this.property1 = property1;this.property2 = property2;System.out.println("構造器依賴注入1");}/*** 測試構造器依賴注入2*/public SimpleConstructorBased2(int property1, boolean property3) {this.property1 = property1;this.property3 = property3;System.out.println("構造器依賴注入2");}@Overridepublic String toString() {return "SimpleConstructorBased2{" +"property1=" + property1 +", property2='" + property2 + '\'' +", property3=" + property3 +'}';}
}

指定參數類型
有可能存在這樣一種情況:多個構造器,具有相同的參數名和數量,但是參數類型不一致的情況,這樣的情況下,仍然不能確定到底使用哪一個構造器。
(前面參數數量相同和基本類型,這面是相同數量和相同的參數名)

/*** @author lx* 構造器依賴注入*/
public class SimpleConstructorBasedx {/*** 依賴的四個屬性*/private String property1;private String property2;private int property3;private boolean property4;/*** 測試構造器依賴注入1*/public SimpleConstructorBasedx(String property1, boolean property2) {this.property1 = property1;this.property4 = property2;System.out.println("構造器依賴注入1");}/*** 測試構造器依賴注入2*/public SimpleConstructorBasedx(int property1, boolean property2) {this.property3 = property1;this.property4 = property2;System.out.println("構造器依賴注入2");}/*** 測試構造器依賴注入3*/public SimpleConstructorBasedx(String property1, String property2) {this.property1 = property1;this.property2 = property2;System.out.println("構造器依賴注入3");}/*** 測試構造器依賴注入4*/public SimpleConstructorBasedx(String property1, int property3, String property2) {this.property1 = property1;this.property2 = property2;this.property3 = property3;System.out.println("構造器依賴注入4");}/*** 測試構造器依賴注入5*/public SimpleConstructorBasedx(String property1, String property2, int property3) {this.property1 = property1;this.property2 = property2;this.property3 = property3;System.out.println("構造器依賴注入5");}@Overridepublic String toString() {return "SimpleConstructorBasedx{" +"property1='" + property1 + '\'' +", property2='" + property2 + '\'' +", property3=" + property3 +", property4=" + property4 +'}';}
}

前三個構造器,構造器的形參列表參數名字完全一致,這種情況可以用指定type,

<bean id="simpleConstructorBasedx"class="com.spring.core.SimpleConstructorBasedx"><constructor-arg name="property1" value="1" type="int"/><constructor-arg name="property2" value="true"  type="boolean"/>
</bean>

指定參數順序,使用index屬性

<bean id="simpleConstructorBasedx" 
class="com.spring.core.SimpleConstructorBasedx"><!--一個constructor-arg表示一個屬性--><constructor-arg name="property1" value="xx" type="java.lang.String"/><constructor-arg name="property3" value="1" type="int" index="1"/><constructor-arg name="property2" value="yy" type="java.lang.String"/>
</bean>

(2)setter參數注入
setter依賴注入通過IoC容器調用參數的setter方法,他執行的順序是在構造器實例化后再實例setter方法來實例化。

ApplicationContext對于他所管理Bean的支持同時基于構造器和基于setter方法的依賴注入,依賴注入的屬性開始都是value的bean字符串保存起來,隨后通過PropertiyEditor(屬性編譯器,Spring內部擴展Java原生的PropertyEditor)轉換為實際類型。轉換過程是IoC容器自動轉換,當然這個編輯器也是可以自定義的。

和前面的標簽對比,setter方法對應的子標簽是,name屬性表示屬性名 value 屬性表示屬性值。

/*** @author lx*/
public class SimpleSetterBased {/*** 依賴的5個屬性*/private String property1;private String property2;private int property3;private boolean property4;private int property5;/*** 構造器依賴注入*/public SimpleSetterBased(String property1, String property2) {this.property1 = property1;this.property2 = property2;System.out.println("構造器依賴注入");}//setter方法依賴注入,idea生成stter方法public void setProperty3(int property3) {System.out.println("setter注入property3");this.property3 = property3;}public void setPr11operty5(int property5) {System.out.println("setter注入property5");this.property5 = property5;}public void setProperty4(boolean property4) {System.out.println("setter注入property4");this.property4 = property4;}@Overridepublic String toString() {return "SimpleSetterBased{" +"property1='" + property1 + '\'' +", property2='" + property2 + '\'' +", property3=" + property3 +", property4=" + property4 +", property5=" + property5 +'}';}
}

xml配置文件

<!--setter and constructor-->
<bean id="simpleSetterBased" class="com.spring.core.SimpleSetterBased"><!--構造器參數 name表示參數名 value 表示參數值--><constructor-arg name="property1" value="xxx"/><constructor-arg name="property2" value="yyy"/><!--setter方法 name表示屬性名 value 表示屬性值--><property name="property3" value="123"/><property name="property4" value="true"/><!--name還可以表示方法名除了set后面的部分,不一定是屬性名--><property name="Pr11operty5" value="321"/>
</bean>

工廠方法的依賴注入(區別之前的依賴注入)

使用靜態工廠方法或者實例工廠方式實例bean時,同樣可以注入依賴,方法上的參數可視為bean的依賴項,用于構造器注入,同樣使用< constructor-arg >標簽,而setter注入則不受影響。

依賴注入的解析流程

容器執行Bean的解析流程
1 ApplicationContext容器被實例化,包含所有Bean的所有配置元信息
2 對于每一個bean,其依賴項以屬性set方法,構造函數參數或靜態工廠方法的參數形式表示。創建bean,這些依賴項傳遞依賴給bean。
3 每個需要注入的依賴項,要實際設置value的值,或對Bean的另一個ref引用,最開始統一為一個字符串格式。
4 屬性值在字符串描述轉換為實際屬性的類型。

循環依賴

bean的依賴項和依賴項的依賴項會在bean創建之前創建(也就是A依賴B,B會在A創建前就創建成功。)
這種依賴關系創建的情況,構造器注入就會出現循環依賴,A依賴B,B依賴A。
一種解決方式就是使用setter注入,當兩個互相依賴的bean都創建完畢之后,才會調用set方法進行依賴注入。

構造器和setter注入的選擇

我們怎么選擇依賴注入的方式,看情況分心:
對于強制依賴使用構造器
對于可選的依賴項選擇setter方法(在setter方法上加@required,使這個屬性為必填屬性)

public class MyBean {private String requiredProperty;@Required  // 標記此屬性必須注入public void setRequiredProperty(String requiredProperty) {this.requiredProperty = requiredProperty;}
}

適用于非顯式自動裝配的場景(如早期XML配置),或需明確標記某些屬性為必需依賴的情況。
標記在Setter方法上,表示該屬性必須在Bean初始化時被顯式賦值(通過XML配置、Java Config或自動裝配)

Spring團隊現在推薦使用構造器注入,構造器注入能夠保證注入的組件不可變,并且確保需要的依賴不為null。此外,構造器注入的依賴總是能夠在返回客戶端(組件)代碼的時候保證完全初始化的狀態,還能檢測循環依賴。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/85717.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85717.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/85717.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

(四)動手實現多層感知機:深度學習中的非線性建模實戰

1 多層感知機&#xff08;MLP&#xff09; 多層感知機&#xff08;Multilayer Perceptron, MLP&#xff09;是一種前饋神經網絡&#xff0c;包含一個或多個隱藏層。它能夠學習數據中的非線性關系&#xff0c;廣泛應用于分類和回歸任務。MLP的每個神經元對輸入信號進行加權求和…

第十三篇:MySQL 運維自動化與可觀測性建設實踐指南

本篇重點介紹 MySQL 運維自動化的關鍵工具與流程&#xff0c;深入實踐如何構建高效可觀測體系&#xff0c;實現數據庫系統的持續穩定運行與故障快速響應。 一、為什么需要 MySQL 運維自動化與可觀測性&#xff1f; 運維挑戰&#xff1a; 手動備份容易遺漏或失敗&#xff1b; …

蜜獾算法(HBA,Honey Badger Algorithm)

2021年由Hashim等人提出&#xff08;論文&#xff1a;Honey Badger Algorithm: A New Metaheuristic Algorithm for Solving Optimization Problems&#xff09;。模擬蜜獾在自然界中的智能捕食行為&#xff0c;屬于群體智能優化算法&#xff08;與粒子群PSO、遺傳算法GA同屬一…

Duix.HeyGem:以“離線+開源”重構數字人創作生態

在AI技術快速演進的今天,虛擬數字人正從高成本、高門檻的專業領域走向大眾化應用。Duix.HeyGem 數字人項目正是這一趨勢下的杰出代表。該項目由一支擁有七年AI研發經驗的團隊打造,通過放棄傳統3D建模路徑,轉向真人視頻驅動的AI訓練模型,成功實現了低成本、高質量、本地化的…

HTTP常見的請求方法、響應狀態碼、接口規范介紹

HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是Web通信的基礎協議&#xff0c;用于客戶端和服務器之間的請求和響應。本文將詳細介紹HTTP常見的請求方法、響應狀態碼以及接口規范&#xff0c;幫助開發者更好地理解和使用HTTP協議。 一、HTTP請求方法 HTTP請求方…

基于Matlab實現LDA算法

線性判別分析&#xff08;Linear Discriminant Analysis, LDA&#xff09;是一種經典的統計方法&#xff0c;常用于特征降維和分類問題。在機器學習領域&#xff0c; 一、LDA基本原理 LDA的目標是尋找一個投影空間&#xff0c;使得類間距離最大化&#xff0c;同時保持類內距離…

matlab基于GUI實現水果識別

基于GUI實現水果識別系統&#xff0c;限一個圖片內存在一種水果 圖像處理是一種利用計算機分析圖像以達到預期結果的技術。圖像處理一般指數字圖像處理&#xff0c;而數字圖像指由工業相機、攝像機、掃描儀等設備捕捉到的二維數組&#xff0c;數組中的元素稱為像素&#xff0c…

XML 編碼:結構化數據的基石

XML 編碼:結構化數據的基石 引言 XML(可擴展標記語言)作為互聯網上廣泛使用的數據交換格式,已經成為結構化數據存儲和傳輸的重要工具。本文旨在深入探討XML編碼的原理、應用場景以及編碼規范,幫助讀者更好地理解和運用XML。 XML編碼概述 1. XML的起源 XML誕生于1998年…

虛擬機無法開啟-關掉虛擬化

這個問題我之前解決過&#xff0c;沒做筆記&#xff0c;這次記錄下&#xff0c;最常見都上開啟bois的cpu虛擬化。 其次是啟動或關閉功能頁面也需要選擇&#xff0c;再就是和wsl都沖突問題&#xff0c;就是今天這個問題 您的主機不滿足在啟用 Hyper-V 或 Device/Credential Gua…

Python數據可視化科技圖表繪制系列教程(二)

目錄 表格風格圖 使用Seaborn函數繪圖 設置圖表風格 設置顏色主題 圖表分面 繪圖過程 使用繪圖函數繪圖 定義主題 分面1 分面2 【聲明】&#xff1a;未經版權人書面許可&#xff0c;任何單位或個人不得以任何形式復制、發行、出租、改編、匯編、傳播、展示或利用本博…

LeetCode算法題 (搜索二維矩陣)Day18!!!C/C++

https://leetcode.cn/problems/search-a-2d-matrix/description/ 一、題目分析 給你一個滿足下述兩條屬性的 m x n 整數矩陣&#xff1a; 每行中的整數從左到右按非嚴格遞增順序排列。每行的第一個整數大于前一行的最后一個整數。 給你一個整數 target &#xff0c;如果 ta…

獵板硬金鍍層厚度:新能源汽車高壓系統的可靠性基石

在新能源汽車的電池管理系統&#xff08;BMS&#xff09;和電機控制器中&#xff0c;硬金鍍層厚度直接關系到高壓環境下的電氣穩定性與使用壽命。獵板針對車載場景開發的耐電遷移方案&#xff08;金層 2.5μm&#xff0c;鎳層 8μm&#xff09;&#xff0c;經 150℃/85% RH 高壓…

亞馬遜站內信規則2025年重大更新:避坑指南與合規策略

亞馬遜近期對Buyer-Seller Messaging&#xff08;買家-賣家站內信&#xff09;規則進行了顯著收緊&#xff0c;明確將一些曾經的“灰色操作”列為違規。違規操作輕則收到警告&#xff0c;重則導致賬戶暫停或績效受限。本文為您全面解析本次規則更新的核心要點、背后邏輯&#x…

WPF可拖拽ListView

1.控件描述 WPF實現一個ListView控件Item子項可刪除也可拖拽排序&#xff0c;效果如下圖所示 2.實現代碼 配合 WrapPanel 實現水平自動換行&#xff0c;并開啟拖拽 <ListViewx:Name"listView"Grid.Row"1"Width"300"AllowDrop"True&…

相機--雙目立體相機

教程 鏈接1 教程匯總 立體匹配算法基礎概念 視頻講解攝像機標定和雙目立體原理 兩個鏡頭。 雙目相機也叫立體相機--Stereo Camera&#xff0c;屬于深度相機。 作用 1&#xff0c;獲取圖像特征&#xff1b; 2&#xff0c;獲取圖像深度信息&#xff1b; 原理 原理和標定 …

Unity3D仿星露谷物語開發59之定制角色襯衫

1、目標 自定義角色襯衫、褲子、手臂顏色。 2、概念 在Assets -> Sprites -> Output Textures下&#xff0c;Customised_farmer為目前角色所用的精靈表。 如果上面是輸出紋理&#xff0c;那么輸入紋理是什么呢&#xff1f;它位于Assets/Sprites/Sprite Textures/Chara…

【HarmonyOS 5】游戲開發教程

一、開發環境搭建 ?工具配置? 安裝DevEco Studio 5.1&#xff0c;啟用CodeGenie AI助手&#xff08;Settings → Tools → AI Assistant&#xff09;配置游戲模板&#xff1a;選擇"Game"類型項目&#xff0c;勾選手機/平板/折疊屏多設備支持 二、游戲引擎核心架構…

深度探索:如何用DeepSeek重構你的工作流

前言:AI時代的工作革命 在人工智能浪潮席卷的今天,DeepSeek作為國產大模型的代表之一,正以其強大的自然語言處理能力、代碼生成能力和多模態交互特性,重新定義著人類的工作方式。根據IDC報告顯示,2024年企業級AI應用市場規模已突破800億美元,其中智能辦公場景占比達32%,…

Linux 進程調度與管理:從內核管理到調度機制的深度解析

文章目錄 引言一、進程基礎&#xff1a;概念與核心數據結構1.1 進程的本質&#xff1a;程序的動態化身1.2 進程控制塊&#xff08;PCB&#xff09;&#xff1a;內核管理的靈魂1.2.1 鏈表節點嵌入1.2.2 鏈表操作宏1.2.3 全局鏈表管理 1.3 進程查看與系統調用1.3.1 通過系統調用獲…

信息學奧賽一本通 1570:【例 2】能量項鏈 | 1843:【06NOIP提高組】能量項鏈 | 洛谷 P1063 [NOIP 2006 提高組] 能量項鏈

【題目鏈接】 ybt 1570&#xff1a;【例 2】能量項鏈 ybt 1843&#xff1a;【06NOIP提高組】能量項鏈 洛谷 P1063 [NOIP 2006 提高組] 能量項鏈 【題目考點】 1. 動態規劃&#xff1a;區間動規 2. 環形序列 解決方法&#xff1a;破環為鏈 模板題&#xff1a;洛谷 P1880 [N…