Maven(三):Maven的组成详解

文章目录

  • 坐标和依赖
    • 坐标详解
    • 依赖
      • 配置
      • 依赖范围
      • 传递性依赖
      • 依赖调节
      • 可选依赖
      • 优化
        • 排除依赖
        • 归类依赖
        • 优化依赖
  • 仓库
    • 本地仓库
    • 远程仓库
    • 仓库镜像
    • 常用搜索地址
  • 生命周期与插件
    • 三套生命周期
      • clean生命周期
      • default生命周期
      • site生命周期
    • 插件
  • 聚合与继承
  • 更加灵活的构建
  • 常见问题
    • 使用jdk来运行,而不是用jre
    • Invalid signature file digest for Manifest main attributes
  • 参考文献

坐标和依赖

Maven的核心功能之一:管理项目依赖

Maven中有构件的概念,其实就是指我们平时用的jar、war等文件。

Maven世界中有数量非常巨大的构件,通过坐标,我们可以唯一标识一个构件。

Maven中构件的坐标包括以下元素:

  • groupId
  • artifactId
  • version
  • packaging
  • classifier

比如说,当需要使用Java5平台上的TestNG构件的5.8版本时,就告诉Maven,去给我按照一下坐标搜索:

groupId=org.testng;

artifactId=testng;

version=5.8;

classifier=jdk1.5;

Maven就会根据以上坐标,去自己的中央仓库去找。

而我们在开发自己项目的时候,也需要为其定义适当的坐标。

坐标详解

<groupId>org.wlh</groupId>
<artifactId>helloworld</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

上面是我一个自定义项目的信息。

  • groupId:该项目隶属的实际父项目,一个父项目下可能有多个子项目,就是groupId一样,但是artifactId不一样。或者是填公司等组织信息;
  • artifactId:实际项目名称
  • version:版本
  • packaging:该项目的打包方式
  • classifier:帮助定义构建输出的一些附属构件,不能直接定义项目的classifier,而是由附加插件帮助生成。

依赖

配置

一个正式的依赖声明如下:

<project>
    ...
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
    ...
</project>

dependencies元素下包含一个或者多个dependency元素,每个dependency元素声明一个依赖。每个依赖包含以下元素:

  • groupIdartifactIdversion:基本坐标;
  • type:依赖的类型,对应于项目坐标中的packaging;默认值是jar;
  • scope:依赖的范围;
  • optional:标记依赖是否可选;
  • exclusions:用来排除传递性依赖;

依赖范围

依赖范围就是指这个依赖生效的范围。

Maven在编译、测试、运行项目的时候,分别需要一套classpath。就是说,编译的时候使用编译classpath、测试的时候使用测试的classpath,以此类推。

Maven有以下几种依赖范围:

  • compile:编译依赖范围。默认值。使用compile的依赖,对于编译、测试、运行这三种classpath都有效,简单说就是编译、测试、运行的时候都需要用到这个依赖;
  • test:测试依赖范围。只有在编译测试代码 + 运行测试代码的时候才需要;
  • provided:已提供依赖范围。编译和测试时使用,运行时无效;
  • runtime:运行时依赖范围。测试和运行时有效,编译主代码时无效;
  • system:系统依赖范围。与provided一致,唯一的区别是system的依赖必须通过systemPath元素显式的指定依赖文件的路径,与本机是强绑定,会导致不可移植,慎用。systemPath中可以引用环境变量。
  • import:导入依赖范围。

大概了解下吧,这个会影响打包时候是否把该依赖打进去的问题,test、provided这种就不用打进去了嘛,反正运行的时候也不需要。

传递性依赖

什么是传递性依赖?

项目所依赖的依赖本身也依赖其他依赖。

项目A有一个compile范围的依赖B,而B有一个compile范围的依赖C,那么C就称为是A的compile范围依赖,也是A的一个传递性依赖。

Maven的传递性依赖机制,可以再让你使用B的时候,不需要知道B依赖了什么,也不用担心会引入多余的依赖,Maven会自动帮你管理,它会去解析B,把那些必要的间接依赖,以传递性依赖的形式隐式的引入到当前的项目中去。

传递性依赖的依赖范围?

在这里插入图片描述

横向是第一直接依赖,就是B在A里的范围;

纵向是第二直接依赖,就是C在B中的范围。

举个例子,当第二直接依赖范围是test的时候,依赖C将不会传递至项目A中。

