• Java开发小技巧(三):Maven多工程依赖项目


    Maven多工程依赖项目开发流程

    前言

    本篇文章基于Java开发小技巧(二):自定义Maven依赖中创建的父工程project-monitor实现,运用我们自定义的依赖包进行多工程依赖项目的开发。

    下面以多可执行Jar包项目的开发为例,进行Maven多工程依赖项目开发的讲解。

    需求分析

    首先来看一下封面图,我们要实现的效果是:
    1.多个项目共享一个项目的类和方法等通用内容
    2.每个子项目单独导入所需依赖,以及各自填充父项目配置文件中的占位符
    3.子项目按指定目录结构进行打包
    4.所有子项目集成打包到一个统一的目录,共享依赖包和配置文件等内容
    5.打包后目录结构:

    • bin:存放脚本文件,用来设置环境变量,执行相应的jar包
    • lib:依赖、项目jar包
    • etc:配置文件
    • ......

    好啦,目标明确的,接下来要进行具体开发实现了

    实现

    打包配置

    在上一篇文章中已经创建好了一个自定义的Maven依赖,相当于一个父项目,接下来我们新建一个子项目,命名为project-onepom.xml文件与父项目基本相同,所有依赖包都必须单独引入,不同的是多了对父项目的依赖:

    <dependency>
        <groupId>com.demo</groupId>
        <artifactId>project-monitor</artifactId>
        <version>0.0.1</version>
    </dependency>
    

    以及Maven插件maven-assembly-plugin的引入,用来实现依赖的打包以及打包后的目录结构:

    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
            <appendAssemblyId>false</appendAssemblyId>
            <descriptors>
                <descriptor>package.xml</descriptor>
            </descriptors>
        </configuration>
        <executions>
            <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    

    目录结构配置位于项目根目录下package.xml配置文件中:

    <assembly 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.0http://maven.apache.org/xsd/assembly-1.0.0.xsd">
        <id>package</id>
        <formats>
            <format>zip</format>
        </formats>
        <includeBaseDirectory>true</includeBaseDirectory>
    
        <fileSets>
            <fileSet>
                <directory>src/main/resources</directory>
                <includes>
                    <include>*.properties</include>
                    <include>*.xml</include>
                </includes>
                <outputDirectory>etc</outputDirectory>
            </fileSet>
        </fileSets>
        <dependencySets>
            <dependencySet>
                <outputDirectory>lib</outputDirectory>
                <scope>runtime</scope>
            </dependencySet>
        </dependencySets>
    </assembly>
    

    以上就实现了项目打包的配置工作,实现流程图中最后的项目结构,打包结果为zip文件

    填充配置文件占位符

    之前我们在父项目的spring上下文中定义了一个数据源bean,配置信息使用了占位符填充,所以如果我们想要使用这个bean,就需要替换其中的占位符信息,要怎么做呢?
    首先当然是创建配置文件了,在项目中创建jdbc.propertiesJDBC配置文件,如:

    jdbc.driverClassName=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localdb:3306/test?characterEncoding=utf8&useSSL=true&serverTimezone=UTC
    jdbc.username=root
    jdbc.password=5EF28C5A9A0CE86C2D231A526ED5B388
    

    然后我们需要借助PropertyPlaceholderConfigurer这个类来实现,在项目spring上下文中定义bean:

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <value>classpath:jdbc.properties</value>
        </property>
        <property name="ignoreResourceNotFound" value="false"/>
    </bean>
    

    Bingo,占位符修改完毕,别忘了引入父项目的上下文,毕竟我们要填充占位符的bean是在父项目中的:

    <import resource="classpath*:project-monitor.xml"/>
    

    测试Demo

    好了,接下来来测试项目的可行性,主要实现使用父项目定义的数据源来对MySql进行查询。
    先创建一个DemoService类,内容如下:

    package com.demo.project.one.service;
    
    import org.apache.log4j.Logger;
    
    import javax.sql.DataSource;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class DemoService {
        private static final Logger logger = Logger.getLogger(DemoService.class);
        private DataSource dataSource;
    
        public void queryDb(){
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;
    
            try {
                conn = dataSource.getConnection();
                stmt = conn.createStatement();
                rs = stmt.executeQuery("select * from movie limit 1");
                while(rs.next()){
                    logger.info(String.format("Movie[Id=%d,Title=%s,Director=%s,Genre=%s,Language=%s]",
                            rs.getInt(1),
                            rs.getString(2),
                            rs.getString(3),
                            rs.getString(4),
                            rs.getString(5)
                            ));
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                try {
                    if(rs != null){
                        rs.close();
                    }
                    if(stmt != null){
                        stmt.close();
                    }
                    if(conn != null){
                        conn.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public void setDataSource(DataSource dataSource) {
            this.dataSource = dataSource;
        }
    }
    

    在上下文中为其注入dataSource定义:

    <bean id="demoService" class="com.demo.project.one.service.DemoService">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    

    别忘了添加log4j.properties配置文件,这里就不贴出文件内容了。
    OK,新建一个入口类来执行DemoService的测试吧:

    package com.demo.project.one;
    
    import com.demo.project.one.service.DemoService;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Application {
        public static void main(String[] args){
            ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("/project-one.xml");
            DemoService demoService = (DemoService)context.getBean("demoService");
            demoService.queryDb();
        }
    }
    

    最终的项目结构如图
    项目结构

    打包

    一切准备就绪,轮到项目打包了,在项目根目录执行以下Maven命令即可

    mvn clean package
    

    执行完成后你会发现target目录的结构如图所示
    target目录结构
    project-one.zip就是我们要的打包结果,解压后你会发现,依赖包和配置文件已经放在了各自的目录下
    zip包目录结构

    执行文件

    项目开发完成,接下来就是执行程序了,以Windows平台下为例,首先创建bin目录,目录中创建批处理文件setenv.batproject-one.bat
    因为jar包与配置文件的分离,所以我们需要指定执行jar包时的classpath,批处理文件内容如下:

    setenv.bat

    @echo off
    set SRC_DIR=%cd%
    
    cd %~dp0
    cd ..
    set MAIN_HOME=%cd%
    
    cd %SRC_DIR%
    
    set BIN_HOME=%MAIN_HOME%in
    set ETC_HOME=%MAIN_HOME%etc
    set LIB_HOME=%MAIN_HOME%lib
    set CLASSPATH=%ETC_HOME%;%JAVA_HOME%lib	ools.jar
    
    for %%i in (%LIB_HOME%*.jar) do set CLASSPATH=!CLASSPATH!;%%i
    

    project-one.bat

    @echo off
    @setlocal enableextensions enabledelayedexpansion
    call setenv.bat
    
    chcp 65001
    java -cp %CLASSPATH% com.demo.project.one.Application
    pause
    

    bat文件的内容就不详细解释,有兴趣可以百度了解一下,主要是为了拼接出完整的CLASSPATH,执行project-one-0.0.1.jar可执行jar包

    运行

    点击project-one.bat运行程序
    运行结果

    结语

    项目终于开发演示完毕,这里只是创建一个打造可执行jar包的子项目作为例子,你还可以创建多个子项目,最后打包的时候合并相同的依赖和配置文件,然后在bin中创建相应项目的执行文件即可,各个子项目之间也可进行相互依赖。
    以上开发技巧不仅适用于可执行jar包的开发,同样适用于WEB项目的开发,具体还是由项目需求决定。

    文章项目源码已发布到Github:https://github.com/ZKHDEV/MultDependPjo

    本文为作者kMacro原创,转载请注明来源:http://www.jianshu.com/p/3fa98dd52520。

  • 相关阅读:
    我的第一次JAVA实训——校园公用房管理系统
    打我吧,不写了
    我有我的方向
    JAVA 算法练习(二)
    JAVA 算法练习(一)
    php设置时区和strtotime转化为时间戳函数
    dos中文乱码怎么办?
    织梦怎么调用栏目SEO标题
    for in循环介绍以及陷阱
    浅谈js for循环输出i为同一值的问题(闭包解决)
  • 原文地址:https://www.cnblogs.com/zkh101/p/8083368.html
Copyright © 2020-2023  润新知