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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…