这个感觉大概了解下,有用到的时候再说吧。

依赖调节

Maven引入的传递性依赖机制,一方面大大简化和方便了依赖的声明,另一方面,大部分情况下我们只需要关心项目的直接依赖是什么,而不用考虑这些直接依赖会给项目引入什么样的传递性依赖。

但是,当传递性依赖造成问题的时候,我们需要清楚的知道这个传递性依赖是被哪个直接依赖所引入的。

依赖调节第一原则:路径最近者优先

例如,项目A有这样的依赖关系:

  • A -> B -> C -> X(1.0);
  • A - > D -> X(2.0)

由于后者的路径长度更短,所以X(2.0)会被解析使用。

依赖调节第二原则:第一声明者优先

在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用,顺序最靠前的那个依赖优先。

可选依赖

假设有这样的依赖关系,项目A依赖于项目B,项目B可选依赖于X和Y,如果这几个项目的依赖范围都是compile,那么X和Y都应该是A的可传递依赖。但是由于X和Y是B的可选依赖,所以实际上X和Y不会传递给A。

为什么会有可选依赖这种东西呢?

可能项目B实现了两个特性,其中的特性一依赖X,特性二依赖Y,但是两个特性是互斥的,不可能同时使用两个特性。

比如说B是个工具包,它支持多种数据库,MySQL、DB2等,在构建工具包的时候肯定是需要这两种数据库的驱动包,但是每次实际上只需要一种驱动包。

如何标明是可选依赖?

使用<optional>元素

<dependency>
	<groupId>...</groupId>
	<optional>true</optional>	
</dependency>

理想情况下,是不应该使用可选依赖的。

优化

排除依赖

项目A依赖项目B,但是由于一些原因,不想引入传递性依赖C,而是想自己显式的声明对于项目C的直接依赖。

这时候该怎么做呢?

首先使用exclusions元素来排除依赖,然后dependency再显式引入项目C即可。

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit</groupId>
            <artifactId>junit-bom</artifactId>
        </exclusion>
    </exclusions>
</dependency>

exclusions中可以包含一个或者多个exclusion元素,代表着可以排除一个或者多个传递性依赖。

需要注意的是,声明exclusion的时候只需要指定groupId和artifactId,不需要指定version元素。因为没必要,Maven解析后,直接依赖里不可能存在版本不同的相同依赖。所以通过groupId和artifactId就可以实现唯一定位了。

归类依赖

其实就是使用properties元素来定义属性,然后通过${属性}的方式来调用。

最突出的用法就是用来统一定义依赖的版本,一般来讲,一类依赖的版本都应该是一样的,比如统一Flink的版本。

<properties>
    <flink.version>1.13.5</flink.version>
</properties>

<dependencies>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-java</artifactId>
            <version>${flink.version}</version>
            <scope>provided</scope>
        </dependency>
</dependencies>

这种用法还是很实用的。

优化依赖

MAVEN会自动解析所有项目的直接依赖和传递性依赖,并根据规则正确判断每个依赖的范围,对于一些依赖冲突,也能根据规则进行调节,以确保任何一个构件都有唯一一个版本在最终的依赖中存在。这些工作之后,最后得到的那些依赖被称为已解析依赖(resolved dependency)。

可以运行mvn dependency:list查看当前项目的已解析依赖

这个好像IDE也能做。

运行mvn dependency:tree查看当前项目的依赖树

可以通过解析树,来查看某个依赖是通过哪条传递路径被引进来的。这个IDE也支持。

运行mvn dependency:analyze辅助分析当前项目的依赖使用情况

这个功能很重要,暂时没有在IDE上发现功能入口。

analyze的结果分两部分:

  • Used undeclared dependencies:项目中使用到的,但是没有显式声明的依赖。如果存在这种依赖,需要显式申明一下;
  • Unused declared dependencies:项目中未使用,但是显式声明了的依赖。但是这种依赖不能简单的直接删除,因为analyze只会分析编译主代码和测试代码是用到的依赖,执行测试和运行时需要的依赖它分析不出来,所以不能盲目直接删除,要自己仔细瞅瞅。

可以在IDEA中安装Maven Helper插件,来图形化查看依赖冲突情况,并支持以列表形式和树形式查看所有依赖。使用方法详见参考文献6。

