YOU'VE MADE A BRAVE DECISION, WELCOME.

每一个不曾起舞的日子都是对生命的辜负。

学习笔记:Maven-2


多模块项目介绍

Maven中,一个大型项目分为若干个子项目,也就是module。提高重用率。相关的业务逻辑放在一个模块中进行集中管理,体现了单一原则。


创建骨架结构

  1. 进入helloweb根目录,新建四个文件夹,分别是:/helloweb-core,/helloweb-parent,/helloweb-web,/helloweb-entity
  2. 将根目录下的/src与pom.xml分别复制到新创建的四个文件夹,根目录删掉/src
  3. 修改根目录下的pom.xml,删除后的所有标签

    • <modelVersion>用来说明当前的pom文件遵循的是哪个model版本
    • <packaging>是打包的类型:jar普通的java类库(默认类型);war普通的javaweb应用程序;ear包含全部企业应用程序,包括jar,war;pom不打包成任何文件,代表副项目
  4. 添加以下内容,用来添加模块列表,里面填写文件的相对路径

    1
    2
    3
    4
    5
    6
    <modules>
    <module>helloweb-parent</module>
    <module>helloweb-entity</module>
    <module>helloweb-web</module>
    <module>helloweb-core</module>
    </modules>
  5. 在四个文件夹下的pom.xml的下面添加以下代码:

    1
    2
    3
    4
    5
    6
    <parent>
    <groupId></groupId>
    <artifactId></artifactId>
    <version></version>
    <relationPath></relationPath>
    </parent>

删除四个文件pom.xml的冗余配置信息,从下的标签开始,helloweb-web从开始删除


使用dependencyManagement管理依赖

Maven使用dependencyManagement元素来定义一种管理依赖版本号的方法。

  1. 在helloweb-parent的pom.xml中,添加以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    <dependencyManagement>
    <dependencies>
    <denpency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
    </denpency>
    <denpency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.1</version>
    <scope>provided</scope>
    </denpency>
    <denpency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
    </denpency>
    <denpency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.21</version>
    <scope>compile</scope>
    </denpency>
    </dependencies>
    </dependencyManagement>
  2. 构建项目,$maven install ,成功后不需要再子项目中添加具体依赖的版本号

  3. 例如在helloweb-entity的pom.xml中加上以下代码:

    1
    2
    3
    4
    5
    6
    7
    <dependencies>
    <denpency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
    </denpency>
    </dependencies>
  4. 构建成功即可说明,在父项目中添加dependencyManagement了就可以在子项目中省略版本号

使用PluginManagement管理插件

PluginManagement作用:Maven使用PluginManagement元素来提供了一种管理插件的方式。

  1. 进入helloweb-parent文件夹下的pom.xml,添加以下代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <build>
    <pluginManagement>
    <plugins>
    <plugin>
    <groupId>org.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
    <source>1.7</source>
    <target>1.7</source>
    <encoding>UTF-8<encouding>
    </configuration> </plugin>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>2.6</version>
    </plugin>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.4</version>
    <configuration>
    <warName>${priject.artifactId}</warName>
    </configuration> </plugin>
    </plugins>
    </pluginManagement>
    </build>
  2. 进入helloweb-entity文件夹下的pom.xml的已经进行了相应的改变

定义项目属性及配置信息

  1. 打开helloweb-parent文件夹下的pom.xml文件,在标签下添加以下的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <properties>
    <jdk.version>1.7</jdk.version>
    <servlet.api.version>3.0.1</servlet.api.version>
    <jsp.api.version>2.1</jsp.api.version>
    <junit.version>4.11</junit.version>
    <mysql.version>5.1.21</mysql.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    //ps:<properties>功能是定义一些常量,可以在pom.xml的其他地方进行引用
  2. 替换常量时候的格式${jdk.version}

  3. 重新构建$maven install,若正确则说明修改成功
  • description 项目表示信息
  • url 项目的地址
  • inceptionYear 项目起止年份
  • 其他

