WEB-INF文件夹的作用:
WEB-INF是servlet-container中的安全目录,这个目录下的文件只能被后台代码方法,不能通过浏览器访问。
WEB-INF下包括web.xml, lib和classes 3个文件(夹)。classes下包括xml配置文件等。
html,js, css, image等静态资源放在WEB-INF外面,否则浏览器访问不到。
maven中的lifecyclye,phase和plugin:goal区别:
maven有3个lifecycle:clean, default, site。
default周期有clean,compile, resource, test, package, install , deploy等phase,执行后面的phase则前面的phase也会被顺带执行,即执行mvn install,前面所有的phase如clean, compile都会被依次执行。
plugin:goal:其中plugin一般和phase的名字相同,但他们2个根本不是一回事。插件和目标中间用:分隔,phase没有。
执行一个plugin:goal则只是执行这个plugin:goal,没有前后依赖关系,
如mvn install:install执行的是install插件的install目标,只是把已经生成的.jar/.war安装到本地repo。并不会去执行编译、打包等过程。
而mvn install就会执行编译、打包、安装等过程。
plugin:goal也可以配置到phase中去, 在pom.xml中可以指定plugin:goal到某一个phase,在执行到这个phase的时候plugin:goal会被自动执行。
maven的版本问题:参考https://www.cnblogs.com/huang0925/p/5169624.html
- 非SNAPSHOT版本,mvn会去本地查找,找不到再去nexus查找,如果提供方发布了一个新的版本,则必须在调用方改变版本,否则调用方始终用的旧的。
- SNAPSHOT 版本,如1.0-SNAPSHOT,nexus仓库里并不存在一个名为xxx-1.0.SNAPSHOT.jar的文件,而是根据metadata.xml来判断最新的版本号并下载。在调用方的local repo里的jar名可以看出来。
snapshot版本适合于公司内部开发,这样可以快速发布,调用放也能快速引用,在正式发布出去,版本号一定要去掉snapshot,同时也不要依赖任何snapshot。
snapshot版本可以设置updatePolicy,有always,daily,interval,never,默认是daily即每天第一次从nexus访问,后面就用本地缓存了。可以设置interval:minutes,这样做缓存和及时性之间取得平衡。
idea中maven下载不到snapshot jar问题:toggle offline mode去掉,等个几分钟就可以了。
settings.xml中的mirrorOf, mirror设置仓库镜像,一般公司内部有nexus,可以设置mirrorOf=*,这样只能去公司内部nexus下载,mirrofOf=central相当于屏蔽了中央仓库。
pom.xml中设置多个profile,一般有dev,test,pre,release,用于保存不同环境下的配置文件,在build->war.plugin设置webResource,不同的mvn -p profile参数决定拷贝不同的配置文件到war包中。
用了disconf后,只需要在不同profile下保存不同的disconf.properties就可以了。配置通过disconf统一管理。
mybatis生成的mapper.xml在java文件中,即使在父模块中配置了resource plugin不过滤.xml文件也不行,需要在当前模块的pom.xml中设置,resources和plugins平级。
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
这样打的包中就会包含资源文件了。
- 如果全局exclude某个artifact?
例如日志框架我们引入了slf4j,那么jcl就不能引入了,而很多其他artifact都依赖了jcl(commons-logging),如果在每一个依赖里都添加exclusion,那样很麻烦,而且很多时候会忘记去添加。如果maven能提供全局exclude某个artifact就好了,可惜没有。解决方法有2种: - 在pom.xml里添加maven-enforcer-plugin插件,配置jar的黑名单,这样在打war包的时候如果发现有对commons-logging的依赖,则报错,打包失败。当然了,开发人员依旧可以在代码里import commons-logging中的类。这个属于防御式的。
- 在pom.xml里引入commons-logging,scope设置为provided,你没看错,就是要手动引入commons-logging,这样根据依赖最短路径原则,其他依赖所依赖的commons-logging就会被omitted,scope为provided这样在打的war中是不含commons-logging,但是开发人员这个时候仍然能在代码里import commons-logging中的类。这个方法貌似还没上一个解决方法好,
- 如果我们有自己的私服,那么传入一个没有任何代码的commons-logging.jar,在pom.xml里引入这个“垃圾”commons-logging,scope设置为provided。
参考:https://www.cnblogs.com/E-star/p/3635540.html
Maven工程打jar包:
1、maven shade插件,
https://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html
https://crunchify.com/how-to-create-only-one-executable-jar-file-with-all-required-jars-properties-and-resources/
shade插件是把所有的jar和资源文件都打成一个jar,这样可能会出现相同的文件,只会选择其中一个。可能会造成冲突,同时也会造成jar文件内资源太多,混乱。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.xxx.msg.server.MsgWebSocketServer</Main-Class>
<Build-Jdk>1.7.0_80</Build-Jdk>
</manifestEntries>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.tooling</resource>
</transformer>
</transformers>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>all-in-one</shadedClassifierName>
<!--下面exclude没用,只能在dependency中设置exclude -->
<!--<artifactSet>
<excludes>
<exclude>com.itextpdf:itextpdf</exclude>
<exclude>com.lowagie:itext</exclude>
<exclude>bouncycastle:bcmail-jdk14</exclude>
<exclude>bouncycastle:bcprov-jdk14</exclude>
<exclude>bouncycastle:bctsp-jdk14</exclude>
</excludes>
</artifactSet>-->
</configuration>
</execution>
</executions>
</plugin>
2、maven assembly插件,把所有jar和资源文件打进一个zip包,和war包类似,缺点就是配置稍显复杂。
- 配置maven-jar-plugin,设置manifest
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<!--这个一定要设置成default-jar,否则maven-jar会执行2次,生成2个jar包 -->
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>com.xxx.msg.server.MsgWebSocketServer</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
- 设置maven-dependency-plugin,拷贝依赖的jar到lib文件夹
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
- 配置maven-assembly
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
assembly.xml配置
<assembly>
<id>executable</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>target</directory>
<includes>
<include>*.jar</include>
</includes>
<outputDirectory>/</outputDirectory>
</fileSet>
<fileSet>
<directory>target/lib</directory>
<outputDirectory>/lib</outputDirectory>
</fileSet>
</fileSets>
</assembly>
注意:上面maven-jar, maven-dependency, maven-assembly插件配置需要的module中,这样只对当前module有效。然后在父module执行package,否则会报相关jar在nexus上找不到。
部署时要想不用快照版本,可以在命令行改打包出来的版本号:
mvn versions:set -DnewVersion=版本号 -Dmaven.test.skip=true clean deploy -f pom.xml
如果在打包时候要改某个依赖的版本,可以用:
mvn -Dmaven.test.skip=true -Dspring.version=4.3.17.RELEASE clean package -f pom.xml