由于当前公司在组织进行项目基本结构的整理,将以前通过eclipse/ ant 方式构建的项目向maven上迁移,于是便进行maven项目方面的调研。

对于maven项目,基本的结构已经在标准文件中:

 
 
以及其翻译成中文的相关文档:
 
 
使用一套通用的目录结构的好处是,可以减少开发人员熟悉不同Maven项目时的认知负担。在使用相同的目录结构的情况下,开发人员可以很快的熟悉一个项目。接下来,我们将开始介绍Maven的通用的目录结构。
 

<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->

Maven默认约定了一套目录结构,在通过Maven创建了项目以后,项目的目录结构就是以这套目录结构作为模板创建的。
 
文档中关于所有目录结构的含义如下:
 
src/main/java Application/Library sources
src/main/resources Application/Library resources
src/main/filters Resource filter files
src/main/webapp Web application sources
src/test/java Test sources
src/test/resources Test resources
src/test/filters Test resource filter files
src/it Integration Tests (primarily for plugins)
src/assembly Assembly descriptors
src/site Site
LICENSE.txt Project's license
NOTICE.txt Notices and attributions required by libraries that the project depends on
README.txt Project's readme
 
 
<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->

在一个Maven项目中,在项目根目录下,除了包含了上面约定的目录结构中的部分目录外,还包含了项目描述文件,pom.xml文件。
 
在根目录下,主要有两个目录,分别是src和target目录,除此之外,还会有一些版本控制系统的元数据文件,包括git的.gitignore或者svn的.svn。如果一个项目时由多个子项目组成的,那么在该项目的根目录下,还会包含它的子项目的目录。子项目的目录布局,默认也是和上面列出的目录结构一致的。
 
在src目录下,包含了项目所有的源代码和资源文件,以及其他项目相关的文件。在该目录的main目录下,包含了构建该项目的artifact(可以理解为时项目的程序部分)所需的代码和资源,而test目录包含了测试相关的代码和资源文件。
 
在目录main和test下的子目录结构,是非常相似的,都包含了两个子目录:java子目录和resources子目录,这两个目录分别放了源代码和资源文件。不同的是,在main目录下的这两个目录中放置了项目主程序的代码,而在test目录下,放置的是测试相关的代码和资源文件。其中java目录是代码的根目录,在该目录下的子目录,就是Java的包名对应的目录结构了。
 
讨论:是否有必要在同一个项目下声明多个source folder(源代码目录)?还是以包名来区分?
 
 
maven需要设置groupId和artifactId,其命名规则需要一起根据公司的策略制定一下。
 
由于当前我们使用git作为版本控制工具,因此.gitignore文件必不可少,基于java项目的文件,考虑到使用eclipse和idea IDE工具都有对应的开发人员:
 
由于我们使用git作为版本管理工具,在使用maven作为build工具时,需要将IDE的工程描述文件以及项目生成的target/,bin/目录忽略掉,因此.gitignore文件必不可少,以下内容可以作为项目的.gitignore文件范本:

# generated files where run in local machine
bin/
target/ # eclipse project description files
.settings/
.project # idea project description files
.idea/
*.iml ### Java template
*.class # Mobile Tools for Java (J2ME)
.mtj.tmp/ # Package Files #
*.jar
*.war
*.ear # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
 
最终整理的web项目结构如下(用idea作为实例),由于使用SpringMVC,业务上增加了一些java package:
 


 
 
 
 
其他的目录都比较容易理解,下面介绍一下src/main/filter目录的作用:
  
构建项目的过程中,可能会对开发,测试,线上等不同的环境有着不同的设置,或资源,比较常见的是数据库jdbc.properties配置,下面就以这个为具体例子简单介绍一下,参考了下面两篇blog(已经讲得非常详细了)。
  
 
不同的软件开发生命周期阶段、不同的最终客户(用户)环境、不同的运行平台都有可能需要不同配置或资源的情况。假如各个环境下的差别很小的话,我们可以在项目编译之后手工修改或者写个 shell script 自动修改,但如果需要修改的项目很多而且复杂的话,则应该使用 Apache Maven 的 Profile 和 Filtering 功能来解决
 
 
Profile 的作用是允许你在项目文件(pom.xml)里定义若干个 profile 段,然后在编译时选择其中的一个用于覆盖项目文件原先的定义,我们可以在pom文件中定义多个profile,分别表示开发(dev), 测试(test),以及线上(product)用来区分不同的执行环境。
 
<profiles>
<profile>
<id>dev</id>
<properties>
<active.profile>dev</active.profile>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile> <profile>
<id>test</id>
<properties>
<active.profile>test</active.profile>
</properties>
</profile> <profile>
<id>product</id>
<properties>
<active.profile>product</active.profile>
</properties>
</profile>
</profiles>
上述设置中表示profile dev为默认的profile,在idea编辑器中,执行maven编译时,选择对应的profile;profile不仅可以在项目中配置,还可以全局配置(下面的sonar就是在全局setting.xml中配置的)。
 


 
 
