当前位置:首页 > 科技  > 软件

现学现用,写个Maven插件用下

来源: 责编: 时间:2024-01-15 09:19:39 323观看
导读Maven 插件实践上一次简单介绍了如何编写一个Maven插件,并且如何将插件的执行与Maven生命周期绑定,这样通过调用maven生命周期方法时,则会在配置的阶段按照插件的目标来执行代码。今天通过一个具体的插件来熟悉在项目中

Maven 插件实践

上一次简单介绍了如何编写一个Maven插件,并且如何将插件的执行与Maven生命周期绑定,这样通过调用maven生命周期方法时,则会在配置的阶段按照插件的目标来执行代码。MXa28资讯网——每日最新资讯28at.com

今天通过一个具体的插件来熟悉在项目中的使用。MXa28资讯网——每日最新资讯28at.com

一般公司的项目结构或者代码结构都是非常固定的,有一些框架针对这种固化的代码结构或约定的规范,在开发前会严格对项目进行模块划分,对各个模块的代码结构也会严格要求。那么我们则可以根据这种约定的规范,通过工具来自动化的生成代码,从而减少开发人员的工作量。MXa28资讯网——每日最新资讯28at.com

示例项目

比如我们的项目一般都会由多个模块组成,比如下面的示例:MXa28资讯网——每日最新资讯28at.com

DMP    ├ system    │ ├ account    │   ├ entity    │   ├ dao    │   └ service    │   └ web    │ ├ role    │   ├ ...    │ ├ permission    │   ├ ...        │ └ pom.xml    ├ monitor    │ ├ database    │   ├ ...    │ ├ disk    │   ├ ...    │ ├ memory    │   ├ ...        │ └ pom.xml    └ pom.xml

在上面的例子中,我们项目包括了system、monitor等多个模块,其中system模块包含了account、role、permission三个子模块, monitor模块包含了database、disk、memory三个子模块,每个子模块又包含了特定的代码结构. 这个属于我们约定的模块划分规则,那么基于这样的规则,我们完全可以通过开发一个插件来自动生成这种约定结构的空项目。MXa28资讯网——每日最新资讯28at.com

实现步骤

假设插件名称为 `module-create-maven-plugin`,将来我们会通过该插件实现
项目模块文件夹和一些通用文件的自动生成。插件大概配置如下:
<build>   <plugins>      <plugin>         <groupId>com.sucls.blog.plugin</groupId>         <artifactId>module-create-plugin</artifactId>         <version>1.0.0</version>         <configuration>            <basedir>E://_projects//demo//DMP</basedir>            <modules>               <module>system/account</module>               <module>system/role</module>               <module>monitor/databse</module>               <module>monitor/disk</module>               <module>monitor/memory</module>            </modules>         </configuration>      </plugin>   </plugins></build>

根据我们预期要求,来设想插件的开发过程。MXa28资讯网——每日最新资讯28at.com

定义一个maven插件项目

创建一个maven插件项目,在pom.xml中添加如下配置:MXa28资讯网——每日最新资讯28at.com

<?xml version="1.0" encoding="UTF-8"?><project 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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>com.sucls.blog.plugin</groupId>    <artifactId>module-create-plugin</artifactId>    <version>1.0.0</version>    <packaging>maven-plugin</packaging>    <dependencies>        <dependency>            <groupId>org.apache.maven</groupId>            <artifactId>maven-plugin-api</artifactId>            <version>3.8.1</version>        </dependency>        <dependency>            <groupId>org.apache.maven</groupId>            <artifactId>maven-core</artifactId>            <version>3.8.1</version>        </dependency>        <dependency>            <groupId>org.apache.maven.plugin-tools</groupId>            <artifactId>maven-plugin-annotations</artifactId>            <version>3.8.1</version>            <scope>provided</scope>        </dependency>        <dependency>            <groupId>org.freemarker</groupId>            <artifactId>freemarker</artifactId>            <version>2.3.32</version>        </dependency>    </dependencies></project>

