前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >maven:通过自定义maven插件运行启动自定义应用服务

maven:通过自定义maven插件运行启动自定义应用服务

作者头像
10km
发布2019-05-25 21:30:13
9920
发布2019-05-25 21:30:13
举报
文章被收录于专栏:10km的专栏10km的专栏

版权声明:本文为博主原创文章,转载请注明源地址。 https://cloud.tencent.com/developer/article/1433523

我们知道tomcat可以通过maven启动,执行类似如下的命令,就可以启动一个tomcat服务了。

mvn tomcat7:run 参见 《maven 配置tomcat插件启动》

如果我们也想像tomcat一样,用maven直接启动自己的应用服务,应该怎么做呢?这就是我这两天在折腾的问题。实现这个想法,需要具体几个条件。

  1. 自定义maven插件 tomcat实现在maven启动,其实是通过执行 org.apache.tomcat.maven:tomcat7-maven-plugin插件来实现的,上面mvn tomcat7:run命令其实是插件的简写。 所以如果要实现自定义的应用服务用maven启动,就是要实现一个类似的插件,将自己的服务启动操作放在插件中执行,关于开发自定义插件的基本知识不是本文的重点。 注意:自定义插件的pom.xmlpackage类型应该定义为<packaging>maven-plugin</packaging>
  2. 发布到仓库 有了自定义插件,当然要把它发布到仓库(maven中央仓库,或自己的私服)才能被maven找到。这个部分不是本文重点,可以在网上找到很多的文章介绍如何发布插件。

自定义maven插件听上去是个好高大上的东西,其实并不复杂,只要继承org.apache.maven.plugin.AbstractMojo实现execute抽象方法,就完成了一个最简单的插件。

以下是我的项目中用到的启动自定义服务的一个简单插件实现,其中的Main类是服务入口:

RunMojo.java

代码语言:javascript
复制
import org.apache.maven.plugin.AbstractMojo;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import net.gdface.facelog.service.Main;

/**
 * maven 插件<br>
 * 执行facelog服务启动,等同于命令行执行{@link Main#main(String[])}
 * 
 * @author guyadong
 *
 */
@Mojo(name = "run", requiresProject = false)
public class RunMojo extends AbstractMojo {
    /**
     * Set this to true to allow Maven to continue to execute after invoking the
     * run goal.
     *
     */
    @Parameter(property = "maven.facelog.fork", defaultValue = "false")
    private boolean fork;

    public RunMojo() {
    }

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        // 调用应用服务入口方法启动服务
        Main.main(null);
        if (!fork) {
            waitIndefinitely();
        }
    }

    /**
     * Causes the current thread to wait indefinitely. This method does not
     * return.
     */
    private void waitIndefinitely() {
        Object lock = new Object();

        synchronized (lock) {
            try {
                lock.wait();
            } catch (InterruptedException e) {
                getLog().warn("RunMojo.interrupted", e);
            }
        }
    }
}

上面这个插件非常简单,只定义一个有默认值的fork参数,只是简单的调用了Main.main()方法去启动服务。但作为一个启动服务的插件,在写法上还是与普通插件有些不同:

  1. 请注意在类的注释中有requiresProject = false,是指该插件可以不依赖特定项目运行,简单的说就是不需要在maven 项目的文件夹下执行,可以在任何位置执行。因为我们会在非开发环境使用该插件来启动服务所以这里必须指定为false
  2. 上面的代码中在调用了main方法启动服务后,还调用了waitIndefinitely方法故意让当前线程进行无限等待。因为一般来说,应用服务都是异步启动的,服务启动后主线程调用就直接返回了,会导致主线程execute方法会立即返回,maven调用结束,服务也就自动结束啦!所以这里要用waitIndefinitely方法阻止主线程结束。

tomcat插件也是这么干的,waitIndefinitely方法的代码就是从tomcat7-maven-plugin插件的源码中直接抄过来的。 为什么主线程结束后,maven会不等服务线程结束就结束插件运行我也没搞明白,这应该涉及到mave调用插件的机制没有详细研究

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年01月17日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档