Maven进阶宝典

Posted 心若不动,风又奈何;你若不伤,岁月无恙。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Maven进阶宝典相关的知识,希望对你有一定的参考价值。

前言:

    团队在开发过程中用的是maven项目,由于对maven的一些打包流程以及相关参数配置不是太了解,因此应大家的需求做一下maven的讲解,为了不误导大家,看了很多相关资料,自己也实验了一下,就把自己觉得对大家有用的东西列出来,做了一些简单的介绍,起到抛砖引玉的作用,希望能对大家能有帮助。

一、什么是maven

  Maven是一个Java语言编写的开源项目管理工具,是Apache软件基金会的顶级项目。主要用于项目构建,依赖管理,项目信息管理。

二、Maven诞生的背景

  Maven这个单词来自于意第绪语(犹太语),意为知识的积累,最初在Jakata Turbine项目中用来简化构建过程。当时有一些项目(有各自Ant build文件),仅有细微的差别,而JAR文件都由CVS来维护。于是希望有一种标准化的方式构建项目,一个清晰的方式定义项目的组成,一个容易的方式发布项目的信息,以及一种简单的方式在多个项目中共享JARs。

三、Maven特点

        1. maven不仅是构建工具,它还是依赖管理工具和项目管理工具,提供了中央仓库,能够帮我们自动下载构件。

        2.为了解决的依赖的增多,版本不一致,版本冲突,依赖臃肿等问题,它通过一个坐标系统来精确地定位每一个构件(artifact)。

        3.还能帮助我们分散在各个角落的项目信息,包括项目描述,开发者列表,版本控制系统,许可证,缺陷管理系统地址。

        4.maven还为全世界的java开发者提供了一个免费的中央仓库,在其中几乎可以找到任何的流行开源软件。通过衍生工具(Nexus),我们还能对其进行快速搜索

        5.maven对于目录结构有要求,约定优于配置,用户在项目间切换就省去了学习成本。

        6.跨平台,是声明式的,没有依赖管理。

四、Maven私服的搭建

  一、为什么搭建Maven私服

  有些公司都不提供外网给项目组人员,因此就不能使用maven访问远程的仓库地址,所以很有必要在局域网里找一台有外网权限的机器,搭建nexus私服,然后开发人员连到这台私服上,这样的话就可以通过这台搭建了nexus私服的电脑访问maven的远程仓库。  

 二、Maven仓库

       Maven库:

http://repo2.maven.org/maven2/

Maven依赖查询:

http://mvnrepository.com/

      maven的仓库只有两大类:1.本地仓库 2.远程仓库,在远程仓库中又分成了3种:2.1 中央仓库 2.2 私服 2.3 其它公共库;如图:

 

       1.本地仓库

        Maven在本地存储构件的地方。

       2. 远程仓库

        2.1 中央仓库

          中央仓库是默认的远程仓库,maven在安装的时候,自带的就是中央仓库的配置。

        2.2 私服

          Maven私服的 个特性:

1.节省自己的外网带宽:减少重复请求造成的外网带宽消耗

2.加速Maven构件:如果项目配置了很多外部远程仓库的时候,构建速度就会大大降低

3.部署第三方构件:有些构件无法从外部仓库获得的时候,我们可以把这些构件部署到内部仓库(私服)中,供内部maven项目使用

4.提高稳定性,增强控制:Internet不稳定的时候,maven构建也会变的不稳定,一些私服软件还提供了其他的功能

5.降低中央仓库的负荷:maven中央仓库被请求的数量是巨大的,配置私服也可以大大降低中央仓库的压力

当前主流的maven私服:

1.Apache的Archiva

2.JFrog的Artifactory

3.Sonatype的Nexus

  

 三、搭建Maven私服

详细介绍地址:http://www.cnblogs.com/quanyongan/archive/2013/04/24/3037589.html

       http://blog.csdn.net/clj198606061111/article/details/52200928

在安装安装nexus如果出现这种情况:   

                  

                  以管理员身份运行cmd.exe即可。

五、Maven安装

    安装教程:http://jingyan.baidu.com/article/4f7d5712a1306c1a21192746.html

