1. 程式人生 > >**Maven高階 筆記二[共兩篇,史上最全重點]*

**Maven高階 筆記二[共兩篇,史上最全重點]*

Maven高階應用

1. maven基礎回顧
2. maven傳統的web工程做一個數據查詢操作
3. maven工程拆分與聚合的思想		//要理解其意義所在,重點
4. 把第二階段做好的web工程修改成maven拆分與聚合的形式。
5. 私服【遠端倉庫】
6. 如何安裝第三方jar包。【把第三方jar包安裝到本地倉庫,把第三方jar包安裝到私服】

maven基礎知識回顧

1. maven是一個專案管理工具
2. 核心功能:
	1. 依賴管理:
		* maven對專案jar包的管理過程。傳統工程我們直接把jar包放置在專案中。
		* maven工程真正的jar包放置在倉庫中,專案中只用放置jar包的座標
	2. 一鍵構建:
		* maven自身集成了tomcat外掛,可以對專案進行編譯,測試,打包,安裝,釋出等操作。
		* maven常用命令:clean ,complie(編譯),test,package,install(把包安裝到本地倉庫),deploy(把做好的專案直接打包上傳到私服)。
		* maven三套生命週期:
			1. 清理生命週期:clean
			2. 預設生命週期:complie~install
			3. 站點生命週期
3. 倉庫的種類:
	1. 本地倉庫
	2. 遠端倉庫【私服】:公司區域網內的倉庫
	3. 中央倉庫【本地的環境只要可以聯網就直接連上了中央倉庫】
	4. 關係: 
		* 當我們啟動了一個maven工程的時候,maven工程會通過pom檔案中jar包的座標去本地倉庫找對應jar包。
		* 預設情況下,如果本地倉庫沒有對應jar包,maven工程會自動去中央倉庫下載jar包到本地倉庫。
		* 在公司彙總,如果本地沒有對應jar包,會先從私服下載jar包。
		* 如果私服沒有jar包,可以從中央倉庫下載,也可以從本地上傳到私服。

案例準備

1. 環境準備
	1. 建立資料庫,執行建表語句和插入表語句	[可以直接複製語句,也可以直接執行資料庫指令碼-maven高階-資料-items.sql]
	2. 建立maven工程,補齊目錄名字和對應屬性;java,resources,webapp,test
	3. 找到web配置頭宣告,開啟web.xml加入到<web-app>標籤內
	4. pom.xml中匯入座標 [spring-context]			/匯入了核心包,它會附帶其他依賴包;
		* 匯入時需要注意的地方:
			1. maven工程咬匯入jar包的座標,就必須要解決jar衝突;
			-- 解決jar包衝突的方式一:
				1. 宣告優先原則:哪個jar包的座標在靠上的位置,這個jar包就是先宣告的,先宣告的jar包座標下的依賴包,可以優先進入專案中。
					* maven匯入jar包中的一些概念:
						1. 直接依賴:專案中直接匯入的jar包,就是該專案的直接依賴包
						2. 傳遞依賴:專案中沒有直接匯入的jar包,可以通過專案直接依賴jar包傳遞到專案中。
			-- 解決jar包衝突的方式二:
				2. 路徑近者優先原則。直接依賴路徑比傳遞依賴路徑近,那麼最終專案進入的jar包會是路徑近的直接依賴包
			-- 解決jar包衝突的方式三:
				3. 直接排除法。當我們要排除某個jar包下的依賴包,在配置exclusions標籤的時候,內部可以不寫版本號,因此此時依賴包使用的版本和預設版本一樣。
					* <exclusions>
					* <exclusion>
					* <groupId>org.springframework</groupId>
					* <artifactId>spring-core</artifactId>
					* </exclusion>
					* <exclusions>
			-- 如果高版本和低版本的包同時存在,有可能低版本的包會將高版本的包覆蓋掉,可能會出問題。[有些功能無法實現]
		2. <dependencyManagenment>鎖定jar包版本。  鎖定版本的時候,需要重新複製一份,不能剪下。
			1. maven工程是可以分父子依賴關係的。凡是依賴別的專案後,拿到的別的專案的依賴包,都屬於傳遞依賴。
				* 比如:當前A專案,被B專案依賴。那麼我們A專案總所有jar包都會傳遞到B專案中。
			2. B專案開發者,如果再再B專案總匯入一套ssm框架的jar包,對於B專案是直接依賴。那麼直接依賴的jar包就會把我們A專案傳遞過去的jar包覆蓋掉。為了防止以上情況的出現。我們可以把A專案中主要jar包的座標鎖住,那麼其他依賴該專案的專案中,即便是有同名jar包直接依賴,也無法覆蓋。 
		3. 統一管理jar包版本,方便以後維護,以後修改版本的時候,只需要修改統一管理的地方,不需要每一處做修改。

