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

我们知道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

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调用插件的机制没有详细研究

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值