完善helloweb-entity模块

  1. 启动MySQL,新建数据库maven_db
  2. 在新建的数据库上点击右键,将其设置为默认的”scheme”
  3. 新建表,语句成功后点击”闪电”图标,刷新scheme

    1
    2
    3
    4
    5
    6
    7
    create table users(
    id int(11) unsigned not null auto_increment,
    name varchar(50) not null,
    password varchar(50) not null,
    email varchar(50),
    primary key(id) engine = InnoDB default charset=utf8
    )
  4. 插入一条数据,填写完成后选中这条sql语句,点击闪电图标,显示插入成功

    1
    insert into user(name,password,email)values('Tom','123456','tom@163.com');
  5. 在helloweb-entity的src/中建立User.java文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class User{
    private long id;
    private String name;
    private String password;
    private String email;
    }
    @Override
    public String toString(){
    return "User [id="+ id +",name=" + name + ",password=" + password+ ",email=" + email + "]";
    }
    //自动生成get,set方法
  6. 打包,run as $maven install


完善helloweb-core模块

  1. 在helloweb-code的src/main中建立resources/文件夹,设置其为Source Folder
  2. 在其下建立一个新文件dbconfig.properties
  3. 在属性文件里添加数据库的配置信息

    1
    2
    3
    4
    5
    6
    7
    8
    //驱动名称
    driver=com.mysql.jdbc.Driver
    //jdbc链接地址
    dburl=jdbc:mysql://localhost:3306/maven_db
    //用户名
    user=root
    //密码为空
    password
  4. 新建一个java/util文件夹,其下新建ConnectionFactory.java文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    package com.XXX.util;
    public class ConnectionFactory{
    private static String driver;
    private static String dburl;
    private static String user;
    private static String password;
    private static final ConnectionFactory factory = new ConnectionFactory();
    private Connection conn;
    static{
    Properties prop = new Properties();
    try{
    InputStream in = ConnectionFactory class getClassLoader().getResourceAsStream("dbconfig.properties");
    prop.load(in);
    }catch(Exception e){
    //TODO
    }
    driver = prop.getProperty("driver");
    dburl=prop.getProperty("dburl");
    user=prop.getProperty("user");
    password=prop.getProperty("password");
    }
    private ConnectionFactory(){
    }
    public static ConnectionFactory getInstance(){
    return factory;
    }
    public Connection makeConnection(){
    try{
    Class forName(driver)
    conn = DriverManager.getConnection(dburl,user,password);
    }catch(Exception e){
    e.printStackTrace();
    }
    return conn;
    }
    }
  5. 在helloweb-code的pom.xml文件中添加MySQL驱动

    1
    2
    3
    4
    5
    6
    7
    <dependencies>
    <denpency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>compile</scope>
    </denpency>
    </dependencies>
  6. 与util同级建立dao和service文件夹,dao文件夹下建立impl文件夹和UserDao.java,service文件夹下建立CheckUserService.java;

  7. 添加依赖

    1
    2
    3
    4
    5
    6
    7
    <dependency>
    <groupId>com.sakura</groupId>
    <artifactId>helloweb-entity</artifactId>
    <version>1.0</version>
    <type>jar</type>
    <scope>complie</scope>
    </dependency>
  8. 打包项目,$mvn install


完善helloweb-web模块

  1. 在helloweb-web的main/下建立action包,再建立CheckAction.java,引入HttpServlet,引入doGetdoPost方法,并在其中补充完整业务逻辑代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    private CheckUserService cku = new CheckUserService();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOExceotion{
    doPost(req, resp);
    }
    @Override
    protected void doPost(HttpservletRequest req, HttpServletResopnse resp)throws SerletException, IOException{
    String uname = req.getParameter("uname");
    String password = req.getParameter("upwd");
    RequestDispatcher rd = null;
    String forward = null;
    if(uname == null || password == null){
    req.setAttribute("msg","error!");
    rd = req.getRequestDispatcher("error.jsp");
    rd.forward(req,resp);
    }else{
    User user = new User();
    user.setName(uname);
    user.setPassword(password);
    boolean bool = cku check(user);
    if(bool){
    forward = "success.jsp";
    }else{
    req.setAttribute("msg","error");
    forward = "error.jsp";
    }
    rd = req.getRequestDispatcher(forward);
    rd.forward(req,resp);
    }
    }
  2. 添加依赖

    1
    2
    3
    4
    5
    6
    7
    <dependency>
    <groupId>com.XXX<groupId>
    <artifactId>helloweb-core<artifactId>
    <version>1.0<version>
    <type>jar<type>
    <scope>compile<scope>
    </dependency>
  3. 在webapp文件夹下写入error.jsp,index.jsp,login.jsp,success.jsp

  4. 在webapp/WEB-INF下写入web.xml
  5. 使用Tomcat启动