其入口藏得比较隐蔽,就是pom.xml下方多了个Dependency Analyzer选项卡,点那个就行。

在这里插入图片描述

仓库

仓库,存储构件,并提供构件下载。

一个构件,在仓库中的存储路径,跟坐标是大致对应的:groupId/artifactId/version/artifactId-version.packaging。

仓库的分类:本地仓库和远程仓库

Maven在寻找构件的时候,会先去本地仓库寻找,如果本地仓库没有找到该构件,那就会去远程仓库,从远程仓库中下载构件到本地仓库,然后再从本地仓库调用。

中央仓库,是Maven核心自带的远程仓库。

私服,是另一种特殊的远程仓库。局域网内自建。

除了中央仓库和私服之外,还有很多公开的远程仓库。

本地仓库

Maven默认的本地仓库是放在用户目录下的.m2/repository/目录下,不论是windows还是linux,都是这样。

如果想修改默认的本地仓库地址的话,有两种方式:

  • 修改用户级别settings.xml,位于.m2/repository/目录下;
  • 修改全局层级settings.xml,在maven安装目录下。

修改方式是,在settings元素下,修改localRepository元素:

<settings>
	<localRepository>D:\\software\\Maven\\repository\\</localRepository>
</settings>

需要注意的是,默认情况下,.m2/repository/下的settings.xml是不存在的,如果你想设置用户层级的settings.xml的话,需要从安装目录复制出一个xml放在.m2/repository/下。

一般来讲,推荐设定用户层级配置文件进行修改,但是个人电脑的话,无所谓,全局设置更方便一些。

至于怎么安装本地jar包到本地仓库,这个之后再查吧。

如何安装本地jar包到本地仓库?

D:/software/IntelliJ_IDEA/plugins/maven/lib/maven3/bin/mvn install:install-file -Dfile=D:/tmp/smartbi-SDK-smartbi-SDK.jar -DgroupId=com.smartbi -DartifactId=smartbi-SDK -Dpackaging=jar -Dversion=1.0

如果下面出现了BUILD SUCCESS字眼的话,那就可以。

远程仓库

可以在repositories元素下自定义远程仓库:

<repositories>
    <repository>
        <id>Dcm4Che</id>
        <name>Dcm4Che</name>
        <url>http://www.dcm4che.org/maven2/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

可以使用repository元素定义一个或者多个远程仓库。

任何一个仓库声明的id必须是唯一的,Maven自带的中央仓库使用的id是central。

releases元素与snapshots元素分别用来控制Maven对于发布版和快照版构件的下载。releases为true代表允许下载发布版本的构件,为false代表不允许下载发布版本的构件。

其中,快照版本就是现行版本,是不稳定的版本。

另外,releases元素与snapshots元素还可以通过updatePolicy元素来配置Maven从远程仓库检查更新的频率。暂且不表,用到再说。

远程仓库的认证

大部分远程仓库是免费的,无需认证即可访问,但是有些是需要认证的,那怎么配置认证信息呢?

在settings.xml中:

<servers>
    <server>
        <id>my-proj</id>
        <username>repo-user</username>
        <password>repo-pwd</password>
    </server>
</servers>

注意:server元素的id必须与POM中需要认证的repository元素的id完全一致。

部署到远程仓库

怎么把自己生成的构件,部署到远程仓库给大家使用呢?

这里就需要修改项目的pom.xml文件了,在pom中配置distributionManagement元素:

<project>
	<distributionManagement>   
       <repository>   
           <id>releases</id>   
           <name>Internal Releases</name>   
           <url>http://localhost:8081/nexus/content/repositories/releases</url>
       </repository>   
       <snapshotRepository>   
           <id>Snapshots</id>   
           <name>Internal Snapshots</name>   
           <url>http://localhost:8081/nexus/content/repositories/snapshots</url>
       </snapshotRepository>   
	</distributionManagement>
</project>

url可以换成相应的远程仓库地址。

repository元素表示发布版本构件的仓库,snapshotRepository表示快照版本的仓库,其中id是远程仓库的唯一标识。

往远程仓库部署构件的时候,往往需要验证,这个之前提过了,是一样的。

一切配置完成后,命令行运行mvn clean deploy,Maven就会将项目构建形成的构件部署到对应的远程仓库。如果你构建的是快照版本,那就部署到快照仓库,否则就部署到发布版本仓库。

快照版本与发布版本的区别?

