java实现的一个maven多模块项目自动生成工具
Posted worldwalker77
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java实现的一个maven多模块项目自动生成工具相关的知识,希望对你有一定的参考价值。
平时在做spring mvc web新项目时,都需要自己去搭建spring mvc的项目框架,包括基本pom 依赖引入,基本配置文件(web.xml,spring-mvc.xml,数据库配置文件等等),基础工具类引入。实际上对于所有spring mvc web项目,这些基础的配置和基础类都是通用的,都是可以复用,真正需要改变的无非是我们具体的业务逻辑。所以我们可以把这些通用的东西都做成基础模板,通过指定项目的groupId、artifactId、version就可以通过代码自动生成spring mvc 的项目框架,这个项目框架可以直接运行,我们要做的就是直接往项目框架里面添加具体的业务逻辑,在做新项目时可以大大的提高项目的开发效率。
以下是代码实现,主要就是通过代码读取已经写好的模板文件,根据指定的groupId、artifactId去替换模板文件中的${groupId}、${artifactId}占位符,将替换后的文件写入生成的目录路径下(spring mvc java web项目目录路径都是固定的),并生成spring mvc项目框架,模板文件将项目分为多个模块,web、service、rpc(远程调用模块)、dao(数据库调用模块)、common(基础工具类模块)、cache(缓存模块)、domain(model对象模块):
package com.project.maven.generator; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Map.Entry; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * 多模块maven项目自动生成 * @author liujinfeng * */ public class MavenProjectGenerate { private static final Log log = LogFactory.getLog(MavenProjectGenerate.class); /**使用的模板文件夹名称*/ private static final String sourceTemplate = "sourceTemplate"; private static final String groupId = "com.zhaogang.mpay"; private static final String artifactId = "mpay"; /**在创建hessian调用客户端应用的时候才会使用*/ // private static final String serverGroupId = "com.zhaogang.pricesoa"; // private static final String serverArtifactId = "price-soa"; /**电脑盘符,文件路径*/ private static final String disk = "E"; /**源模板文件基础路径*/ private static final String sourceBasePath = disk + ":\\\\generateProject\\\\" + sourceTemplate; private static final String sourceBasePath1 = disk + ":\\\\\\\\generateProject\\\\\\\\" + sourceTemplate; /**目标文件基础路径*/ private static final String targetBasePath = disk + ":\\\\generateProject\\\\targetProject" + "\\\\" + artifactId; public static void main(String[] args) { MavenProjectGenerate mpg = new MavenProjectGenerate(); mpg.createProject(); } /** * 根据模板创建maven工程 */ public void createProject(){ makeDirectoryAndFileByRecursion(sourceBasePath); } /** * 递归方式根据源目录和文件创建目标目录和文件 * @param path */ private void makeDirectoryAndFileByRecursion (String path){ File[] fileAndDirs = getFileAndDirListFromSourceDir(path); if (null == fileAndDirs) { return; } for(File file : fileAndDirs){ if (file.isDirectory()) { String sourceAbsolutePath = file.getAbsolutePath(); String sourceFileName = null; String sourceDirPath = getReplacedSourceDirPath(sourceAbsolutePath, false, sourceFileName); String targetDirPath = getReplacedTargetDirPath(sourceAbsolutePath, sourceDirPath, sourceFileName, false); makeTargetDirectory(targetDirPath); makeDirectoryAndFileByRecursion(sourceDirPath); }else if(file.isFile()){ String sourceAbsolutePath = file.getAbsolutePath(); String sourceFileName = file.getName(); String sourceDirPath = getReplacedSourceDirPath(sourceAbsolutePath, true, sourceFileName); String targetDirPath = getReplacedTargetDirPath(sourceAbsolutePath, sourceDirPath, sourceFileName, true); String targetFileName = sourceFileName; makeDirectoryAndFile(sourceDirPath, sourceFileName, targetDirPath, targetFileName); } } } /** * 获取目标目录路径 * @param sourceAbsolutePath * @param sourceDirPath * @param sourceFileName * @param isFile * @return */ private String getReplacedTargetDirPath(String sourceAbsolutePath, String sourceDirPath, String sourceFileName, boolean isFile){ String targetDriPath = null; /**如果是文件*/ if (isFile) { /**如果是读取的是java文件,由于需要根据java文件第一行的包路径来得到最终路径,所以需要单独处理*/ if (isJavaFileDir(sourceDirPath)) { targetDriPath = replacedSourceDirPath(sourceDirPath) + "\\\\" + getPackageDir(sourceDirPath, sourceFileName); }else{/**如果是非java文件,则直接根据源路径进行替换后得到目标路径*/ targetDriPath = replacedSourceDirPath(sourceDirPath); } }else{/**如果是目录*/ targetDriPath = replacedSourceDirPath(sourceDirPath); } return targetDriPath; } /** * 判断此目录路径是否是java文件目录路径 * 引用注意:在正则表达式中的“\\\\”表示和后面紧跟着的那个字符构成一个转义字符(姑且先这样命名),代表着特殊的意义;所以如果你要在正则表达式中表示一个反斜杠\\,应当写成“\\\\\\\\” * @param sourceDirPath * @return */ private boolean isJavaFileDir(String sourceDirPath){ String regex = sourceBasePath1 + "\\\\\\\\(web|service|dao|rpc|domain|common|client|cache)\\\\\\\\src\\\\\\\\main\\\\\\\\java"; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(sourceDirPath); if (m.find()) { return true; } return false; } private String replacedSourceDirPath(String sourceDirPath){ String result = sourceDirPath .replace(sourceBasePath + "\\\\web", targetBasePath + "\\\\" + artifactId + "-web") .replace(sourceBasePath + "\\\\service", targetBasePath + "\\\\" + artifactId + "-service") .replace(sourceBasePath + "\\\\dao", targetBasePath + "\\\\" + artifactId + "-dao") .replace(sourceBasePath + "\\\\rpc", targetBasePath + "\\\\" + artifactId + "-rpc") .replace(sourceBasePath + "\\\\domain", targetBasePath + "\\\\" + artifactId + "-domain") .replace(sourceBasePath + "\\\\common", targetBasePath + "\\\\" + artifactId + "-common") .replace(sourceBasePath + "\\\\client", targetBasePath + "\\\\" + artifactId + "-client") .replace(sourceBasePath + "\\\\cache", targetBasePath + "\\\\" + artifactId + "-cache") .replace(sourceBasePath, targetBasePath); return result; } /** * 获取源目录路径 * @param sourceAbsolutePath * @param isFile * @param sourceFileName * @return */ private String getReplacedSourceDirPath(String sourceAbsolutePath, boolean isFile, String sourceFileName){ String sourceDirPath = null; if (isFile) { sourceDirPath = sourceAbsolutePath.replace("\\\\" + sourceFileName, ""); }else{ sourceDirPath = sourceAbsolutePath; } return sourceDirPath; } /** * 创建目录及文件 * @param sourceDirPath * @param sourceFileName * @param targetDirPath * @param targetFileName */ private void makeDirectoryAndFile(String sourceDirPath, String sourceFileName, String targetDirPath, String targetFileName){ String sourceContent = readContentFromSourceFile(sourceDirPath, sourceFileName); String newContent = getReplacedContent(sourceContent); if ("pom.xml".equals(sourceFileName)) { newContent = getReplacedJarVersion(newContent); } if (makeTargetDirectory(targetDirPath)) { if (makeTargetFile(targetDirPath, targetFileName)) { writeNewContentToTargetFile(targetDirPath, targetFileName, newContent); } } } /** * 根据java文件的第一行获取包路径 * @param sourceDirPath * @param sourceFileName * @return */ private String getPackageDir(String sourceDirPath, String sourceFileName){ String packageDir = null; File file = new File(sourceDirPath + "\\\\" + sourceFileName); BufferedReader br = null; try { br = new BufferedReader(new FileReader(file)); String firstLine = br.readLine(); packageDir = getReplacedContent(firstLine).replace(".", "\\\\").replace("package ", "").replace(";", ""); } catch (Exception e) { e.printStackTrace(); }finally{ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } return packageDir; } /** * 获取文件和目录列表 * @param sourceDirPath * @return */ private File[] getFileAndDirListFromSourceDir(String sourceDirPath){ File file = new File(sourceDirPath); File[] fileList = file.listFiles(); return fileList; } /** * 创建目录 * @param dirPath */ private boolean makeTargetDirectory(String dirPath){ try { File file =new File(dirPath); if (!file .exists() && !file.isDirectory()){ file .mkdirs(); System.out.println(dirPath); } } catch (Exception e) { log.error("dirPath:" + dirPath, e); return false; } return true; } /** * 创建文件 * @param dirPath * @param fileName */ private boolean makeTargetFile(String targetDirPath, String targetFileName){ try { File file = new File(targetDirPath + "\\\\" + targetFileName); if (!file.exists()) { file.createNewFile(); } } catch (IOException e) { log.error("targetDirPath:" + targetDirPath + ", targetFileName:" + targetFileName, e); return false; } return true; } private void writeNewContentToTargetFile(String targetDirPath, String targetFileName, String newContent){ FileWriter fw = null; try { fw = new FileWriter(targetDirPath + "\\\\" + targetFileName); fw.write(newContent); System.out.println(targetDirPath + "\\\\" + targetFileName); } catch (IOException e) { e.printStackTrace(); } finally{ try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 将文件中的占位符替换为需要的格式 * @param sourceContent * @return */ private String getReplacedContent(String sourceContent){ String result = sourceContent.replace("${groupId}", groupId).replace("${artifactId}", artifactId); // if ("sourceTemplate-client".equals(sourceTemplate)) { // result = result.replace("${server-groupId}", serverGroupId).replace("${server-artifactId}", serverArtifactId); // } return result; } /** * 如果是pom.xml文件的话就需要替换里面的jar版本号 * @param sourceContent * @return */ private String getReplacedJarVersion(String sourceContent){ String result = sourceContent; Set<Entry<String, String>> set = JarDependencyVersion.jarVersionMap.entrySet(); for(Entry<String, String> entry : set){ result = result.replace(entry.getKey(), entry.getValue()); } return result; } /** * 一次性读出文件中所有内容 * @param sourceDirPath * @param sourceFileName * @return */ private String readContentFromSourceFile(String sourceDirPath, String sourceFileName){ String encoding = "utf-8"; File file = new File(sourceDirPath + "\\\\" + sourceFileName); Long filelength = file.length(); byte[] filecontent = new byte[filelength.intValue()]; try { FileInputStream in = new FileInputStream(file); in.read(filecontent); in.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { return new String(filecontent, encoding); } catch (UnsupportedEncodingException e) { System.err.println("The OS does not support " + encoding); e.printStackTrace(); return null; } } }
package com.project.maven.generator; import java.util.HashMap; import java.util.Map; /** * 依赖jar包版本号管理类 * @author liujinfeng * */ public class JarDependencyVersion { public static Map<String, String> jarVersionMap = new HashMap<String, String>(); static{ jarVersionMap.put("${spring-webmvc}", "4.0.4.RELEASE"); jarVersionMap.put("${spring-jdbc}", "4.0.4.RELEASE"); jarVersionMap.put("${spring-context-support}", "4.0.4.RELEASE"); jarVersionMap.put("${spring-tx}", "4.0.4.RELEASE"); jarVersionMap.put("${mybatis-spring}", "1.2.0"); jarVersionMap.put("${mybatis}", "3.2.2"); jarVersionMap.put("${mysql-connector-java}", "5.0.8"); jarVersionMap.put("${commons-dbcp}", "1.4"); jarVersionMap.put("${cglib-nodep}", "2.1_3"); jarVersionMap.put("${javax.servlet-api}", "3.1.0"); jarVersionMap.put("${velocity}", "1.7"); jarVersionMap.put("${log4j}", "1.2.16"); jarVersionMap.put("${velocity-tools}", "2.0"); jarVersionMap.put("${org.codehaus.jackson}", "1.4.3"); jarVersionMap.put("${commons-pool}", "1.6"); jarVersionMap.put("${artifactId-parent}", "0.0.1-SNAPSHOT"); jarVersionMap.put("${artifactId-web}", "0.0.1.0-SNAPSHOT"); jarVersionMap.put("${artifactId-service}", "0.0.1.0-SNAPSHOT"); jarVersionMap.put("${artifactId-dao}", "0.0.1.0-SNAPSHOT"); jarVersionMap.put("${artifactId-rpc}", "0.0.1.0-SNAPSHOT"); jarVersionMap.put("${artifactId-common}", "0.0.1.0-SNAPSHOT"); jarVersionMap.put("${artifactId-domain}", "0.0.1.0-SNAPSHOT"); } }
模板文件及详细代码见:https://github.com/worldwalker77/studydemo.git
使用的时候将代码拷贝至E盘目录下,指定groupId 、artifactId 两个参数
private static final String groupId = "com.zhaogang.mpay";
private static final String artifactId = "mpay";
/**电脑盘符,文件路径*/
private static final String disk = "E";
下图是生成的项目框架结构,可以直接运行。
以上是关于java实现的一个maven多模块项目自动生成工具的主要内容,如果未能解决你的问题,请参考以下文章
Java:听说maven比ant方便多了?有多方便,能给我个大致的印象么