前言

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

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

需求分析

首先来看一下封面图,我们要实现的效果是:

1.多个项目共享一个项目的类和方法等通用内容

2.每个子项目单独导入所需依赖,以及各自填充父项目配置文件中的占位符

3.子项目按指定目录结构进行打包

4.所有子项目集成打包到一个统一的目录,共享依赖包和配置文件等内容

5.打包后目录结构:

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

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

实现

打包配置

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

  1. <dependency>
  2. <groupId>com.demo</groupId>
  3. <artifactId>project-monitor</artifactId>
  4. <version>0.0.1</version>
  5. </dependency>

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

  1. <plugin>
  2. <artifactId>maven-assembly-plugin</artifactId>
  3. <configuration>
  4. <appendAssemblyId>false</appendAssemblyId>
  5. <descriptors>
  6. <descriptor>package.xml</descriptor>
  7. </descriptors>
  8. </configuration>
  9. <executions>
  10. <execution>
  11. <id>make-assembly</id>
  12. <phase>package</phase>
  13. <goals>
  14. <goal>single</goal>
  15. </goals>
  16. </execution>
  17. </executions>
  18. </plugin>

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

  1. <assembly xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/assembly-1.0.0.xsd">
  3. <id>package</id>
  4. <formats>
  5. <format>zip</format>
  6. </formats>
  7. <includeBaseDirectory>true</includeBaseDirectory>
  8. <fileSets>
  9. <fileSet>
  10. <directory>src/main/resources</directory>
  11. <includes>
  12. <include>*.properties</include>
  13. <include>*.xml</include>
  14. </includes>
  15. <outputDirectory>etc</outputDirectory>
  16. </fileSet>
  17. </fileSets>
  18. <dependencySets>
  19. <dependencySet>
  20. <outputDirectory>lib</outputDirectory>
  21. <scope>runtime</scope>
  22. </dependencySet>
  23. </dependencySets>
  24. </assembly>

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

填充配置文件占位符

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

首先当然是创建配置文件了,在项目中创建jdbc.propertiesJDBC配置文件,如:

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

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

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

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

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

测试Demo

好了,接下来来测试项目的可行性,主要实现使用父项目定义的数据源来对MySql进行查询。