使用log4j打印日志

  1. 打开helloweb-parent的pom.xml,添加依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</ artifactId>
    <version>2.2</version>
    </dependency>
    <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</ artifactId>
    <version>2.2</version>
    </dependency>
  2. 打开helloweb-entity的pom.xml,添加依赖

    1
    2
    3
    4
    5
    6
    7
    8
    <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</ artifactId>
    </dependency>
    <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</ artifactId>
    </dependency>
  3. 构建helloweb-parent模块,在构建helloweb-entity.$mvn install

  4. 在helloweb-entity的main/建立与java同级的resources文件夹
  5. 在新建的文件夹中建立log4j2.xml文件
  6. 添加内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration status="OFF">
    <appenders>
    <Console name="Console" target="SYSTEM_OUT">
    <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    </appenders>
    <loggers>
    <root level="trace">
    <appender-ref ref="Console"/>
    </root>
    </loggers>
    </configuration>

POM.xml的配置信息

  • project 包含了pom的信息
  • modelVersion 指定当前pom版本
  • groupId 包名,反写的公司网址+项目名
  • artifactId 模块名,项目名+模块名
  • version 三位数,大版本号+分支版本号+小版本号
  • packaging 打包类型,默认是jar
  • name 项目描述名
  • url 项目地址
  • description 项目的描述
  • developers 开发者列表
  • licenses 许可号
  • organization 组织信息
  • dependencies 依赖信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <dependency>
    <groupId></groupId>
    <artifactId></artifactId>
    <version></version>
    <type></type>
    <scope></scope> //可用的范围,test,system,runtime等
    <optional></optional> //设置依赖是否可选
    <exclusions> //排除依赖传递列表
    <exclusion>
    </exclusion>
    </exclusions>
    </dependency>
  • dependencyManagement 依赖管理

    1
    2
    3
    4
    5
    6
    7
    <dependencies>
    <denpendency>
    <groupId></groupId>
    <artifactId></artifactId>
    <version></version>
    </denpendency>
    </dependencies>
  • build 插件列表

    1
    2
    3
    4
    5
    6
    7
    <plugins>
    <plugin>
    <groupId></groupId>
    <artifactId></artifactId>
    <version></version>
    </plugin>
    </plugins>
  • parent 子模块中对父模块pom的继承

  • modules 聚合运行多个模块

具体的结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<project>
<modelVersion></modelVersion>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<packaging></packaging>
<name></name>
<url></url>
<description></description>
<developers>
<developer>
</developer>
</developers>
<licenses></licenses>
<organization></organization>
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<type></type>
<scope></scope>
<optional></optional>
<exclusions>
<exclusion>
</exclusion>
</exclusions>
</dependency>
<dependencies>
<dependencyManagement>
<dependencies>
<denpendency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
</denpendency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
</plugin>
</plugins>
</build>
<parent>
<groupId></groupId>
<artifactId></artifactId>
</parent>
<modules>
<module></module>
</modules>
</project>

依赖的范围

maven中提供了三种classpath:编译,测试,运行 scope共有六种:

  • complie 默认,只在编译测试运行时有效
  • provided 编译测试时有效
  • runtime 测试和运行时有效
  • test 测试时有效
  • system 编译和测试时有效,与本机系统相关联
  • import 导入的依赖范围,表示从其他的pom中继承过来,只在dependencesManagement中使用

依赖传递

依赖冲突

  1. 短路优先
  2. 路径相同,先声明先依赖

聚合和继承

聚合:使用modules标签

继承:使用parent标签