Maven多模块案例

wen java案例 3

本文目录导读:

Maven多模块案例

  1. 项目结构
  2. 父POM (pom.xml)
  3. 公共模块 (ecommerce-common/pom.xml)
  4. 数据访问模块 (ecommerce-dao/pom.xml)
  5. 业务逻辑模块 (ecommerce-service/pom.xml)
  6. Web展示模块 (ecommerce-web/pom.xml)
  7. API模块 (ecommerce-api/pom.xml)
  8. 构建和运行
  9. 最佳实践建议

我来为您提供一个完整的Maven多模块项目案例,这是一个典型的企业级电商系统示例。

项目结构

ecommerce-parent
├── pom.xml                    (父POM)
├── ecommerce-common         (公共模块)
│   ├── pom.xml
│   └── src/main/java/com/example/common
│       ├── util/
│       ├── exception/
│       └── result/
├── ecommerce-dao           (数据访问模块)
│   ├── pom.xml
│   └── src/main/java/com/example/dao
│       ├── entity/
│       └── mapper/
├── ecommerce-service       (业务逻辑模块)
│   ├── pom.xml
│   └── src/main/java/com/example/service
│       ├── impl/
│       └── interface/
├── ecommerce-web          (Web展示模块)
│   ├── pom.xml
│   └── src/main/java/com/example/web
│       ├── controller/
│       └── config/
└── ecommerce-api         (接口API模块)
    ├── pom.xml
    └── src/main/java/com/example/api
        ├── dto/
        └── vo/