六、settings.xml配置

   详细介绍地址:http://blog.csdn.net/u014527058/article/details/50906343

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
 3           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 4           xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
 5 
 6 
 7   <proxies>
 8 
 9   </proxies>
10 
11 
12   <servers>
13 
14     <!--用来实现热部署 -->
15     <server>  
16        <id>tomcat7x</id>  
17        <username>admin</username>  
18        <password>admin</password>  
19     </server>  
20     <!--用来发布项目到nexus的相对应的发布目录下 ,这里的id要和eclipse中配置的一样-->
21     <server>  
22        <id>user-release</id>  
23        <username>deployment</username>  
24        <password>deployment123</password>  
25     </server> 
26     <!--用来发布项目到nexus的相对应的快照目录下 ,这里的id要和eclipse中配置的一样-->
27     <server>  
28        <id>user-snapshots</id>  
29        <username>deployment</username>  
30        <password>deployment123</password>  
31     </server> 
32   </servers>
33 
34   <mirrors>
35 
36     <mirror>
37       <id>public</id>
38       <mirrorOf>*</mirrorOf>
39       <name>Human Readable Name for this Mirror.</name>
40        <!--<url>http://repo.maven.apache.org/maven2/</url>-->
41     <url>http://maven私服ip地址:8081/nexus/content/groups/public/</url>
42     </mirror>
43     
44   </mirrors>
45   
46 
47   <profiles>
48 
49     <profile>
50       <id>nexus</id>
51       <repositories>
52         <repository>
53           <id>central</id>
54           <url>http://central</url>
55           <releases><enabled>true</enabled></releases>
56           <snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots>
57         </repository>
58       </repositories>
59       <pluginRepositories>
60         <pluginRepository>
61           <id>central</id>
62           <url>http://central</url>
63           <releases><enabled>true</enabled></releases>
64           <snapshots><enabled>true</enabled></snapshots>
65         </pluginRepository>
66       </pluginRepositories>
67     </profile>
68     
69     <profile>  
70       <id>jdk-1.7</id>  
71       <activation>  
72           <activeByDefault>true</activeByDefault>  
73           <jdk>1.7</jdk>  
74       </activation>  
75       <properties>  
76           <maven.compiler.source>1.7</maven.compiler.source>  
77           <maven.compiler.target>1.7</maven.compiler.target>  
78           <maven.compiler.compilerVersion>1.7</maven.compiler.compilerVersion>  
79       </properties>  
80     </profile>  
81 
82   </profiles>
83 
84   <activeProfiles>
85     <activeProfile>nexus</activeProfile>
86   </activeProfiles> 
87 </settings>

 