dao層編寫:

1. 建立java.com.itheima.domain.Items類
	* public class Items{
	* private Integer id;
	* private String name;
	* private Double price;
	* privaete String pic;
	* private Date createtime;
	* private String detail;
	* get,set方法
	* 
	* }

2. 建立java.com.itheima.dao.ItemsDao介面
	* public interface ItemsDao{
	* public Items findById(Integer id);
	* }

3. resources.com/itheima/dao.ItemsDao.xml
	* 匯入約束頭部
	* <mapper namespace="com.itheima.dao.ItemsDao">
	* <select id="findById" parameterType="int" resultType="items">
	* select * from items where id=#{id}
	* </select>
	* </mapper>

4. resources根目錄下建立applicationContext.xml		//dao層配置檔案
	* 匯入約束
	* <!--dao層配置檔案開始-->
	* 
	* <!-- 配置連線池-->
	* <bean id="dateSource" class="com.alibaba.druid.pool.DruidDateSource">
	* <property name="driverClassName" value="com.alibaba.druid.pool.DruidDateSource"/>
	* <property name="url" value="jdbc:mysql:///maven"/>
	* <property name="username" value="root"/>
	* <property name="password" value="root"/>
	* </bean>
	* <!--配置生產SqlSession物件的工廠-->
	* <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
	* <property name="dateSource" ref="dataSource"/>
	* <!--掃描pojo包,給包下所有pojo物件起別名-->
	* <property name="typeAliasesPackage" value="com.itheima.domain"/>
	* </bean>
	* <!--掃描介面包路徑,生成包下所有介面的代理物件,並且放入spring容器中-->
	* <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
	* <property name="basePackage" value="com.itheima.dao"/>
	* <!--dao層配置檔案結束-->
5. 測試dao,建立test.java.com.itheima.test.ItemsTest:
	* public class ItemsTest{
	* @Test
	* public void findById(){
	* //獲取spring容器
	* ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
	* //從容器中拿到所需的dao的代理物件
	* ItemsDao itemsDao=ac.getBean(ithemsDao.class);
	* //呼叫方法
	* Items items=itemsDao.findById();
	* System.out.println(items.getName());
	* }
	* }

service 層編寫

* 遵從原則:
		* 自己寫的類儘量使用註解
		* 框架的類儘量使用配置檔案
1. 建立main.java.com.itheima.service.ItemsService介面
	* public interface ItemsService{
	* public Items findById(Integer id);
	* }
2. 建立main.java.com.itheima.service.impl.ItemsServiceImpl實現類
	* public Items findById(Integer id){
	* @Autowired
	* private ItemsDao itemsDao;
	* public Items findById(Integer id){
	* return itemsDao.findById(id);
	* }  
	* }

3. 開啟applicationContext.xml
	* <!-- dao層配置檔案結束-->
	* <!--service配置檔案開始-->
	* <!--元件掃描配置-->
	* <context:component-scan base-package="com.itheima.service"/>
	* <!--aop面向切面程式設計,切面就是切入點和通知的組合-->
	* <!--配置事務管理器-->
	* <bean id="transactionManager" class="org.springframework.jdbc.datesource.DataSourceTransactionManager">
	* <property name="dateSource" ref="dateSource"/>
	* </bean>
	* <!--配置事務的通知-->
	* <tx:advice id="advice">
	* <tx:attributes>
	* <tx:method name="save*" propagation="REQUIRED"/>
	* <tx:method name="update*" propagation="REQUIRED"/>
	* <tx:method name="delete*" propagation="REQUIRED"/>
	* <tx:method name="find*" propagation="true"/>
	* //<tx:method name="*" propagation="REQUIRED"/>
	* </tx:attributes>
	* </tx:advice>
	* <!--配置切面-->
	* <aop:config>
	* <aop:pointcut id="pointcut" expression="execution(* com.itheima.service.impl.*.*(..))"/>
	* <aop:advisor advice-ref="advice" pointcut-ref="pointcut"/>
	* <aop:config>
	* <!--service配置檔案結束-->