在pom.xml中声明build标签,用来加入filter文件,${active.profile}就表示当前使用的profile,在profile文件中被定义:
 
<build>
<finalName>example</finalName>
<filters>
<filter>src/main/filters/filters-${active.profile}.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
在src/main/filters目录下存在三个文件:
  • filters-dev.properties
  • filters-test.properties
  • filters-product.properties
 
注意,名称需要与profile的名称保持一致,以满足 filter-${active.profile}文件的通配符。
 
在src/main/resources目录下的全局配置文件 jdbc.properties不指定具体的路径,使用变量来定义:
 
dbc.url=${pom.jdbc.url}
jdbc.username=${pom.jdbc.username}
jdbc.passworkd=${pom.jdbc.password}
 
在filters-dev.properties文件就需要如此定义:
 
pom.jdbc.url=dev
pom.jdbc.username=dev
pom.jdbc.password=dev
这样在执行maven 构建命令时,默认使用dev profile(默认设置为true),或者通过-P product来产生生产环境下的war包。
 
<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->

可以定义多个profile来支持 开发环境/测试环境/生产环境 之间的文件属性替换操作。
 
不同的软件开发生命周期阶段、不同的最终客户(用户)环境、不同的运行平台都有可能需要不同配置或资源的情况。假如各个环境下的差别很小的话,我们可以在项目编译之后手工修改或者写个 shell script 自动修改,但如果需要修改的项目很多而且复杂的话,则应该使用 Apache Maven 的 Profile 和 Filtering 功能来解决
 
 
Profile 的作用是允许你在项目文件(pom.xml)里定义若干个 profile 段,然后在编译时选择其中的一个用于覆盖项目文件原先的定义。
 