快照版本不稳定,基本是内部开发迭代使用的。

版本名为2.1-snapshot的话,实际上在发布的时候,Maven会在后面打上时间戳,比如2.1-20091214-13就表示2.1快照版本在2009年12月14日的第13次快照,有了这个时间戳,有人调用这个构建版本的时候,Maven就会找到最新时间戳的版本。

这样有两个好处,发布方可以随时部署快照版本到远程仓库,而调用法也可以随时从远程仓库调用,反正每次调用都是最新的,二者之间不用担心版本的差异问题。

当快照版本稳定了,就把快照版本修改为发布版本,比如2.1-snapshot改为2.1.

从仓库解析以来的机制

太长了,暂时不想看。

仓库镜像

镜像就是跟主远程仓库一模一样。

在settings.xml中加入你所选定的远程仓库的镜像(下面代码示例没有用):

  <mirrors>
        <mirror>
            <id>Maven2</id>
            <name>Nexus Mirror</name>
            <url>http://xxx/repository/maven-public</url> 
            <mirrorOf>*</mirrorOf>
        </mirror>
  </mirrors>

<mirrorOf>*</mirrorOf>是星号的意思是,该镜像配置是所有Maven仓库的镜像,不管是对哪个远程仓库的请求,都会被转移到http://xxx/repository/maven-public。

如果镜像仓库需要认证,那么配置一个id为internal-repository的<server>,其他一样。

<mirrorOf>repo1,repo2</mirrorOf>,代表匹配仓库repo1,repo2.。。

<mirrorOf>*,!repo2</mirrorOf>,匹配所有远程仓库,但是repo2除外。使用感叹号表示排除。

常用搜索地址

几个常用的,功能强大的公共Maven仓库搜索服务。

可以在这里面进行各版本的jar包搜索、pom格式查看以及jar包下载等。

sonatype nexus:https://repository.sonatype.org/

mvn repository:https://mvnrepository.com/ 这个比较好

生命周期与插件

Maven仓库的另外两个核心概念:生命周期和插件。

简单的总结一下:根据命令行的输入来执行插件,进而推进Maven的生命周期

mvn package就表示执行默认生命周期阶段package。而Maven的生命周期是抽象的,其实际行为是由插件来完成的,如package阶段的任务可以由maven-jar-plugin来完成。

生命周期和插件协同工作,密不可分。

什么是生命周期

生命周期其实就是对构建过程的抽象。每个周期都是构建过程中的一个环节。

这个生命周期包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等所有构建步骤。

在Maven中,实际的任务都是交由插件来完成的。这种思想模式与设计模式中的模板方法(Template Method)非常相似。模板方法模式在父类中定义算法的整体结构,子类可以通过实现或者重写父类的方法来控制实际的行为,这样既保证了算法有足够的的扩展性,又能严格控制算法的整体结构。

每个构建步骤下,都绑定了一个或多个插件行为。

用户也可以自行编写插件来自定义构建行为。

三套生命周期

Maven的生命周期不是一个整体,而是拥有三套独立的生命周期,分别是clean、default和site。

  • clean生命周期:最终目的是清理项目
  • default生命周期:最终目的是构建项目;
  • site生命周期:建立项目站点。

每个生命周期内都包含一些有顺序的阶段,并且后面的阶段依赖于前面的阶段。

用户与Maven最直接的交互方式就是调用这些生命周期阶段。

以clean生命周期为例,就包含pre-clean、clean和post-clean阶段。

clean生命周期

  • pre-clean:执行一些清理前需要完成的工作;
  • clean:清理上一次构建生成的文件;
  • post-clean:执行一些清理后需要进行的工作。

default生命周期

定义了真正的构建过程中需要执行的所有步骤,是所有生命周期中最核心的地方。

包含的阶段实在太多了,这里只介绍几个重要阶段。

  • process-sources:处理项目主资源文件,一般来讲,是对src/main/resources目录的内容进行变量替换等工作后,复制到项目输出的主classpath目录中;
  • compile:编译项目的主源码。一般来讲,是吧src/main/java目录下的java文件编译输出至主classpath目录;
  • test-compile:编译项目的测试代码,跟compile基本一致;
  • test:使用单元测试框架进行测试,测试代码不会被部署或者打包;
  • package:将编译好的代码打包成可发布格式,如jar;
  • install:将打好的包安装到Maven本地仓库;
  • deploy:将打好的包复制到Maven远程仓库。