创建一个Mojo根据配置添加实现逻辑

goal的名字设计成modules,由于最终项目是基于maven构建,所以会生成pom.xml,插件中的几个参数就是为了生成pom而设计MXa28资讯网——每日最新资讯28at.com

@Mojo(name = "run")public class ModulesCreatePlugin extends AbstractMojo {    @Parameter(property = "basedir",defaultValue = "${project.basedir}")    private String basedir;    @Parameter    private String project;    @Parameter(property = "groupId",defaultValue = "${project.groupId}")    private String groupId;    @Parameter(property = "artifactId",defaultValue = "${project.artifactId}")    private String artifactId;    @Parameter(property = "version",defaultValue = "${project.version}")    private String version;    @Parameter    private List<String> modules;    private ModuleTemplateHelper moduleTemplateHelper;    public ModulesCreatePlugin(){        init();    }    public void init(){        moduleTemplateHelper = new ModuleTemplateHelper();    }    @Override    public void execute() throws MojoExecutionException, MojoFailureException {        Log log = getLog();        log.info(StringUtils.repeat("=",50));        log.info(modules.toString());        createModules();        log.info(StringUtils.repeat("=",50));    }    private void createModules() {        if(modules != null && modules.size() >0){            List<File> moduleFiles = new ArrayList<>();            modules.forEach(module -> {                // 创建目录                File path = new File(basedir,module);                path.mkdirs();                moduleFiles.add(path);            });            Set<String> parentModules = new HashSet<>();            // 添加pom.xml            for (File module : moduleFiles) {                File parent = module.getParentFile();                parentModules.add(parent.getName());                // 上级pom                if( !new File(parent,"pom.xml").exists() ){                    moduleTemplateHelper.process("pom.ftl", new ModuleEntity(groupId,project,version, parent.getName()),parent.getAbsolutePath()+"/pom.xml");                }                // 追缴module                XmlUtils.appendModule(new File(parent,"pom.xml"), module.getName());                // 模块pom                moduleTemplateHelper.process("jar.ftl", new ModuleEntity(groupId,parent.getName(),version,module.getName()),module.getAbsolutePath()+"/pom.xml");                new File(module,"src/main/java").mkdirs();                new File(module,"src/main/resources").mkdirs();            }            // 项目pom.xml追加module            if(new File(basedir,"pom.xml").exists()){                for (String parentModule : parentModules) {                    XmlUtils.appendModule(new File(basedir,"pom.xml"), parentModule);                }            }        }    }}

上面我们通过ModuleTemplateHelper辅助类结合freemaker框架,最后为各个模块生成对应的pom.xml文件;通过自定义的XmlUtils工具类结合JDK Documentation API,实现父级模块中modules节点的添加子module;MXa28资讯网——每日最新资讯28at.com

public class ModuleTemplateHelper {    private Configuration configuration;    public ModuleTemplateHelper() throws IOException {        configuration = new Configuration(Configuration.VERSION_2_3_22);        configuration.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "/templates"));        configuration.setDefaultEncoding("UTF-8");    }    public void process(String tpl, Object module, String outputPath){        Template template = configuration.getTemplate(tpl);        template.process(module, new FileWriter(outputPath));    }}
public class XmlUtils {    static DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();    static TransformerFactory transformerFactory = TransformerFactory.newInstance();    static DocumentBuilder documentBuilder;    static {        try {            documentBuilder = documentBuilderFactory.newDocumentBuilder();        } catch (ParserConfigurationException e) {            throw new RuntimeException(e);        }    }        /**     *     * @param pomXmlPath     * @param moduleName     */    public static void appendModule(File pomXml, String moduleName) {        try {            Document document = documentBuilder.parse(pomXml);            NodeList modules = document.getElementsByTagName("modules");            Node modulesNode = null;            if( modules.getLength()>0 ){                modulesNode = modules.item(0);            }            if( modulesNode == null ){                modulesNode = document.createElement("modules");                document.appendChild(modulesNode);            }            // 追加            Element module = document.createElement("module");            module.setTextContent(moduleName);            modulesNode.appendChild(module);            // 保存            transformerFactory.newTransformer().transform(new DOMSource(document), new StreamResult(pomXml));        } catch (Exception e) {            throw new RuntimeException(e);        }    }}

生成插件

执行下面的命令即可生成插件jar,并安装到本地仓库MXa28资讯网——每日最新资讯28at.com

mvn clean package

在项目中调用插件

在项目中引入插件,并且按照需要的模块添加配置,最后在IDEA右侧则可以看到该插件,双击运行,最终项目结构如下图:MXa28资讯网——每日最新资讯28at.com

结束语

很多技术本身不复杂,合理使用与加工则可以将我们平时工作中重复相似的工作内容进行简化,很多自动化工具亦是如此,只不过这些工作由别人完成了。通过今天的示例,主要了解如何将学到的知识具体化到工作中。MXa28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-60918-0.html现学现用,写个Maven插件用下

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Android应用开发简单几步实现摇一摇功能

下一篇: 如何使用FluentResults优雅地处理结果和错误

标签:
  • 热门焦点
  • JavaScript 混淆及反混淆代码工具

    介绍在我们开始学习反混淆之前,我们首先要了解一下代码混淆。如果不了解代码是如何混淆的,我们可能无法成功对代码进行反混淆,尤其是使用自定义混淆器对其进行混淆时。什么是混
  • 摸鱼心法第一章——和配置文件说拜拜

    为了能摸鱼我们团队做了容器化,但是带来的问题是服务配置文件很麻烦,然后大家在群里进行了“亲切友好”的沟通图片图片图片图片对比就对比,简单对比下独立配置中心和k8s作为配
  • CSS单标签实现转转logo

    转转品牌升级后更新了全新的Logo,今天我们用纯CSS来实现转转的新Logo,为了有一定的挑战性,这里我们只使用一个标签实现,将最大化的使用CSS能力完成Logo的绘制与动画效果。新logo
  • Golang 中的 io 包详解:组合接口

    io.ReadWriter// ReadWriter is the interface that groups the basic Read and Write methods.type ReadWriter interface { Reader Writer}是对Reader和Writer接口的组合,
  • 雅柏威士忌多款单品价格大跌,泥煤顶流也不香了?

    来源 | 烈酒商业观察编 | 肖海林今年以来,威士忌市场开始出现了降温迹象,越来越多不断暴涨的网红威士忌也开始悄然回归市场理性。近日,LVMH集团旗下苏格兰威士忌品牌雅柏(Ardbeg
  • “又被陈思诚骗了”

    作者|张思齐 出品|众面(ID:ZhongMian_ZM)如今的国产悬疑电影,成了陈思诚的天下。最近大爆电影《消失的她》票房突破30亿断层夺魁暑期档,陈思诚再度风头无两。你可以说陈思诚的
  • 签约井川里予、何丹彤,单视频点赞近千万,MCN黑马永恒文希快速崛起!

    来源:视听观察永恒文希传媒作为一家MCN公司,说起它的名字来,可能大家会觉得有点儿陌生,但是说出来下面一串的名字之后,或许大家就会感到震惊,原来这么多网红,都签约这家公司了。根
  • 华为将推出盘古数字人大模型 可帮助用户12小时完成数字人生成

    在今日举行的2023年华为云数字文娱AI创新峰会上,华为云全球Marketing与销售服务总裁石冀琳表示,华为云将在后续推出盘古数字人大模型,可帮助用户12小
  • 到手价3099元起!iQOO Neo8 Pro今日首销:安卓性能最强旗舰

    5月23日,iQOO如期举行了新品发布会,全新的iQOO Neo8系列也正式与大家见面,包含iQOO Neo8和iQOO Neo8 Pro两个版本,其中标准版搭载高通骁龙8+,而Pro版更
Top