到目前為止(未來有很多不可預知的事),Java應該還是企業級應用開發的首選,基于Java開發的企業級應用軟件架構也是經歷了一代又一代,從最初的jsp+javabean+servlet,到后來流行的MVC架構SSH,再到目前的“百花齊放”——涌現出了太多的開發框架。
在這個已經到來的“云時代”,如何讓我們開發的軟件具備很好的“云感知”能力呢? 不管你選擇什么樣的框架,什么樣的技術,從我這幾年的工作經驗來看,大部分還是要通過軟件架構層面的調整,才能讓我們的軟件更有生命力。
關于企業級應用開發,我將會介紹一些工具、一些架構層面的東西,希望能有助于讓各位程序員能開發出能跑在云環境下的應用。今天給大家首先帶來的是Maven。
maven
有將項目打好war包部置到生產環境后報各種錯誤的經歷嗎?
有到處找jar包的經歷嗎?
有各種jar包沖突導致的各種錯誤的經歷嗎?
也許你們都沒有,但我真的遇到很多,幾乎每一個項目都會遇到,直到遇到了Maven,這些大部分問題都得到了解決。
應用商店
2008年7月11日,蘋果APP Store正式上線,開創了軟件銷售的全新模式,App Store模式的意義在于為第三方軟件的提供者提供了一個統一的軟件銷售平臺。這真的是蘋果的創新成果嗎?從商業角度出發,我們必須承認,但從技術上來說,Linux社區在很久很久以前,就使用了“軟件倉庫”來集中管理軟件包,同時也通過軟件層面解決了軟件包之間的依賴問題。如ubuntu上的apt-get, CentOS上的yum都是非常好的軟件包管理工具,它們的前提就是有一個集中存放軟件的中央倉庫。
這幾年隨著軟件技術有發展,大部分開發語言都吸取了Linux的軟件倉庫精華,都有自己的模塊(或軟件)依賴管理工具,如ruby的gem,python的pip,nodejs的npm等。
Maven也解決了Java開發中最讓人鬧心的jar包管理問題,讓開發人員不用再到處找jar包,然后復制到lib目錄,添加到classpath……,當然Maven能做的事遠遠不止這些。
Maven是一個項目管理工具,它包含了一個項目對象模型 (Project Object Model),一組標準集合,一個項目生命周期(Project Lifecycle),一個依賴管理系統(Dependency Management System),和用來運行定義在生命周期階段(phase)中插件(plugin)目標(goal)的邏輯。當你使用Maven的時候,你用一個明確定義的項目對象模型來描述你的項目,然后Maven可以應用橫切的邏輯,這些邏輯來自一組共享的(或者自定義的)插件。
火速入門
從一開始我對本書的定義就不是一本純技術的書,所以本節只會簡單介紹Maven的使用,如果想更深入的了解Maven,請參考和Maven相關的專業書籍或google。
師傅領進門,修行在個人
jar包管理基本原理
如下圖所示,Maven通過統一的存儲庫來保存jar包、插件等。
+---------------------+
| |
| Remote Repository |
| |
+----------^----------+
|
|
+----------------------------------------------+
| | your compute |
| | +------------+ |
| | | | |
| | +--+ Project1 | |
| +--------+---------+ | | | |
| | <--+ +------------+ |
| | Local Repository | |
| | <--+ +------------+ |
| +------------------+ | | | |
| +--+ Project2 | |
| | | |
| +------------+ |
| |
+----------------------------------------------+
同一個項目可以同時使用多個遠程存儲庫(Remote Repository),Maven在本地會有自己的一個存儲庫(Local Repository),在構建項目時,Maven會將遠程存儲庫中項目所依賴的jar包、插件等下載到本地存儲庫緩存,本地的項目共享同一個存儲庫,如果Project1中使用到了junit4.0版本的jar包,在Porject2中也用到時,Maven就不會再從遠程存儲庫中下載。
在Project1和Project2中將不在存儲jar包,只在項目描述文件中聲明項目對jar包的依賴關系。以前在管理項目源代碼的時候,往往也會將這些jar包一起放到版本控制工具,而現在結合公司的Repository,這些jar包就不再需要加入到版本控制工具(如SVN)中了,這大大減少了項目文件所占用的空間(這樣說或許有些牽強)。
安裝與配置
以Ubuntu為例,執行如下命令即完成Maven的安裝:
sudo apt-get install maven
Maven配置文件默認在~/.m2/settings.xml,在配置文件中可以配置代理服務器、用戶認證信息、遠程倉庫地址、插件倉庫地址等。
詳細的配置項和說明可見:http://maven.apache.org/settings.html
如果找不到這個文件,可以從Maven安裝目錄下conf/settings.xml文件拷貝到~/.m2/目錄。
Maven的使用
在正式開始之前,先來介紹一個概念:Archetype
每個公司經過長期的技術積累,雖然是不同的項目,但項目的代碼基本結構、代碼的打包方式基本是相同的。
Archetype是一個Maven項目模板管理工具,我們可以把前面說的項目一些共性的東西做成一個模板,在新項目開始的時候,只可使用Archetype直接初始化項目開發環境。在本文中我們就把Archetype理解為項目模板,在寫本節時,在Maven公共倉庫(http://search.maven.org/)中的Archetype已達1098個,對于常見的項目,我們可以直接基于這個Archetype創建初始環境即可。
下面我們開始新建一個項目,我們基于Maven公共倉庫中的Archetype:spring-mvc-archetype為基于開始我們的項目。
執行如下命令:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeGroupId=co.ntier -DarchetypeArtifactId=spring-mvc-archetype -DinteractiveMode=false
相關參數說明:
- DgroupID : Java包名
- DartifactID : 項目名稱(會做為生成項目目錄)
- DarchetypeGroupId: 模板所屬組織ID,默認值為:org.apache.maven.archetypes(這里很容易出錯哦,一定要指定模板的組織ID,要不然會報找不到模板。
- DarchetypeArtifactId:模板名稱
- DinteractiveMode : 是否與maven交互,如果為true,會提示輸入包名、版本號等信息,false時,都使用默認值
執行完命令后,會生成如下目錄結構:
└── my-app
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── mycompany
│ └── app
│ ├── config
│ │ └── MvcConfiguration.java
│ └── controller
│ └── HomeController.java
└── webapp
├── WEB-INF
│ ├── views
│ │ └── home.jsp
│ └── web.xml
└── resources
└── style.css
這是一個spring mvc 的 hello world 程序,我們可以看到,這里并沒有看到我們所需要的相關spring的jar包,我們來看看maven核心配置文件pom.xml
<?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>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>my-app</name>
<url>http://maven.apache.org</url>
<properties>
<java.version>1.6</java.version>
<spring.version>3.1.0.RELEASE</spring.version>
<cglib.version>2.2.2</cglib.version>
</properties>
<dependencies>
<!-- Spring core & mvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>test</scope>
</dependency>
<!-- CGLib for @Configuration -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>${cglib.version}</version>
<scope>runtime</scope>
</dependency>
<!-- Servlet Spec -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>springsource-milestones</id>
<name>SpringSource Milestones Proxy</name>
<url>https://oss.sonatype.org/content/repositories/springsource-milestones</url>
</repository>
</repositories>
<build>
<finalName>my-app</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置文件大家一看就知道是干什么了,一開始的version、packaging等屬性是定義這個項目的版本號、打包方式等,接下來的properties定義了一堆常量,后面的dependencies就是聲明項目所依賴的一些包,最后的build是聲明打包編譯時需要的一些插件。
接下來,進入my-app目錄,執行如下命令:
cd my-app
mvn package
您將看到maven會到maven遠程倉庫將pom.xml中聲明的依賴包下載到本地,然后執行打包。
命令執行完后,您將看到在target目錄下生成了my-app.war的包,拿著這個包就可以去部署到各種java中間件上了。是不是很方便。
前面介紹過,maven并不是單純的jar包依賴管理工具,Maven是一個項目管理工具,它包含了一個項目對象模型 (Project Object Model),因此,除了管理jar包依賴,它還包括項目管理過程中常用的很多工具。
我們可以在根目錄下建立test目錄,將java測試用例放到下面,然后在命令行執行mvn test
,就能看到測試結果,看測試有沒有發生錯誤等。
對于開發人員,經常使用tomcat來開發的話,整個過程是很簡單的。在剛才的my-app項目根目錄執行:mvn tomcat:run
,然后打開瀏覽器:http://localhost:8080/my-app ,您就將看到運行結果。沒想到吧,都不用安裝tomcat,全部通過maven就能搞定。
如果您是在開發一個純java模塊,那就執行:mvn install
就可以把jar包發布到本地Repository,然后就可以在別的項目里引用這個jar包了,借助一些插件就可以把它發布到公司的統一Repository庫中。
Maven還有很多很多的功能,本書maven就介紹到這里,詳細的關于Maven的知識可以參考一些專業的書籍或官方文檔。最后推薦您將下面的項目clone到本地來深入學習:
https://github.com/spring-projects/spring-mvc-showcase
git clone git://github.com/SpringSource/spring-mvc-showcase.git
國際范程序必讀:
程序員的編輯器-VIM(愛就是愛)
向開源社區貢獻您的代碼
在github上寫博客
DevOps是什么東東?
js依賴管理工具bower
JS模塊化編程-requirejs