完整周期可参考:https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

site生命周期

建立和发布项目站点。

  • pre-site:生成站点之前的工作;
  • site:生成站点文档
  • post-site:生成站点之后的工作
  • site-deploy:将生成的站点发布到服务器上。

一些常用的Maven命令跟生命周期的配合:

  • mvn clean:调用clean生命周期的pre-clean和clean阶段;
  • mvn clean install:调用clean生命周期的pre-clean和clean阶段,然后调用default生命周期的从validate到install的所有阶段。在构建项目前进行项目清理,是一个很好的习惯。

插件

Maven的核心分发包很小,只定义了抽象的生命周期,插件可以在需要的时候再额外下载。

涉及的有些复杂,暂且不表。。。

插件构件同样存在于Maven仓库中,

对于Maven官方的插件的话,其groupId都是:org.apache.maven.plugins

下面引入了一个编译插件,里面的configuration表示编译java1.8版本的源文件,生成与1.8版本兼容的字节码文件。

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

在Maven3中,当插件没有声明版本的时候,会解析最新的release,而不是latest,这样子可以避免由于快照频繁更新而导致的插件行为不稳定。

但是,还是推荐显式设定版本。

聚合与继承

粗略看了看,太难了,而且暂时用不到,先搁置。

聚合、继承、反应堆。

更加灵活的构建

这个可以看看,比较有意思。

其他的暂时可以先不用看。

常见问题

使用jdk来运行,而不是用jre

见参考文献用idea中No compiler is provided in this environment. Perhaps you are runningon a JRE,报错信息为:

No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?

这个问题折磨了我很久。

网上资料说是因为mvn的运行环境用的是jre,所以会导致mvn testmvn dependency:analyze等命令会编译失败,报这个错误。

我看网上资料,mvn -version打印出来的信息里,都是有java_home指向jdk的,但是我的打印出来是这样的:

C:\Users\xxx>mvn -version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: D:\software\Maven\apache-maven-3.6.3\bin\..
Java version: 1.8.0_111, vendor: Oracle Corporation, runtime: D:\software\jdk1.8\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

runtime指向的是jre。

尝试了很久,没有修改成功,最后尝试使用参考文献的方式,在pom.xml中强行指定compile插件的jdk版本以及路径:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <verbose>true</verbose>
        <fork>true</fork>
        <!--jdk路径-->
        <executable>D:\software\jdk1.8\bin\javac</executable>
    </configuration>
</plugin>

然后再mvn test就可以了。。。。但总感觉不是正规方案。。。

Invalid signature file digest for Manifest main attributes

正常使用打包插件打包,而且指定了入口主类,但是有时候打完jar包运行之后,还是会报标题的错。

这是因为jar包的META-INF/文件夹下,混杂了太多的其他文件,比如说ECLIPSE.RSA, ECLIPSE.SF

解决方法很简单,要么手动删除这些文件,要么通过插件配置过滤,举个例子:

