分模块构建工程
上一节中,利用maven构建了一个最基础的ssh项目,这一节将对该项目进行分模块构建工程。
通过聚合和继承构建
继承:创建一个parent工程将通用的pom配置抽取出来 聚合:聚合多个模块运行
需求
将ssh工程拆分为多个模块开发
dao + service + web
理解继承和聚合
通常继承和聚合同时使用
- 继承
继承是为了消除重复,如果将dao、service、web分开创建独立的工程则每个工程的pom.xml文件中的内容存在重复,比如:设置编译版本、锁定spring的版本的等,可以将这些重复的配置提取出来在父工程的pom.xml中定义。
- 聚合
项目开发通常是分组分模块开发,每个模块开发完成要运行整个工程需要将每个模块聚合在一起运行,比如:dao、service、web三个工程最终会打一个独立的war运行。
案例实现
maven-parent父模块
创建父工程
注意,父工程只是一个pom工程
定义pom.xml
在父工程的pom.xml中抽取一些重复的配置的,比如:锁定jar包的版本、设置编译版本等。
<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.yaolong.maven</groupId>
<artifactId>maven-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>parent project</name>
<!-- 属性 -->
<properties>
<spring.version>4.2.4.RELEASE</spring.version>
<hibernate.version>5.0.7.Final</hibernate.version>
<struts.version>2.3.24</struts.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 统一依赖构件版本 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>${struts.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>${struts.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>maven-web</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
将父工程发布至仓库
父工程创建完成执行maven-install将父工程发布到仓库方便子工程继承:
查看本地仓库,看到maven-parent已经被安装
maven-dao子模块
创建dao子模块
选择maven模块:
这里指定模块名称,选择父工程,选择“跳过骨架选择”:
定义pom.xml
dao模块的pom.xml文件中需要继承父模块,添加持久层需要的依赖坐标:
<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>
<parent>
<groupId>com.yaolong.maven</groupId>
<artifactId>maven-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>maven-dao</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<!-- 数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
<!-- c3p0 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.2</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
dao接口
将maven-web工程中的dao接口及domain类拷贝到src/main/java中:
配置文件
将applicationContext.xml拆分出一个applicationContext-dao.xml,此文件中只配置dao
applicationContext-dao.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- dao -->
<bean id="newsDao" class="com.yaolong.maven.demo.dao.impl.NewsDaoImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 数据库连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/hibernatedb" />
<property name="user" value="root" />
<property name="password" value="12345" />
</bean>
<!-- 配置sessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 依赖dataSource -->
<property name="dataSource" ref="dataSource"/>
<!-- 创建工厂需要加载hibernate映射文件 -->
<property name="configLocations" value="classpath:hibernate.cfg.xml"></property>
</bean>
</beans>
单元测试
package com.yaolong.maven.demo.dao.impl;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.yaolong.maven.demo.dao.NewsDao;
import com.yaolong.maven.demo.domain.News;
@ContextConfiguration(locations = { "classpath:applicationContext.xml", "classpath:applicationContext-dao.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class NewsDaoImplTest {
@Autowired
private NewsDao newsDao;
@Before
public void setUp() throws Exception {
}
@Test
public void testFindNewsById() {
News news = newsDao.findNewsById(1);
System.out.println(news.getContent());
}
}
项目目录结构
maven-service子模块
创建service子模块
方法同maven-dao模块创建方法,模块名称为maven-service。
定义pom.xml
<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>
<parent>
<groupId>com.yaolong.maven</groupId>
<artifactId>maven-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>maven-service</artifactId>
<packaging>jar</packaging>
<dependencies>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
<!-- 依赖dao -->
<dependency>
<groupId>com.yaolong.maven</groupId>
<artifactId>maven-dao</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
- 创建applicationContext-service.xml,此文件中定义的service。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- service -->
<bean id="newsService" class="com.yaolong.maven.demo.service.impl.NewsServiceImpl">
<property name="newsDao" ref="newsDao"/>
</bean>
</beans>
NewsService.java
package com.yaolong.maven.demo.service;
import com.yaolong.maven.demo.domain.News;
public interface NewsService {
public News findNewsById(Integer newsId);
}
NewsServiceImpl.java
package com.yaolong.maven.demo.service.impl;
import com.yaolong.maven.demo.dao.NewsDao;
import com.yaolong.maven.demo.domain.News;
import com.yaolong.maven.demo.service.NewsService;
public class NewsServiceImpl implements NewsService {
private NewsDao newsDao;
public void setNewsDao(NewsDao newsDao) {
this.newsDao = newsDao;
}
@Override
public News findNewsById(Integer newsId) {
return this.newsDao.findNewsById(newsId);
}
}
单元测试
package com.yaolong.maven.demo.service.impl;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.yaolong.maven.demo.domain.News;
import com.yaolong.maven.demo.service.NewsService;
@ContextConfiguration(locations = {"classpath:applicationContext.xml","classpath:applicationContext-service.xml","classpath:applicationContext-dao.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class NewsServiceImplTest {
@Autowired
private NewsService newsService;
@Before
public void setUp() throws Exception {
}
@Test
public void testFindCustomerById() {
News news = newsService.findNewsById(1);
System.out.println(news.getContent());
}
}
项目目录结构
maven-web子模块
创建web子模块
方法同maven-dao模块创建方法,模块名称为maven-web。
- action
package com.yaolong.maven.demo.action;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.yaolong.maven.demo.domain.News;
import com.yaolong.maven.demo.service.NewsService;
public class NewsAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private News news;
public News getNews() {
return news;
}
public void setNews(News news) {
this.news = news;
}
private NewsService newsService;
public NewsService getNewsService() {
return newsService;
}
public void setNewsService(NewsService newsService) {
this.newsService = newsService;
}
//根据主键获取新闻信息
public String queryNews(){
String id = ServletActionContext.getRequest().getParameter("id");
news = newsService.findNewsById(Integer.valueOf(id));
return SUCCESS;
}
}
applicationContext-web.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- action -->
<bean id="newsAction" class="com.yaolong.maven.demo.action.NewsAction" scope="prototype">
<property name="newsService" ref="newsService"/>
</bean>
</beans>
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<import resource="classpath:applicationContext-web.xml"/>
<import resource="classpath:applicationContext-service.xml"/>
<import resource="classpath:applicationContext-dao.xml"/>
</beans>
模块聚合
修改父工程的pom.xml,添加:
<!-- 由于父工程要聚合子工程,配置modules -->
<modules>
<!-- 在modules中配置相对路径,相对父工程pom.xml的路径找到子工程的pom.xml -->
<module>maven-dao</module>
<module>maven-service</module>
<module>maven-web</module>
</modules>
注意:上边module中配置的路径,此路径是相对父工程的pom.xml文件找子工程的pom.xml文件的路径。
运行调试
方法1:
在maven-web工程的pom.xml中配置tomcat插件运行 运行maven-web工程它会从本地仓库下载依赖的jar包,所以当maven-web依赖的jar包内容修改了必须及时发布到本地仓库,比如:maven-web依赖的maven-service修改了,需要及时将maven-service发布到本地仓库。
方法2:
在父工程的pom.xml中配置tomcat插件运行,自动聚合并执行
推荐方法2,如果子工程都在本地,采用方法2则不需要子工程修改就立即发布到本地仓库,父工程会自动聚合并使用最新代码执行。
注意:如果子工程和父工程中都配置了tomcat插件,运行的端口和路径以子工程为准。