七、Maven工程的创建

   省略,这些在网上一搜一大堆,这里就不再啰嗦了。

   知识驿站(具体了解地址:http://blog.csdn.net/cnhk1225/article/details/51189467):

      maven中的仓库分为两种,snapshot快照仓库和release发布仓库。snapshot快照仓库用于保存开发过程中的不稳定版本,release正式仓库则是用来保存稳定的发行版本。定义一个组件/模块为快照版本,只需要在pom文件中在该模块的版本号后加上-SNAPSHOT即可(注意这里必须是大写)

八、pom.xml的配置

  一、插件配置详解地址:

      http://www.cnblogs.com/dennyzhangdd/p/5831112.html

  

  1 <?xml version="1.0"?>
  2 <project
  3     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
  4     xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  5     <modelVersion>4.0.0</modelVersion>
  6     <parent>
  7         <groupId>组织名</groupId>
  8         <artifactId>父工程名</artifactId>
  9         <version>版本号</version>
 10     </parent>
 11     <artifactId>子工程名</artifactId>
 12     <packaging>war</packaging>
 13     <dependencies>
 14 
 15     </dependencies>
 16     <profiles>
 17        <!-- 开发/测试环境,默认激活 -->
 18        <profile>
 19            <id>dev</id>
 20            <properties>
 21               <env>dev</env>
 22               <tomcat.host>远程tomcat的地址</tomcat.host>
 23               <tomcat.port>${tomcatPort}</tomcat.port>
 24               <tomcat.username>admin</tomcat.username>
 25               <tomcat.password>admin</tomcat.password>
 26            </properties>
 27            <activation>
 28               <activeByDefault>true</activeByDefault><!--默认启用的是dev环境配置-->
 29            </activation>
 30        </profile>
 31        <!-- 生产环境 -->
 32        <profile>
 33            <id>prod</id>
 34            <properties>
 35               <env>prod</env>
 36               <tomcat.host>远程服务器ip地址</tomcat.host>
 37               <tomcat.port>${tomcatPort}</tomcat.port>
 38               <tomcat.username>admin</tomcat.username>
 39               <tomcat.password>admin</tomcat.password>
 40            </properties>
 41        </profile>
 42        <profile>
 43            <id>qa</id>
 44            <properties>
 45               <env>qa</env>
 46               <tomcat.host>远程服务器ip地址</tomcat.host>
 47               <tomcat.port>${tomcatPort}</tomcat.port>
 48               <tomcat.username>admin</tomcat.username>
 49               <tomcat.password>admin</tomcat.password>
 50            </properties>
 51        </profile>
 52     </profiles>  
 53     
 54     <build>
 55         <finalName>ucf-personal</finalName>
 56         <plugins>
 57             <!-- 用来支持maven自带的命令 -->
 58             <plugin>
 59                 <groupId>org.apache.maven.plugins</groupId>
 60                 <artifactId>maven-compiler-plugin</artifactId>
 61                 <version>3.1</version>
 62                 <configuration>
 63                     <source>1.7</source>
 64                     <target>1.7</target>
 65                 </configuration>
 66             </plugin>
 67             <!-- 用cargo插件来实现项目自动远程热部署 -->
 68             <plugin>
 69                 <groupId>org.codehaus.cargo</groupId>
 70                 <artifactId>cargo-maven2-plugin</artifactId>
 71                 <version>1.4.9</version>
 72                 <configuration>
 73                     <container>
 74                         <containerId>tomcat7x</containerId>
 75                         <type>remote</type>
 76                     </container>
 77                     <configuration>
 78                         <type>runtime</type>
 79                         <properties>
 80                             <cargo.remote.uri>http://${tomcat.host}:${tomcat.port}/manager/text</cargo.remote.uri>
 81                             <cargo.remote.username>${tomcat.username}</cargo.remote.username>
 82                             <cargo.remote.password>${tomcat.password}</cargo.remote.password>
 83                         </properties>
 84                     </configuration>
 85                 </configuration>
 86             </plugin>
 87         </plugins>
 88        <!-- 根据构建环境的改变(生产或测试)来获得相应的值 -->
 89        <filters> <!-- 指定使用的 filter -->
 90          <filter>src/main/resources/filter/${env}.properties</filter>
 91        </filters>
 92        <resources>
 93          <resource> <!-- 配置需要被替换的资源文件路径, db.properties 应该在 src/main/resource 目录下 -->
 94            <directory>src/main/resources</directory>
 95            <filtering>true</filtering> <!-- 是否使用过滤器 -->
 96          </resource>
 97        </resources>
 98     </build>
 99     <properties>
100         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
101     </properties>
102     <distributionManagement>
103         <repository>
104             <id>releases</id>
105             <name>releases</name>
106             <url>http://远程服务器ip地址:8081/nexus/content/repositories/releases/</url>
107         </repository>
108         <snapshotRepository>
109             <id>snapshots</id>
110             <name>snapshots</name>
111             <url>http://远程服务器ip地址:8081/nexus/content/repositories/snapshots/</url>
112         </snapshotRepository>
113     </distributionManagement>
114 </project>

    web.xml动态给变量赋值

1.在<profile><properties>标签中添加与web.xml中相对应的${cas.serverLoginUrl}的key作为标签,

 在里面赋值,如:<cas.serverLoginUrl>http://10.1.1.1</cas.serverLoginUrl>

 1 <profiles>
 2     <profile>
 3         <id>development</id>
 4         <activation>
 5             <activeByDefault>true</activeByDefault>
 6         </activation>
 7         <properties>
 8             <profiles.active>dev</profiles.active>
 9             <mybatis.log>ERROR</mybatis.log>
10             <log.path>/opt/dev/</log.path>
11             <cas.serverLoginUrl>http://10.1.1.1</cas.serverLoginUrl>
12             <cas.serverName>http://10.1.1.1</cas.serverName>
13             <cas.serverUrlPrefix>http://10.1.1.1</cas.serverUrlPrefix>
14         </properties>
15     </profile>
16 </profiles>

 

2.在工程的pom.xml中,新增过滤web资源配置

 1 <plugin>
 2     <groupId>org.apache.maven.plugins</groupId>
 3     <artifactId>maven-war-plugin</artifactId>
 4     <version>2.1.1</version>
 5     <configuration>
 6         <webResources>
 7             <resource>
 8                 <directory>src/main/webapp</directory>
 9                 <filtering>true</filtering>
10             </resource>
11         </webResources>
12     </configuration>
13 </plugin>

 

3.在web.xml中用占位符替换

 1 <filter>
 2    <filter-name>CASFilter</filter-name>
 3    <filter-class>com.ezubo.global.om.web.filter.LoginFilter</filter-class>
 4    <init-param>
 5       <param-name>casServerLoginUrl</param-name>
 6       <param-value>${cas.serverLoginUrl}</param-value>
 7    </init-param>
 8    <init-param>
 9       <param-name>serverName</param-name>
10       <param-value>${cas.serverName}</param-value>
11    </init-param>
12    <init-param>
13       <param-name>noFilterUrl</param-name>
14       <param-value>*.js</param-value>
15    </init-param>
16 </filter>

 

 二、Jetty插件运行Maven Web工程

      详细介绍地址:https://my.oschina.net/cokolin/blog/409164

 1 <?xml version="1.0"?>
 2 <plugin>
 3     <groupId>org.mortbay.jetty</groupId>
 4     <artifactId>jetty-maven-plugin</artifactId>
 5     <version>8.1.16.v20140903</version>
 6     <configuration>
 7         <scanIntervalSeconds>5</scanIntervalSeconds>
 8         <webApp>
 9             <contextPath>/ucf-company</contextPath>
10         </webApp>
11         <connectors>
12             <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
13                 <port>9080</port>
14             </connector>
15             <connector implementation="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
16                 <port>9443</port>
17                 <password>changeit</password>
18             </connector>
19             <!-- 这两个connector的配置要改为: -->
20             <connector implementation="org.eclipse.jetty.server.bio.SocketConnector">
21                 <port>8080</port>
22             </connector>
23             <connector implementation="org.eclipse.jetty.server.ssl.SslSocketConnector">
24                 <port>8443</port>
25                 <password>changeit</password>
26             </connector>
27         </connectors>
28     </configuration>
29 </plugin>

 

  三、Maven混淆代码

      Maven的proguard插件只能混淆jar包。如果要混淆Web项目则将Web混淆的工程jar的classes替换打的war包的classes文件夹即可。 

 
 1   <build>
 2       <plugins>
 3        <plugin>
 4         <groupId>com.github.wvengen</groupId>
 5         <artifactId>proguard-maven-plugin</artifactId>
 6         <version>2.0.7</version>
 7         <executions>
 8           <execution>
 9             <phase>package</phase>
10             <goals>
11               <goal>proguard</goal>
12             </goals>
13           </execution>
14         </executions>
15         <configuration>
16           <attach>true</attach>
17           <attachArtifactClassifier>pg</attachArtifactClassifier>
18           <!-- attach 的作用是在 install 与 deploy 时将生成的 pg 文件也安装与部署 -->
19           <options> <!-- 详细配置方式参考 ProGuard 官方文档 -->
20             <!--<option>-dontobfuscate</option>-->
21             <option>-ignorewarnings</option> <!--忽略所有告警-->
22             <option>-dontshrink</option>   <!--不做 shrink -->
23             <option>-dontoptimize</option> <!--不做 optimize -->
24             <option>-dontskipnonpubliclibraryclasses</option>
25             <option>-dontskipnonpubliclibraryclassmembers</option>
26 
27             <option>-repackageclasses com.ucfgroup.framework.web.app.pg</option>
28             <!--平行包结构(重构包层次),所有混淆的类放在 pg 包下-->
29 
30             <!-- 以下为 Keep,哪些内容保持不变,因为有一些内容混淆后(a,b,c)导致反射或按类名字符串相关的操作失效 -->
31 
32             <option>-keep class **.package-info</option>
33             <!--保持包注解类-->
34 
35             <option>-keepattributes Signature</option>
36             <!--JAXB NEED,具体原因不明,不加会导致 JAXB 出异常,如果不使用 JAXB 根据需要修改-->
37             <!-- Jaxb requires generics to be available to perform xml parsing and without this option ProGuard was not retaining that information after obfuscation. That was causing the exception above. -->
38 
39             <option>-keepattributes SourceFile,LineNumberTable,*Annotation*</option>
40             <!--保持源码名与行号(异常时有明确的栈信息),注解(默认会过滤掉所有注解,会影响框架的注解)-->
41 
42             <option>-keep class SSRuntimeEasyJava.** { *;}</option>
43             <!--保持 Bean 类,(由于很多框架会对 Bean 中的内容做反射处理,请根据自己的业务调整) -->
44 
45           </options>
46           <outjar>${project.build.finalName}-pg</outjar>
47           <libs>
48             <lib>${java.home}/lib/rt.jar</lib>
49           </libs>
50 
51         </configuration>
52      </plugin>
53       </plugins>
54   </build>

 


 

       研究过程出现的问题:

          如果没有<injar></injar>会报如下错误信息:       

1 [ERROR] Failed to execute goal com.github.wvengen:proguard-maven-plugin:2.0.7:proguard (default) on project ucf-company: Obfuscation failed (result=1) -> [Help 1]
2 [ERROR] 
3 [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
4 [ERROR] Re-run Maven using the -X switch to enable full debug logging.
5 [ERROR] 
6 [ERROR] For more information about the errors and possible solutions, please read the following articles:
7 [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

 

      具体实现参照地址:

      http://www.cnblogs.com/yanduanduan/p/5340060.html

      http://blog.csdn.net/wltj920/article/details/48970869

  四、Maven打包时动态替换properties资源文件中的配置值:

 1 <profiles>
 2     <!-- 开发/测试环境,默认激活 -->
 3     <profile>
 4         <id>dev</id>
 5         <properties>
 6             <env>dev</env>
 7         </properties>
 8         <activation>
 9             <activeByDefault>true</activeByDefault>
10             <!--默认启用的是dev环境配置-->
11         </activation>
12     </profile>
13     <!-- 生产环境 -->
14     <profile>
15         <id>prod</id>
16         <properties>
17             <env>prod</env>
18         </properties>
19     </profile>
20     <!-- qa环境 -->
21     <profile>
22         <id>qa</id>
23         <properties>
24             <env>qa</env>
25         </properties>
26     </profile>
27 </profiles>
28 <build>
29     <filters>
30         <!-- 指定使用的 filter -->
31         <filter>src/main/resources/filter/${env}.properties</filter>
32     </filters>
33     <resources>
34         <resource>
35             <!-- 配置需要被替换的资源文件路径, db.properties 应该在 src/main/resource 目录下 -->
36             <directory>src/main/resources</directory>
37             <filtering>true</filtering>
38             <!-- 是否使用过滤器 -->
39         </resource>
40     </resources>
41 </build>

 九、Maven配置多模块项目

    用项目层次的划分替代包层次的划分能给我们带来如下好处:

    1. 方便重用,如果你有一个新的swing项目需要用到app-dao和app-service,添加对它们的依赖即可,你不再需要去依赖一个WAR。而有些模块,如app-util,完全可以渐渐进化成公司的一份基础工具类库,供所有项目使用。这是模块化最重要的一个目的。
    2. 由于你现在划分了模块,每个模块的配置都在各自的pom.xml里,

      以上是关于Maven进阶宝典的主要内容,如果未能解决你的问题,请参考以下文章

      学习宝典XSS攻击进阶篇——那些年我们看不懂的XSS

      阿里技术官纯手打架构师进阶宝典全网首发,一条龙理论+项目齐飞

      Java零基础到进阶宝典!从小白到大神,金九银十面试这届斩获23K月薪

      大数据面试葵花宝典之Kafka进阶

      年度重磅!《2022华为开发者宝典》多元生态技术精选,学练考一站式能力进阶

      年度重磅!《2022华为开发者宝典》多元生态技术精选,学练考一站式能力进阶