父POM (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.example</groupId>
    <artifactId>ecommerce-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>Ecommerce Parent Project</name>
    <!-- 模块列表 -->
    <modules>
        <module>ecommerce-common</module>
        <module>ecommerce-dao</module>
        <module>ecommerce-service</module>
        <module>ecommerce-web</module>
        <module>ecommerce-api</module>
    </modules>
    <!-- 属性配置 -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <spring.version>5.3.9</spring.version>
        <mybatis.version>2.1.4</mybatis.version>
        <mysql.version>8.0.21</mysql.version>
        <junit.version>4.12</junit.version>
    </properties>
    <!-- 依赖管理(统一版本) -->
    <dependencyManagement>
        <dependencies>
            <!-- Spring -->
            <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>
            <!-- MyBatis -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
            <!-- MySQL -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!-- JUnit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!-- 公共依赖(所有子模块都会引用) -->
    <dependencies>
        <!-- 日志 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
    </dependencies>
    <!-- 构建配置 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
            <!-- 资源处理插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.2.0</version>
            </plugin>
        </plugins>
    </build>
</project>

公共模块 (ecommerce-common/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">
    <parent>
        <artifactId>ecommerce-parent</artifactId>
        <groupId>com.example</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ecommerce-common</artifactId>
    <dependencies>
        <!-- 工具类 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.11</version>
        </dependency>
        <!-- JSON处理 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.3</version>
        </dependency>
    </dependencies>
</project>

公共模块示例代码

package com.example.common.result;
import java.io.Serializable;
public class Result<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer code;
    private String message;
    private T data;
    public Result() {}
    public Result(Integer code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
    public static <T> Result<T> success(T data) {
        return new Result<>(200, "success", data);
    }
    public static <T> Result<T> error(Integer code, String message) {
        return new Result<>(code, message, null);
    }
    // getter/setter省略
}

数据访问模块 (ecommerce-dao/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">
    <parent>
        <artifactId>ecommerce-parent</artifactId>
        <groupId>com.example</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ecommerce-dao</artifactId>
    <dependencies>
        <!-- 依赖公共模块 -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>ecommerce-common</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!-- MyBatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <!-- MySQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>
</project>

数据访问模块示例代码

package com.example.dao.entity;
public class User {
    private Long id;
    private String username;
    private String email;
    private String phone;
    private Integer status;
    // getter/setter省略
}
package com.example.dao.mapper;
import com.example.dao.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface UserMapper {
    @Select("SELECT * FROM user WHERE id = #{id}")
    User findById(@Param("id") Long id);
    @Select("SELECT * FROM user WHERE username = #{username}")
    User findByUsername(@Param("username") String username);
}

业务逻辑模块 (ecommerce-service/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">
    <parent>
        <artifactId>ecommerce-parent</artifactId>
        <groupId>com.example</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ecommerce-service</artifactId>
    <dependencies>
        <!-- 依赖DAO模块 -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>ecommerce-dao</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!-- API模块(可选,如果service需要暴露接口给API层) -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>ecommerce-api</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!-- Spring事务支持 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>
    </dependencies>
</project>

业务逻辑模块示例代码

package com.example.service.impl;
import com.example.service.UserService;
import com.example.dao.entity.User;
import com.example.dao.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public User getUserById(Long id) {
        return userMapper.findById(id);
    }
    @Override
    public User getUserByUsername(String username) {
        return userMapper.findByUsername(username);
    }
}

Web展示模块 (ecommerce-web/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">
    <parent>
        <artifactId>ecommerce-parent</artifactId>
        <groupId>com.example</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ecommerce-web</artifactId>
    <packaging>war</packaging>
    <dependencies>
        <!-- 依赖service模块 -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>ecommerce-service</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!-- Spring MVC -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <finalName>ecommerce</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.4.5</version>
            </plugin>
        </plugins>
    </build>
</project>

Web模块示例代码

package com.example.web.controller;
import com.example.api.dto.UserDTO;
import com.example.api.vo.UserVO;
import com.example.common.result.Result;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/user")
public class UserController {
    @Autowired
    private UserService userService;
    @GetMapping("/{id}")
    public Result<UserVO> getUserById(@PathVariable Long id) {
        UserVO user = userService.getUserVOById(id);
        return Result.success(user);
    }
    @PostMapping
    public Result<Boolean> createUser(@RequestBody UserDTO userDTO) {
        boolean result = userService.createUser(userDTO);
        return Result.success(result);
    }
}

API模块 (ecommerce-api/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">
    <parent>
        <artifactId>ecommerce-parent</artifactId>
        <groupId>com.example</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ecommerce-api</artifactId>
    <dependencies>
        <!-- 依赖公共模块 -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>ecommerce-common</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!-- Swagger文档生成 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>
    </dependencies>
</project>

API模块示例代码

package com.example.api.dto;
import java.io.Serializable;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
public class UserDTO implements Serializable {
    private static final long serialVersionUID = 1L;
    @NotBlank(message = "用户名不能为空")
    private String username;
    @Email(message = "邮箱格式不正确")
    private String email;
    private String phone;
    // getter/setter省略
}

构建和运行

Maven构建命令

# 清理并构建所有模块
mvn clean install
# 只构建特定模块及其依赖
mvn clean install -pl ecommerce-web -am
# 跳过测试
mvn clean install -DskipTests
# 构建到本地仓库但不上传
mvn clean install -Dmaven.test.skip=true

应用配置示例 (application.yml)

server:
  port: 8080
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ecommerce?useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath:/mapper/**/*.xml
  type-aliases-package: com.example.dao.entity

项目依赖关系图

ecommerce-web         (Web层 - Controller)
    ↓
ecommerce-service     (Service层 - 业务逻辑)
    ↓
ecommerce-dao         (DAO层 - 数据访问)
    ↓
ecommerce-common      (公共模块 - 工具类、常量)
    ↓
ecommerce-api         (API模块 - 接口定义DTO/VO)

最佳实践建议

  1. 依赖方向:依赖只能从上往下,不能反向依赖
  2. 版本管理:在父POM统一管理版本
  3. 模块划分:按业务功能划分,避免过多过细
  4. 构建优化:使用-am参数构建依赖模块
  5. 测试策略:集成测试放在对应的功能模块中
  6. 配置管理:使用Profile区分不同环境
  7. 解决冲突:优先使用Spring Boot的BOM管理依赖

这个案例展示了Maven多模块项目的标准结构和管理方式,适用于中小型项目开发。

抱歉,评论功能暂时关闭!