4. 測試:test.itemsTest:
	* 註釋掉前面dao層的測試
	* public class ItemsTest{
	* //獲取容器
	* ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
	* ItemsService itemsService =ac.getBean(ItemsService.class);
	* //呼叫方法
	* Items items=itemsService.findById(1);
	* System.out.println(items.getName());
	* }

WEB層編寫

1. 建立main.java.com.itheima.controller.ItemsController類:
	* @Controller
	* @RequestMapping("items")
	* public class ItemsController{
	* @Autowired
	* private ItemsService itemsService;
	* @RequestMapping("/findDetail")
	* public String findDetail(Model model)
	* Items items=itemsService.findById(1);
	* model.addAttribute("",items);
	* return "";
	* }
	* }
	* //等會補上

2.resources 建立springmvc.xml
	1. 匯入約束
	2. 開始:
		* <!--元件掃描-->
		* <context:component-scan base-package="com.itheima.controller"/>
		* <!--處理器對映器,處理器介面卡-->
		* <mvc:annotation-driven/>
		* <!--檢視解析器-->
		* <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		* <property name="prefix" value="/WEB-INF/pages/"/>
		* <property name="suffix" value=".jsp"/>
		* </bean>
		* 
		* <!--釋放靜態資源-->
		* <mvc:default-servlet-handler/>
		* </beans>

3.建立webapp.WEB-INF.pages.itemDatail.jsp;
	* 頁面接收資料
	* 請自行編寫

