本篇文章基于 Java 开发小技巧(二):自定义 Maven 依赖 中创建的父工程 project-monitor 实现,运用我们自定义的依赖包进行多工程依赖项目的开发。
下面以多可执行 Jar 包项目的开发为例,进行 Maven 多工程依赖项目开发的讲解。
首先来看一下封面图,我们要实现的效果是:
1. 多个项目共享一个项目的类和方法等通用内容
2. 每个子项目单独导入所需依赖,以及各自填充父项目配置文件中的占位符
3. 子项目按指定目录结构进行打包
4. 所有子项目集成打包到一个统一的目录,共享依赖包和配置文件等内容
5. 打包后目录结构:
好啦,目标明确的,接下来要进行具体开发实现了
在上一篇文章中已经创建好了一个自定义的 Maven 依赖,相当于一个父项目,接下来我们新建一个子项目,命名为 project-one,pom.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
然后我们需要借助
这个类来实现,在项目 spring 上下文中定义 bean:
- PropertyPlaceholderConfigurer
- <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"
- />
好了,接下来来测试项目的可行性,主要实现使用父项目定义的数据源来对 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 目录的结构如图所示
project-one.zip 就是我们要的打包结果,解压后你会发现,依赖包和配置文件已经放在了各自的目录下
项目开发完成,接下来就是执行程序了,以 Windows 平台下为例,首先创建 bin 目录,目录中创建批处理文件 setenv.bat、project-one.bat
因为 jar 包与配置文件的分离,所以我们需要指定执行 jar 包时的 classpath,批处理文件内容如下:
- @echo off
- set SRC_DIR=%cd%
- cd %~dp0
- cd ..
- set MAIN_HOME=%cd%
- cd %SRC_DIR%
- set BIN_HOME=%MAIN_HOME%\bin
- set ETC_HOME=%MAIN_HOME%\etc
- set LIB_HOME=%MAIN_HOME%\lib
- set CLASSPATH=%ETC_HOME%;%JAVA_HOME%\lib\tools.jar
- for %%i in (%LIB_HOME%\*.jar) do set CLASSPATH=!CLASSPATH!;%%i
- @echo off
- @setlocal enableextensions enabledelayedexpansion
- call setenv.bat
- chcp 65001
- java -cp %CLASSPATH% com.demo.project.one.Application
- pause
bat 文件的内容就不详细解释,有兴趣可以百度了解一下,主要是为了拼接出完整的 CLASSPATH,执行
可执行 jar 包
- project-one-0.0.1.jar
点击 project-one.bat 运行程序
项目终于开发演示完毕,这里只是创建一个打造可执行 jar 包的子项目作为例子,你还可以创建多个子项目,最后打包的时候合并相同的依赖和配置文件,然后在 bin 中创建相应项目的执行文件即可,各个子项目之间也可进行相互依赖。
以上开发技巧不仅适用于可执行 jar 包的开发,同样适用于 web 项目的开发,具体还是由项目需求决定。
文章项目源码已发布到 Github: https://github.com/ZKHDEV/MultDependPjo
本文为作者 kMacro
来源: http://www.cnblogs.com/zkh101/p/8083368.html