<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>8</source>
					<target>8</target>
				</configuration>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<version>3.0.0</version>
				<configuration>
					<createDependencyReducedPom>false</createDependencyReducedPom>
				</configuration>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>shade</goal>
						</goals>
						<configuration>
							<transformers>
								<transformer
										implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
									<mainClass>com.custdata.Main</mainClass>
								</transformer>
							</transformers>
							<filters>
								<filter>
									<artifact>*:*</artifact>
									<excludes>
										<exclude>META-INF/*.SF</exclude>
										<exclude>META-INF/*.DSA</exclude>
										<exclude>META-INF/*.RSA</exclude>
									</excludes>
								</filter>
							</filters>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>

	</build>

上面就是pom.xml中的一个完整的build,可以看到最后面过滤了三类文件。

然后重新打包,就可以运行了。

参考文献:

  1. Invalid signature file digest for Manifest main attributes

参考文献

  1. 通过IDEA 快速 生成 可执行 jar包(超级简单) 没成功,但是过程有点意思。
  2. Maven3种打包方式之一maven-shade-plugin的使用
  3. [1119]使用maven插件maven-shade-plugin对可执行java工程及其全部依赖jar进行打包
  4. Maven插件 maven-shade-plugin 讲了shade插件每部分元素是干什么的,深入力荐。
  5. Apache-Maven-Project Resource Transformer 插件的Transformer元素详解
  6. IDEA Maven Helper插件(详细使用教程)
  7. Maven在pom.xml文件中添加自定义远程仓库
  8. 【Maven】Maven之远程仓库的认证配置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/32354.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TuyaOS 开发固件OTA上传固件指南

文章目录 一、产品创建二、TuyaOS设备开发三、固件上传 通过TuyaOS接入涂鸦云的产品全部默认支持固件OTA功能&#xff0c;TuyaOS设备实现固件OTA需要&#xff1a; 自定义产品创建TuyaOS嵌入式开发固件上传固件OTA配置与发布 等步骤实现产品OTA。本文重点讲述TuyaOS开发模式下&…

基于数据驱动 U-Net 模型的大气污染物扩散快速预测,提升计算速度近6000倍

项目背景 当前&#xff0c;常见的大气污染预测模型大多是基于物理机理构建的&#xff0c;比如空气质量预测模型 Calpuff、AERMOD、CMAQ 等。然而&#xff0c;这些模型运算较为复杂&#xff0c;对于输入数据的要求非常高&#xff0c;运算耗时也比较长&#xff0c;适合用于常规固…

如何在 ZBrush 和 UE5 中创建精灵吟游诗人(P1)

小伙伴们大家好&#xff0c;今天 云渲染小编给大家带来的是CG艺术家Hugo Sena关于“精灵吟游诗人”项目背后的工作流程&#xff0c;讨论了角色身体、服装和竖琴的工作流程&#xff0c;并解释了如何在虚幻引擎 5 中设置灯光。篇幅较长&#xff0c;分为上下两篇&#xff0c;大家接…

为摸鱼助力:一份Vue3的生成式ElementPlus表单组件

目录 一、实现背景 二、简介 三、组织架构设计 四、实现方式 五、代码示例 六、示例代码效果预览 七、项目预览地址 & 项目源码地址 目前项目还有诸多待完善的地方&#xff0c;大家有好的想法、建议、意见等欢迎再次评论&#xff0c;或于github提交Issues 一、实现…

【吃透网络安全】2023软考网络管理员考点网络安全(三)计算机系统安全评估

涉及知识点 计算机系统安全评估准则&#xff0c;计算机系统安全评估历史&#xff0c;软考网络管理员常考知识点&#xff0c;软考网络管理员网络安全&#xff0c;网络管理员考点汇总。 后面还有更多续篇希望大家能给个赞哈&#xff0c;这边提供个快捷入口&#xff01; 第一节…

解决vue依赖报错SockJSServer.js出现Cannot read property ‘headers‘ of null

前言 在做新的需求需要变更vue的项目代码时突然出现报错 TypeError: Cannot read property ‘headers’ of null at Server.socket.on (***/node_modules/webpack-dev-server/lib/servers/SockJSServer.js:68:32) 不清楚为什么突然出现了这个问题&#xff0c;之前在这个vue项目…

【安全】使用docker安装Nessus

目录 一、准备docker环境服务器&#xff08;略&#xff09; 二、安装 2.1 搜索镜像 2.2 拉取镜像 2.3 启动镜像 三、离线更新插件 3.1 获取challenge 3.2 官方注册获取激活码 3.3 使用challenge码和激活码获取插件下载地址 3.4 下载的插件以及许可协议复制到容器内 四…

数据结构第六章 图 6.4 图的应用 错题整理

4.A A. 不是简单路径的话&#xff0c;有环&#xff0c;去环路径会更短 B. 适合的 弗洛伊德算法才不适合 C. 本来就是 D 2X2矩阵拓展到3X3矩阵 再扩大 若是子集 即加入新顶点后&#xff0c;最短路径都没有变&#xff0c;错 5.B 本题用弗洛伊德更合适 但这道题只需全部代入求最…

PowerShell系列(七)PowerShell当中的Provider介绍

往期回顾PowerShell系列&#xff08;一&#xff09;&#xff1a;PowerShell介绍和cmd命令行的区别 PowerShell系列&#xff08;二&#xff09;&#xff1a;PowerShell和Python之间的差异介绍 PowerShell系列&#xff08;三&#xff09;&#xff1a;PowerShell发展历程梳理 P…

@DateTimeFormat与@JsonFormat不完全解析