或者另外一种方案,这是原来我们工程中大量被使用的方案,在build war包的时候,选择将一些文件排除:
 
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src/main/resource</directory>
<excludes>
<exclude>**/*.java</exclude>
<exclude>conf/**</exclude>
</excludes>
</resource>
<resource>
<directory>package/${package.environment}</directory>
<filtering>true</filtering>
</resource>
</resources>
 
这里就会将resources/conf/目录下的文件排除掉,但是此时需要使用其他文件进行顶替,这里就包含了package/${package.environment}目录下的配置文件。
 
配置文件中的package.environment变量是在profile中定义的,每个profile都有着不同的设置,例如dev、test环境就会有所不同。
 
<profiles>
<profile>
<id>dev</id>
<properties>
<package.environment>dev</package.environment>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<package.environment>test</package.environment>
</properties>
</profile>
</profiles>
 
项目目录中都需要有一份完整的配置文件。
 


 
 
如果使用这种方式的话,其实是不知道每个环境的具体配置差异的,只是通过低级的配置文件复制来进行处理(类似于拷贝代码),不利于我们将可变变量统一区分并管理起来,每次更新spring/mybatis配置都需要修改多处的配置文件(执行复制)。
 
但这种方式其实有个好处,就是我们在本地IDE执行时,可以不通过maven调用来进行(如果是Profile+Filter替换的话需要用maven来启动jetty/tomcat)。
 
<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->

常用的maven jar包搜索工具: http://mvnrepository.com,如果不知道所在的jar包,也可以使用google进行站内搜索:
 
site:mvnrepository.com xxx.JavaClass,也可以将该搜索源作为maven仓库加入进去:
 
<repository>
<id>mvnrepository</id>
<name>mvnrepository</name>
<url>http://www.mvnrepository.com</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
 

<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->

关于SnapShots和Release之间的区别,可以参考:http://yongpoliu.com/snapshot-vs-release/
 
对于release版本,我们不能强制将其刷新,maven -U参数可以控制强制刷新snapshots,但是不可以刷新releases,下面是-U参数的说明:
 
-U,--update-snapshots                  Forces a check for missing
releases and updated snapshots on
remote repositories
 
由于我们build的release会自动安装(install)到服务器的.m2目录,所以在该服务器上build其他的jar包会成功(假设jenkins是分布式而非单机,这样操作就会失败了)。
 
以前我们设置的release服务器不允许Re-deploy,重复提交RELEASE版本会导致失败,这也是控制RELEASE意外被修改的一种办法。
 
 
 
 
 
 
 

使用maven构建基本的web项目结构的更多相关文章

  1. 图文详解 IntelliJ IDEA 15 创建 Maven 构建的 Java Web 项目(使用 Jetty 容器)

    图文详解 IntelliJ IDEA 15 创建 maven 的 Web 项目 搭建 maven 项目结构 1.使用 IntelliJ IDEA 15 新建一个项目.  2.设置 GAV 坐标  3. ...

  2. 图文具体解释 IntelliJ IDEA 15 创建 Maven 构建的 Java Web 项目(使用 Jetty 容器)

    图文具体解释 IntelliJ IDEA 15 创建 maven 的 Web 项目 搭建 maven 项目结构 1.使用 IntelliJ IDEA 15 新建一个项目. 2.设置 GAV 坐标 3. ...

  3. maven构建简单的web项目

    把jdk给换掉 项目修改好了以后写个页面测试一下,结果正常 下面应该添加依赖让web项目一步步丰满起来. 0-添加依赖 1-建一个servlet 2-web.xml中添加servlet声明 3-重新运 ...

  4. 使用maven构建第一个web项目

    在eclipse中,正常创建maven项目后,发现在index.jsp中会报错,此时在pom.xml中加入如下依赖关系即可 <dependency> <groupId>java ...

  5. Eclipse中使用Maven创建Servlet3.0 Web 项目

    摘要 Apache Maven是一个优秀的项目构建和管理工具,许多开源项目都使用Maven进行构建.由于最近工作中要用到Maven,于是这里记录下在Eclipse中使用Maven插件创建一个基于Ser ...

  6. Maven实现项目构建直接部署Web项目到Tomcat

    Maven实现项目构建直接部署Web项目到Tomcat配置如下: 1.Tomcat的用户及权限配置:在conf目录下,找到tomcat-users.xml,添加manager权限的用户. <ro ...

  7. 使用Maven构建RichFaces 4.x项目

    使用Maven构建RichFaces 4.x项目 目录 开始之前 第一步 - 创建Maven项目 第二布 - 添加依赖文件 第三步 - 配置RichFaces 第四步 - 创建显示页面 开始之前 本文 ...

  8. Maven构建真正的J2EE项目

    今天同事问起我眼下用Maven构建的多模块项目架构和曾经用Eclipse创建的Web项目的问题.以下将讲一下使用maven搭建多模块的J2ee项目,以及採用这样的方式搭建项目对日后项目的水平拆分和垂直 ...

  9. 使用Apache Tomcat Maven插件部署运行 Web 项目

    什么是Apache Tomcat Maven Plugin? Maven Plugin 是Apache Tomcat 提供的一个Maven插件,它可以在你没有tomcat容器时将任何一个war项目文件 ...

随机推荐

  1. UVa 10294 项链和手镯(polya)

    https://vjudge.net/problem/UVA-10294 题意: 手镯可以翻转,但项链不可以.输入n和t,输出用t种颜色的n颗珠子能制作成的项链和手镯的个数. 思路: 经典等价类计数问 ...

  2. CentOS6.4x86EngCustomize120g__20160307.rar

    安装的镜像包: CentOS-6.4-i386-bin-DVD1to2(CentOS-6.4-i386-bin-DVD1.iso / CentOS-6.4-i386-bin-DVD2.iso) 1. ...

  3. githubpage+hexo构建自己的个人博客

    就这有这么一天,我感觉博客园的博客页面实在太low了.完全跟不上现在潮流. https://segmentfault.com/a/1190000004947261 http://coolcao.com ...

  4. 最小生成树prim和kruskal模板

    prim: int cost[MAX_V][MAX_V]; //cost[u][v]表示边e=(u,v)的权值(不存在的情况下设为INF) int mincost[MAX_V]; //从集合X出发的每 ...

  5. python3 中文乱码,UnicodeEncodeError: 'latin-1' codec can't encode characters in position 10-13: ordinal not in range(256)

    将其源代码复制下来运行之后,报了下面这个错误: UnicodeEncodeError: 'latin-1' codec can't encode characters in position 9-13 ...

  6. Alpha阶段第1周 Scrum立会报告+燃尽图 02

    作业要求与https://edu.cnblogs.com/campus/nenu/2018fall/homework/2246相同 一.小组介绍 组长:刘莹莹 组员:朱珅莹 孙韦男 祝玮琦 王玉潘 周 ...

  7. PCB 中过孔和通孔焊盘的区别

    在PCB设计中,过孔VIA和焊盘PAD都可以实现相似的功能.它们都能插入元件管脚,特别是对于直插DIP)封装的的器件来说,几乎是一样的. 但是!在PCB制造中,它们的处理方法是不一样的. 1.VIA的 ...

  8. Cause: org.postgresql.util.PSQLException: ERROR: cached plan must not change result type的前因后果

    首先说明一下遇到的问题: PG数据库,对其中的某张表增加一列后,应用报错,信息如下: 应用使用相关框架如下:SpringBoot.MyBatis. ### Cause: org.postgresql. ...

  9. 接口测试Fiddler实战20150921

    (写好的文章被不小心删掉了,现在补一篇) 项目背景: 1.接口URL:http://192.168.xx.xx:8080/mserver/rest/ms 2.接口参数:data=xxxxx&k ...

  10. Linux运维学习笔记-网络安全等级保护

    网络安全等级保护简介与作用: 验证信息系统是否满足相应安全保护等级的一个过程. 对不同信息系统分等级进行保护.