4. web.xml中配置
	* <!--編碼過濾器-->
	* <filter>
	* <filter-name>encoding</filter-name>
	* <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	* <init-param>
	* <param-name>encoding</param-name>
	* <param-value>UTF-8</param-value>
	* </init-param>
	* </filter>
	* <filter-mapping>
	* <filter-name>encoding</filter-name>
	* <url-pattern>/*</url-pattern>
	* </filter-mapping>
	* 
	* <!--配置spring核心監聽器-->
	* <listener>
	* <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	* <!--重新指定spring配置檔案的路徑-->
	* <context-param>
	* <param-name>contextConfigLocation</param-name>
	* <param-value>classpath:applicationContext.xml</param-value>
	* </context-param>
	* <!--springmvc的核心servlet-->
	* <servlet>
	* <servlet-name>springmvc</servlet-name>
	* <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	* <init-param>
	* <param-name>contextConfigLocation</param-name>
	* <param-value>classpath:springmvc.xml</param-value>
	* </init-param>
	* <load-on-startup>1</load-on-startup>
	* </servlet>
	* <servlet-mapping>
	* <servelt-name>springmvc</servlet-name>
	* <url-pattern>/</url-pattern>
	* <servlet-mapping>
	* </web-app>

工程的拆分與聚合思想

1. 通過上面的案例可以看出:普通專案分三層:dao,service,controller	
	* 買家:買家要看到訂單,必須要把資料庫中訂單查詢出來。dao層的任務	系統:買家版
	* 賣家:賣家要看到訂單,必須要把資料庫中訂單查詢出來。dao層的任務	系統:賣家版
2. 思想演變:
	* 如果是一個傳統的ssm框架整合的專案,我們要在每個專案中都放置一套ssm框架的jar包;
	* 如果是maven的ssm工程,有十個專案我們也只需要一套jar包。真正專案中只放置jar的座標即可。
	* jar包內的是程式碼,我們寫的每個層,每個專案也是程式碼,所謂的jar包和我們寫的程式碼其實是一樣的。
	* 一份程式碼可重用和一份程式碼複製貼上到不同地方的區別:如果修改維護的話,可重用的只需要修改一份,而複製貼上幾個地方,就要維護幾個地方。
3. maven解決程式碼可重用和便於維護問題上是這樣解決的:[拆分與聚合]
	* maven把一個完整的專案,分成不同的獨立模組,這些模組都有各自獨立的座標,哪個地方需要其中某個模組,就直接引用該模組的座標即可。		
	* 今後如果公司開發一個新專案,我們先考慮的問題不是dao,service,utils,domain如何編寫,我們要考慮的是:dao,service,utils,domain這些模組是否已經存在,如果存在直接引用。
	* 以上說的就是maven拆分的思想;
	* 我們可以把拆分零散的模組聚合到一起編寫一個完整的專案,這就是maven聚合思想。

4. maven父子工程的建立
	1. 父工程可以工程也可以模組,只需要一個pom.xml
		1. 建立mvaen_day02_parent的project工程
		2. 刪除掉其他東西,留著.idea,maven_day02_parent.iml,pom.xml
	2. 在該工程下建立新的專案,AId:maven_day02_dao檔案,AId:maven_day02_service檔案,Aid:maven_day02_web檔案。
		* 在父工程的pom.xml檔案下出現了三個新的標籤:
			* <modules>
			* <module>maven_day02_dao</module>
			* <module>maven_day02_service</module>
			* <module>maven_day02_web</module>
			* </modules>

工程和模組的關係以及繼承依賴的概念:

1. 工程和模組的區別:
	* 工程不等於完整的專案,模組也不等於完整的專案,一個完整的專案看的是程式碼,程式碼完整,就可以說這是一個完整的專案,和此專案是工程和模組沒有關係;
	* 工程只能使用自己內部資源,工程天生是獨立的。後天可以和其他工程或模組建立關聯關係。
	* 模組天生不是獨立的,模組天生是屬於父工程的。模組一旦建立,所有父工程的資源都可以使用。
	* 父子工程之間,子模組天生整合父工程,可以使用父工程所有資源
	* 子模組天生是沒有關係的。
2. 使用,將工程內的模組專案放到本地倉庫中,在pom.xml中匯入座標,即可使用;
	* 父子工程之間不用建立關係,繼承關係是先天的,不需要手動建立。
	* 平級直接的引用叫依賴。		[依賴不是先天的,依賴是需要後天建立的]

父子工程的示例:

1. 在父工程中pom.xml匯入子模組的座標;
2. 對照直接依賴傳遞依賴的圖可以看出:
	1. dao和parent是直接依賴,作用域是compile
	2. dao和junit是傳遞依賴,作用域是test	[junit是在父工程中匯入的junit,它的scope範圍是test]
	3. 通過以上兩個對照表可以知道:junit傳遞到dao中已經不能使用了。
	-- 總結:實際開發中,如果傳遞依賴丟失,表現形式就是jar包的座標導不進去,我們的做法就是直接再匯入一次。
3. 示例:
	1. 建立maven_day02_parent父工程,保留.idea,maven_day02_parent.iml,pom.xml
	2. 建立maven_day02_dao模組,補全相應的內容。
		1. 建立src.main.java.itheima.domain,補全items實體類
		2. 建立src.main.java.itheima.dao,補全itemsDao介面
		3. 建立resource.com.itheima.dao,補全ithemsDao.xml
		4. resources下建立spring.applicationContext-dao.xml,補全該配置檔案 [只加入dao的部分]
	3. 建立maven_day02_service
		1. 在該模組下pom.xml匯入dao模組
		2. 建立java.com.itheima.service,匯入介面Itemsservice,匯入impl.ItemsServiceImpl;
		3. 建立spring包,匯入applicationContext-service.xml   [刪除裡面所有關於dao的部分]
	4. 建立maven_day02_web
		1. 在該模組下pom.xml匯入service模組和dao模組
		2. 建立main.java.com.itheima.controller,補全該包下ItemsController
		3. 建立resources.log4j.properties,resources.springmvc.xml並補全
		4. 建立webapp.WEB-INF.pages.web.xml,並補全該web.xml內容
		5. 建立WEB-INF.index.jsp
		6. 發現web.xml內容中重新指定spring配置檔案的路徑報錯:param-value標籤顯紅色:
			* 在resources下建立一個applicationContext.xml;
			* <bean>
			* 匯入約束
			* <import resource="classpath:spring/application-dao.xml">
			* <import resource="classpath:spring/applicationContext-service.xml">
			* </bean>
	5.測試:	[三種方式測試]
		1. 方式一:啟動父工程的tomcat 7 的run進行訪問
		2. 方式二:在Maven Projects下的maven_day02_parent下找到install雙擊打包安裝到本地倉庫,再找到maven_day02_web下的tomcat 7 下的tomcat7:run雙擊執行
		3. 方式三:使用本地安裝的tomcat:新增tomcat,點選Edit Configurations...->Tomcat Server->Local-> 在Deployment下新增[web模組即可],exploded是熱啟動,war是打包啟動 -> 點選啟動;
		4. 總結:三種啟動方式,方式二模組下的專案需要自己安裝到本地倉庫,而父工程啟動和匯入的tomcat[方式一和方式二]不需要安裝到本地倉庫;


## 私服的安裝和啟動

1. 資料中一個是Linux的,一個是windows的,公司的私服一般在私服伺服器上;
2. 步驟:
	1. 解壓:
		* nexus-2.12.0-01:安裝包
		* sonatype-work: 私服
	2. 開啟nexus-2.12.0-01->bin->以管理員方式執行命令提示符->cd 該路徑地址->
		* 輸入:nexus.bat uninstall     [解除安裝]   
		* 或者輸入:nexus.bat install   [安裝]
		* 完成之後輸入:nexus.bat start   [執行]
	3. 埠號為8081:路徑:nexus-2.12.0-01-bundle->nexus-2.12.0-01->conf->nexus.properties中    【該配置檔案下有該埠號,如果埠號被佔用了,可以在該配置檔案下進行修改。】
	4. 測試:開啟瀏覽器輸入:localhost:8081/nexus/#welcome     
	5. 該地址需要登入:username:admin     password:admin123		[這是預設賬號密碼]
	6. 登入後,點選Repositories即可檢視到本地私服內的檔案了。
		* Snapshots:測試版
		* Releases:發行版
		* 3rd party:第三方
		* central: 中央倉庫   地址:https://repol:maven.org/maven2/
		* group:組:如果沒有就從私服下,私服沒有就從中央倉庫下。
	7. 遠端倉庫[私服]的實體地址:nexus-2.12.0-01-bundle->sonatype-work-nexus-storage

私服的應用

1. 設定登入密碼:
	1. 路徑:apache-maven-3.5.2 ->conf ->settings.xml 
	2. 開啟教案大綱複製server標籤,在該server標籤下新增內容:
		* <servers>
		* <server>		//登入的正式賬號密碼
		* <id>releases</id>
		* <username>admin</username>
		* <password>admin123</password>
		* </server>
		* <server>
		* <id>snapshots</id>		//登入的測試的賬號密碼
		* <username>admin</username>
		* <password>admin123</password>
		* </server>
		* </servaers>
	3. 在需要上傳的模組下的pom.xml中新增該程式碼:
		* <distributionManagement>
		* <repository>
		* <id>releases</id>
		* <url>http://localhost:8081/nexus/content/repositories/releases/</url>
		* </repository>
		* <snapshotRepository>
		* <id>snapshots</id>
		* <url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
		* </snapshotRepository>
		* </distributionMangement>
		* </project>
		* 正式對正式,測試對測試:公司中ip地址就不是localhost了,是需要改的。
2.將maven_day02_dao模組內容上傳到私服:
	1. 找到intellij idea的右邊Maven Projects 下的maven_day02_dao的deploy,雙擊執行
	2. 在nexus-2.12.0-01-bundle ->sonatype-work ->nexus ->storage ->snapshots下即可找到com的資料夾,該資料夾就是已經上傳到私服的檔案。
	

3. 這時候雖然已經上傳成功了,但是不一定能下載成功。下載和上傳的地址可能不一樣;
	1. 找到資料:下載jar包的配置,複製該一串程式碼。找到setting.xml,在標籤<profiles>下複製該程式碼
	2. 啟用:在資料中找到該程式碼,複製到<profile>標籤的外部的下面:
		* <activeProfiles>
		* <activeProfile>dev</activeProfile>
		* </activeProfiles>
	3. 這裡的dev要與上面的配置下載地址的id的內容對應上;這裡是都為dev;

4. 執行tomcat :執行的時候,即便本地倉庫中沒有dao模組,但是它可以到中央倉庫進行下載;

安裝第三方jar包到私服

1. 安裝到本地倉庫:
	1. 安裝第三放jar包需要找到它的座標,fastjson-1.1.37.jar的座標在右邊的mvn.txt中。
	2. 如果安裝其他的第三方jar包,將該文字的名字,版本號相應的修改即可。
2. 安裝到私服:
	1. 將文字的賬號貼上到maven中setting.xml中的賬號位置,參照上面:servers標籤內;
	2. 參照文字;