先创建一个DemoService类,内容如下:

  1. package com.demo.project.one.service;
  2. import org.apache.log4j.Logger;
  3. import javax.sql.DataSource;
  4. import java.sql.Connection;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. import java.sql.Statement;
  8. public class DemoService {
  9. private static final Logger logger = Logger.getLogger(DemoService.class);
  10. private DataSource dataSource;
  11. public void queryDb(){
  12. Connection conn = null;
  13. Statement stmt = null;
  14. ResultSet rs = null;
  15. try {
  16. conn = dataSource.getConnection();
  17. stmt = conn.createStatement();
  18. rs = stmt.executeQuery("select * from movie limit 1");
  19. while(rs.next()){
  20. logger.info(String.format("Movie[Id=%d,Title=%s,Director=%s,Genre=%s,Language=%s]",
  21. rs.getInt(1),
  22. rs.getString(2),
  23. rs.getString(3),
  24. rs.getString(4),
  25. rs.getString(5)
  26. ));
  27. }
  28. } catch (SQLException e) {
  29. e.printStackTrace();
  30. } finally {
  31. try {
  32. if(rs != null){
  33. rs.close();
  34. }
  35. if(stmt != null){
  36. stmt.close();
  37. }
  38. if(conn != null){
  39. conn.close();
  40. }
  41. } catch (SQLException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. }
  46. public void setDataSource(DataSource dataSource) {
  47. this.dataSource = dataSource;
  48. }
  49. }

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

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

别忘了添加log4j.properties配置文件,这里就不贴出文件内容了。

OK,新建一个入口类来执行DemoService的测试吧:

  1. package com.demo.project.one;
  2. import com.demo.project.one.service.DemoService;
  3. import org.springframework.context.ConfigurableApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5. public class Application {
  6. public static void main(String[] args){
  7. ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("/project-one.xml");
  8. DemoService demoService = (DemoService)context.getBean("demoService");
  9. demoService.queryDb();
  10. }
  11. }

最终的项目结构如图

打包

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

  1. mvn clean package

执行完成后你会发现target目录的结构如图所示



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

执行文件

项目开发完成,接下来就是执行程序了,以Windows平台下为例,首先创建bin目录,目录中创建批处理文件setenv.batproject-one.bat

因为jar包与配置文件的分离,所以我们需要指定执行jar包时的classpath,批处理文件内容如下:

setenv.bat

  1. @echo off
  2. set SRC_DIR=%cd%
  3. cd %~dp0
  4. cd ..
  5. set MAIN_HOME=%cd%
  6. cd %SRC_DIR%
  7. set BIN_HOME=%MAIN_HOME%\bin
  8. set ETC_HOME=%MAIN_HOME%\etc
  9. set LIB_HOME=%MAIN_HOME%\lib
  10. set CLASSPATH=%ETC_HOME%;%JAVA_HOME%\lib\tools.jar
  11. for %%i in (%LIB_HOME%\*.jar) do set CLASSPATH=!CLASSPATH!;%%i

project-one.bat

  1. @echo off
  2. @setlocal enableextensions enabledelayedexpansion
  3. call setenv.bat
  4. chcp 65001
  5. java -cp %CLASSPATH% com.demo.project.one.Application
  6. 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开发小技巧(三):Maven多工程依赖项目的更多相关文章

  1. Java开发小技巧(二):自定义Maven依赖

    前言 我们在项目开发中经常会将一些通用的类.方法等内容进行打包,打造成我们自己的开发工具包,作为各个项目的依赖来使用. 一般的做法是将项目导出成Jar包,然后在其它项目中将其导入,看起来很轻松,但是存 ...

  2. Java开发小技巧(一)

    前言 相信许多程序员在看别人写的代码的时候,会有怀疑人生的感想,面对一堆天书一样的代码,很难摸清作者的思路,最后选择了重构,如果你认同上面这个作法,说明了两个问题:要么原来的开发者技术菜.要么你技术菜 ...

  3. Java开发小技巧(六):使用Apache POI读取Excel

    前言 在数据仓库中,ETL最基础的步骤就是从数据源抽取所需的数据,这里所说的数据源并非仅仅是指数据库,还包括excel.csv.xml等各种类型的数据接口文件,而这些文件中的数据不一定是结构化存储的, ...

  4. Java开发小技巧(五):HttpClient工具类

    前言 大多数Java应用程序都会通过HTTP协议来调用接口访问各种网络资源,JDK也提供了相应的HTTP工具包,但是使用起来不够方便灵活,所以我们可以利用Apache的HttpClient来封装一个具 ...

  5. Java开发小技巧(四):配置文件敏感信息处理

    前言 不知道在上一篇文章中你有没有发现,jdbc.properties中的数据库密码配置是这样写的: jdbc.password=5EF28C5A9A0CE86C2D231A526ED5B388 其实 ...

  6. java开发小技巧

    链接地址:http://www.cnblogs.com/zkh101/p/8083368.html 人脸识别地址:http://blog.csdn.net/gitchat/article/detail ...

  7. 开发小技巧1——Logger

    开发小技巧1——Logger 在项目中加入静态Logger类,用于捕获并记录程序的进度.错误信息:   public static class Logger { public static void ...

  8. Mavean多工程依赖项目

    前言 本篇文章基于Java开发小技巧(二):自定义Maven依赖中创建的父工程project-monitor实现,运用我们自定义的依赖包进行多工程依赖项目的开发. 下面以多可执行Jar包项目的开发为例 ...

  9. [翻译]现代java开发指南 第三部分

    现代java开发指南 第三部分 第三部分:Web开发 第一部分,第二部分,第三部分 =========================== 欢迎来到现代 Java 开发指南第三部分.在第一部分中,我们 ...

随机推荐

  1. 软硬链接、文件删除原理、linux中的三种时间、chkconfig优化

    第1章 软硬链接 1.1 硬链接 1.1.1 含义 多个文件拥有相同的inode号码 硬链接即文件的多个入口 1.1.2 作用 防止你误删除文件 1.1.3 如何创建硬链接 ln 命令,前面是源文件  ...

  2. onload、DOMContentLoaded与性能问题

    onload.DOMContentLoaded与性能问题 onload事件 DomContentLoaded   1.onload事件 onload事件一般在所有的文档内容加载完成后触发,如果网页中图 ...

  3. 数据结构 单链表元素定位 PTA

    由于这个很简单,他也貌似没要判断溢出,取巧突破 #include<stdio.h> #include<malloc.h> #include<stdlib.h> // ...

  4. 高阶函数,柯里化,sort排序

    高阶函数概念 first class object:     函数在python中时一等公民.     函数也是对象,可调用的对象.     函数可以作为普通变量,参数,返回值等等. 高阶函数:    ...

  5. 《Linux命令行与shell脚本编程大全》 第七章理解Linux文件权限

    Linux沿用了Unix文件权限的方法,允许用户和组根据每个文件和目录的安全性设置来访问文件. 用户权限通过创建用户时分配的用户ID(UID)来跟踪的.每个用户有唯一的ID,但是登录时用的不是UID, ...

  6. Dev控件treeList

    之前做过一段时间,当时copy 的别人的代码,这就就把节点给添加了,上次帮同事做也发现了这个问题,当时没有记下来,今天有做,磨了半天,记下来吧. Dev控件treeList 要添加节点第一步是右键添加 ...

  7. Boost LRU-Cache使用方法简介

    缓存是提高系统运行效率的常用组件,可以将"有效的"业务数据直接返回用户,避免繁琐的计算过程.除了Redis.MemCache等常用缓存系统,应用程序内部也可以根据需要设置一定容量的 ...

  8. Java 中实现方法重试的一种机制

    有这样一个需求,当调用某个方法抛出异常,比如通过 HttpClient 调用远程接口时由于网络原因报 TimeOut 异常:或者所请求的接口返回类似于"处理中"这样的信息,需要重复 ...

  9. 关于事件mouseover ,mouseout ,mouseenter,mouseleave的区别

    轮播中大多会选择mouseover和mouseout  这个时候是没有任何问题的 但当遇到有css3动画的时候,会发现移入移出过快 动画还没加载完成就需要执行下一个动画,完了动画样式就错乱了. 这时候 ...

  10. MongoDB中的MapReduce介绍与使用

    一.简介 在用MongoDB查询返回的数据量很大的情况下,做一些比较复杂的统计和聚合操作做花费的时间很长的时候,可以用MongoDB中的MapReduce进行实现 MapReduce是个非常灵活和强大 ...