目录 前言测试代码DateTimeFormat不加任何注解的情况普通请求JSON请求 JsonFormat普通请求JSON请求 其他方式&#xff08;InitBinder&#xff09;结论源码地址 前言 一直以来对DateTimeFormat与JsonFormat 比较模糊&#xff0c;容易搞忘&#xff0c;今天就做个笔记&#xff0c…

UE4自定义资产类型编辑器实现

在虚幻引擎中&#xff0c;资产是具有持久属性的对象&#xff0c;可以在编辑器中进行操作。 Unreal 附带多种资源类型&#xff0c;从 UStaticMesh 到 UMetasoundSources 等等。 自定义资源类型是实现专门对象的好方法&#xff0c;这些对象需要专门构建的编辑器来进行高效操作。 …

SQL语言的四大组成部分——DCL(数据控制语言)

1️⃣前言 SQL语言中的DCL&#xff08;Data Control Language&#xff09;是一组用于控制数据库用户访问权限的语言&#xff0c;主要包括GRANT、REVOKE、DENY等关键字。 文章目录 1️⃣前言2️⃣DCL语言3️⃣GRANT关键字4️⃣REVOKE关键字5️⃣DENY关键字6️⃣总结附&#xff1…

【kubernetes】部署网络组件Calico与CoreDNS

前言:二进制部署kubernetes集群在企业应用中扮演着非常重要的角色。无论是集群升级,还是证书设置有效期都非常方便,也是从事云原生相关工作从入门到精通不得不迈过的坎。通过本系列文章,你将从虚拟机配置开始,到使用二进制方式从零到一搭建起安全稳定的高可用kubernetes集…

基于YOLO V8的车牌识别

赵春江 2023年6月 1、前言 十年前就想实现车牌识别这项任务&#xff0c;虽然当时这项技术就已较成熟&#xff08;与现在的实现方法不同&#xff09;&#xff0c;但那时的我还具备这个能力。弹指一瞬间&#xff0c;没想到十年间人工智能技术已经发展到一个新的高度&#xff0c…

Nacos架构与原理 - 健康检查机制

文章目录 注册中心的健康检查机制Nacos 健康检查机制临时实例健康检查机制永久实例健康检查机制集群模式下的健康检查机制 注册中心的健康检查机制 想象发生地质灾害,被掩埋在废墟下,搜救队需定位才能施救。两种方法: 大喊求救,告知位置与健康状况,让搜救队知晓搜救队使用专业…

社区活动 | OpenVINO™ DevCon 中国系列工作坊第二期 | 使用 OpenVINO™ 加速生成式 AI...

生成式 AI 领域一直在快速发展&#xff0c;许多潜在应用随之而来&#xff0c;这些应用可以从根本上改变人机交互与协作的未来。这一最新进展的一个例子是 GPT 模型的发布&#xff0c;它具有解决复杂问题的能力&#xff0c;比如通过医学和法律考试这种类似于人类的能力。然而&am…

CnOpenData数字经济专利申请与授权数据

一、数据简介 自人类社会进入信息时代以来&#xff0c;数字技术的快速发展和广泛应用衍生出数字经济。与农耕时代的农业经济、工业时代的工业经济大有不同&#xff0c;数字经济是一种新的经济、新的动能、新的业态&#xff0c;并引发了社会和经济的整体性深刻变革。现阶段&…

openEuler操作系统禁用 Nouveau

目录 一、什么是openEuler 二、什么是Nouveau 三、禁用Nouveau Liunx系统安装NVIDIA显卡驱动时需要禁用Nouveau&#xff0c;openEuler操作系统也不例外&#xff0c;但是网上openEuler操作系统如何禁用Nouveau的资料比较少&#xff0c;而且基本都不靠谱&#xff0c;我找到一个…

Keras-深度学习-神经网络-人脸识别模型

目录 模型搭建 模型训练 模型搭建 ①导入所需的库&#xff0c;导入了 Keras 和其他必要的库&#xff0c;用于构建和处理图像数据。 from keras.models import Sequential from keras.layers import Dense, Flatten, Conv2D, MaxPooling2D import os from PIL import Image …

streamlit——搭建学生评分网站(告别问卷星)

streamlit搭建多人评分网站 文章目录 streamlit搭建多人评分网站一、引言二、数据准备三、streamlit代码四、数据合并代码 一、引言 当需要对班级内多人进行打分时&#xff0c;为了不使用问卷星等平台进行评分&#xff0c;使用pandas进行操作数据&#xff0c;使用streamlit进行…