build.gradlee stop 状态 怎么办

gradle构建web项目,启动和停止jetty容器
1.在build.gradle文件中添加jetty插件支持:apply plugin : 'jetty'
2.设置web访问参数:
& httpPort = 8080
& stopPort = 8089
& stopKey& = 'ss'
3.启动jetty:右击工程选择run as-》gradle build...,执行gradle
jettyRun或者jettyRunWar任务,即启动jetty服务
4.关闭jetty:右击工程选择run as-》gradle build...,执行gradle
jettyStop,不加任何设置,但是必须有第2步的stopKey的设置,即可关闭jetty。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。珍惜我所拥有的
阿男的最新日记
······
&(1人喜欢)
&(6人喜欢)
&(2人喜欢)
&(21人喜欢)
······
浪漫骑士,行吟诗人,自由思想家 · 1677条内容
蒌蒿满地芦芽短,正是河豚欲上时 · 417条内容
“你有什么要问我的吗?” · 590条内容
摘桑春陌上,踏草夕阳间 · 1309条内容
属于影迷的人间四月天 · 128条内容
共享单车的都市历险记 · 396条内容  本文来自于CSDN博客,作者:工匠若水,已获授权,版权归原作者所有,未经作者同意,请勿转载。
  欢迎同有博客好文章的作者加微信(ID:tm_forever_miss)或直接邮件()投稿、约稿、给文章纠错。
  上一篇我们分析了 Gradle 框架自身初始化(非构建生命周期初始化)的核心流程,这一篇我们续着前面的分析继续(如果没看过前一篇的建议先去看前一篇,因为这一系列存在非常高的关联性)。上一篇说到当我们执行 gradle taskName 命令后经过一系列艰难的框架初始化最终走到了 DefaultGradleLauncher 的 run() 方法,我们也发现这个 run() 方法里调用了 doBuild(Stage.Build),所以这一篇我们就从这里开始分析 Gradle 构建的生命周期核心委托对象创建的流程。
  构建生命周期宏观浅析
  我们在执行 gradle taskName 命令进行 Gradle 框架自身初始化以后会执行到 DefaultGradleLauncher 的 doBuild(Stage.Build) 方法,而该方法首先会触发构建的 buildListener.buildStarted(gradle) 回调通知构建开始,接着执行 doBuildStages(upTo),然后等待结束后包装触发构建的 buildListener.buildFinished(buildResult) 回调通知构建结束,所以我们重点关注下 doBuildStages(upTo) 方法,如下:
  //此时upTo参数值为枚举的Stage.Build
  private voiddoBuildStages(Stage upTo) {
  if(stage == Stage.Build) {
  //状态控制,避免多次状态build,第一次执行该方法时stage为null。thrownewIllegalStateException( "Cannot build with GradleLauncher multiple times"); }
  //第一次实例化调用该方法时stage=null,所以构建生命周期进入Load状态(初始化阶段)。if(stage == null) {
  // Evaluate init sinitHandler.executes(gradle);
  // Build `buildSrc`, load settings.gradle, and construct composite (if appropriate)settings = settingsLoader.findAndLoadSettings(gradle);
  //标记当前状态为Load状态(初始化阶段)。stage = Stage.L }
  if(upTo == Stage.Load) {
  return; }
  if(stage == Stage.Load) {
  //如果当前stage是Load状态(初始化阶段),则接着构建生命周期进入Configure状态(配置阶段)。// Configure buildbuildOperationExecutor.run( "Configure build", newConfigureBuildAction());
  //标记当前状态为Configure状态(配置阶段)。stage = Stage.C }
  if(upTo == Stage.Configure) {
  return; }
  //Load状态(初始化阶段)和Configure状态(配置阶段)完后进入Build状态(执行阶段)。// After this point, the GradleLauncher cannot be reusedstage = Stage.B
  // Populate task graphbuildOperationExecutor.run( "Calculate task graph", newCalculateTaskGraphAction());
  // Execute buildbuildOperationExecutor.run( "Run tasks", newRunTasksAction());}
  怎么样,是不是有点意思了,了解 Gradle 构建生命周期的同学看完上面这个方法基本就能发现 Gradle 构建的核心触发点都在这里了(不了解 Gradle 构建生命周期的同学请先移步《Gradle脚本基础全攻略》看看),到此基本就揭示了一个大多数人迷惑的疑问,那就是很多人都想知道自己每次执行 gradle taskName 命令后 Gradle 怎么就能进入构建生命周期,然后按着周期执行,因为当我们输入命令后首先会初始化 Gradle 构建框架自己,接着把命令行参数包装好送给 DefaultGradleLauncher,然后触发 DefaultGradleLauncher 中 Gradle 构建的真正生命周期,从此开始标准构建流程。
  关于 Gradle 构建生命周期描述更多细节可以查看官方文档的 The Build Lifecycle。
  构建生命周期委托对象浅析
  在Gradle 官方 DSL 文档的 Some basics 部分描述了编写 Gradle 脚本的灵魂说明,具体如下截图:
  也就是说围绕整个 Gradle 构建过程的核心是几个委托实例对象,既然这样那我们就去分别看看这三种对象是怎么创建的吧。
  Gradle 对象浅析
  首先对于 Gradle 对象的继承关系如下:
  public classDefaultGradle extends AbstractPluginAware implements GradleInternalpublic interface GradleInternal extends Gradlepublic interface Gradle extends PluginAware
  其实这个对象的创建时机我们前面基本已经接触过了,只是没有单独突出说明而已;该对象的创建时机就是 Gradle 框架自身初始化接近尾声创建 DefaultGradleLauncher 对象时,具体是在 DefaultGradleLauncherFactory 的 doNewInstance 方法中创建,如下:
  public classDefaultGradleLauncherFactory implements GradleLauncherFactory { ...... private DefaultGradleLauncher doNewInstance(StartParameter startParameter, GradleLauncher parent, BuildCancellationToken cancellationToken, BuildRequestMetaData requestMetaData, BuildEventConsumer buildEventConsumer, final BuildSessionScopeServices sessionScopeServices, List&?& servicesToStop) { BuildScopeServices serviceRegistry = BuildScopeServices.forSession(sessionScopeServices); ......
  //Gradle框架自身初始化OK以后第一次调用时parent为null。GradleInternal parentBuild = parent == null? null: parent.getGradle();
  //创建一个DefaultGradle对象,也就是Gradle的实现,其中最重要的参数就是startParameter,包含了我们执行gradle命令时携带的参数。GradleInternal gradle = serviceRegistry.get(Instantiator.class).newInstance(DefaultGradle.class, parentBuild, startParameter, serviceRegistry.get(ServiceRegistryFactory.class));
  //把实例化的Gradle对象传入DefaultGradleLauncher实例。DefaultGradleLauncher gradleLauncher = newDefaultGradleLauncher( gradle, ...... ); nestedBuildFactory.setParent(gradleLauncher);
  returngradleL } ......}
  上面就是我们说的 Gradle 实例创建时机,可见 Gradle 实例的实现其实是 DefaultGradle 对象,也就是Gradle 官方 DSL 文档的 Some basics中描述的 init 的委托对象 Gradle。由此在我们编写 Gradle 脚本时获取 Gradle 实例后进行的设置其实都是在对该对象进行设置咯,具体编写参考 Gradle 实例对象 DSL Reference和Gradle 对象 API 文档 或者框架源码。这没啥可说的,和写 Java 一样咯。
  Settings 对象浅析
  上面已经介绍了委托实例对象 Gradle 的创建时机,这里再来简单看看委托实例对象 Settings 的创建和作用;老规矩,先看下 Settings 对象的继承关系,如下:
  public classDefaultSettings extends AbstractPluginAware implements SettingsInternalpublic interface SettingsInternal extends Settingspublic interface Settings extends PluginAware
  纳尼?看起来和 Gradle 对象关系比较类似,其共同祖先都是 PluginAware 接口,先不管这些,我们先去看看他在哪创建的吧。
  在上面第二小节的构建生命周期宏观浅析中我们分析了执行 gradle taskName 命令进行 Gradle 框架自身初始化以后会执行到 DefaultGradleLauncher 的 doBuildStages(Stage upTo) 方法,该方法里有这么一行调用,如下:
  //初始化构建时第一次状态初始化会执行该行代码
  // Build `buildSrc`, load settings.gradle, and construct composite (if appropriate)
  settings = settingsLoader.findAndLoadSettings(gradle);
  这里的 settingsLoader 和 gradle 实例都是创建 DefaultGradleLauncher 实例时传入的,关于 gradle 前面已经分析了,settingsLoader 其实是在 DefaultGradleLauncherFactory 创建 DefaultGradleLauncher 实例前通过 settingsLoaderFactory.forTopLevelBuild() 创建的,也就是 DefaultSettingsLoaderFactory 中创建,如下:
  public classDefaultSettingsLoaderFactory implements SettingsLoaderFactory { ......
  //这里是调用Top Settings创建咯,还有个forNestedBuild创建的。@Override public SettingsLoader forTopLevelBuild() {
  //包装三层调用,实质先调用了DefaultSettingsLoader的findAndLoadSettings(gradle)方法returnnewNotifyingSettingsLoader(
  newCompositeBuildSettingsLoader(
  newDefaultSettingsLoader( settingsFinder, settingsProcessor, buildSourceBuilder ), buildServices ), buildLoader); } ......}
  得到 SettingsLoader 对象以后在 DefaultGradleLauncher 的 doBuildStages(Stage upTo) 方法中就创建了我们要说的 Settings 委托实例对象,至于创建的过程无非就是尝试依据命令行参数进行匹配查找譬如 settings.gradle 文件等(感兴趣的可以去看看 DefaultSettingsLoader 的 findAndLoadSettings 方法中的 findSettingsAndLoadIfAppropriate(gradle, startParameter); 调用实现)。
  可见 Settings 实例的实现其实是 DefaultSettings 对象,也就是 Gradle 官方 DSL 文档的 Some basics中描述的 settings 的委托对象 Settings。由此在我们编写 Gradle 脚本时获取 Settings 实例后进行的设置其实都是在对该对象进行设置咯,具体编写参考Settings 实例对象 DSL Reference 和 Settings 对象 API 文档或者框架源码。不过关于 Settings 委托对象的使用和核心说明除过看上面提到的官方文档以外,Settings.java 文件的注释也很言简意赅,如下:
  /** * &p&Declares the configuration required to instantiate and configure the hierarchy of {@link * org.gradle.api.Project} instances which are to participate in a build.&/p& * * &p&There is a one-to-one correspondence between a &code&Settings&/code& instance and a &code&{@value * #DEFAULT_SETTINGS_FILE}&/code& settings file. Before Gradle assembles the projects for a build, it creates a * &code&Settings&/code& instance and executes the settings file against it.&/p& * * &h3&Assembling a Multi-Project Build&/h3& * * &p&One of the purposes of the &code&Settings&/code& object is to allow you to declare the projects which are to be * included in the build. You add projects to the build using the {@link #include(String[])} method. There is always a * root project included in a build. It is added automatically when the &code&Settings&/code& object is created. The * root project's name defaults to the name of the directory containing the settings file. The root project's project * directory defaults to the directory containing the settings file.&/p& * * &p&When a project is included in the build, a {@link ProjectDeor} is created. You can use this deor to * change the default values for several properties of the project.&/p& * * &h3&Using Settings in a Settings File&/h3& * * &h4&Dynamic Properties&/h4& * * &p&In addition to the properties of this interface, the {@code Settings} object makes some additional read-only * properties available to the settings . This includes properties from the following sources:&/p& * * &ul& * * &li&Defined in the {@value org.gradle.api.Project#GRADLE_PROPERTIES} file located in the settings directory of the * build.&/li& * * &li&Defined the {@value org.gradle.api.Project#GRADLE_PROPERTIES} file located in the user's {@code .gradle} * directory.&/li& * * &li&Provided on the command-line using the -P option.&/li& * * &/ul& */
  Project 对象浅析
  上面已经介绍了委托实例对象 Gradle、Settings 的创建时机,这里再来简单看看委托实例对象 Project 的创建和作用;老规矩,先看下 Project 对象的继承关系,如下:
  public classDefaultProject extends AbstractPluginAware implements ProjectInternal, DynamicObjectAwarepublic interface ProjectInternal extends Project, ProjectIdentifier, FileOperations, ProcessOperations, DomainObjectContext, DependencyMetaDataProvider, ModelRegistryScope, PluginAwareInternalpublic interface Project extends Comparable&Project&, ExtensionAware, PluginAware
  纳尼?看起来继承关系略显复杂,但是还是挺直观的,先不管这些,我们从这里看出 Project 接口的实现实例是 DefaultProject 就行。关于这货在哪创建我想眼尖的人已经知道答案了,前面我们分析 Settings 对象时最后有段源码注释还记得么,如下(Settings.java):
  You add projects to the build using the {@link #include( String[])} method.When a project is included inthe build, a {@link ProjectDeor} is created. You can use thisdeor to change the defaultvalues forseveral properties of the project.
  通过这段注释可以发现,其实 Project 创建很有可能依赖于 ProjectDeor,而 ProjectDeor 又是我们在 settings.gradle 中添加的 module 工程。所以我们还是先把目光挪到上面分析 Settings 创建时的 settingsLoader.findAndLoadSettings(gradle);调用,可以发现 NotifyingSettingsLoader 的 findAndLoadSettings(GradleInternal gradle) 方法中调用了如下语句:
  public SettingsInternal findAndLoadSettings(GradleInternal gradle) { SettingsInternal settings = settingsLoader.findAndLoadSettings(gradle); ...... buildLoader.load(settings.getRootProject(), settings.getDefaultProject(), gradle, settings.getRootClassLoaderScope()); gradle.getBuildListenerBroadcaster().projectsLoaded(gradle);
  return }
  可以看见对应的一个 Settings 里关联的 ProjectDeor 都生成了对应的 Project 对象。可见 Project 实例的实现其实是 DefaultProject 对象(是 Settings 里面对应 ProjectDeor 进行转换生成),也就是 Gradle 官方 DSL 文档的 Some basics中描述的 build 的委托对象 Project。由此在我们编写 Gradle 脚本时获取对应不同的 Project 实例后进行的设置其实都是在对该对象进行设置咯,具体编写参考Project 实例对象 DSL Reference和Project 对象 API 文档或者框架源码。不过关于 Project 委托对象的使用和核心说明除过看上面提到的官方文档以外,Project.java 文件的注释也很言简意赅,值得推荐。
  抛开源码浅析回到常规脚本编写总结
  上面分析了一堆源码其实无非就是为了让我们编写脚本时能够做到胸有成竹,不至于被牵着鼻子配,所以有了上面的分析我们可以在我们各个 Gradle 脚本中加入类似如下 log 进行实例对象哈希码测试(不同 gradle 脚本 log 写法可能有出入),如下:
  println( "Gradle Object Test&&&&&&&& gradle="+gradle.hashCode()+ ", getGradle="+getGradle().hashCode());println( "Gradle Object Test&&&&&&&& project="+ this.hashCode());println( "Gradle Object Test&&&&&&&& settings="+settings.hashCode()+ ", getSettings="+getSettings().hashCode());
  经过测试我们会发现结果和我们源码分析完全一致,也就是说无论在哪个 Gradle 工程模块的脚本中打印 gradle 或者 getGradle() 对象的 hashCode 都是同一个对象,而一个 settings.gradle 一一对应一个 Settings 实例对象,一个 project module 的 build.gradle 一一对应一个 Project 对象。所以我们在编写 Gradle 脚本时要时刻铭记这个分析结论,因为记住这个结论对于我们 Gradle 脚本的编写和理解非常重要,很多人写不明白 Gradle 脚本的实质其实就是分不清哪个对象有啥 API,哪个 API 属于哪个层次的对象。
  趣闻:譬如想在 Gradle 修改整个项目工程的 buildDir 路径,有的人模棱两可认为修改 buildDir 属性可以加到任何的 build.gradle 文件即可,其实这样好吗?(加在 settings.gradle 可能会更好些)通过这篇分析相信你能明白本篇分析带来的好处。
  通过这个系列的这几篇分析我们渐渐的揭开了 Gradle 构建脚本的神秘之处,这一篇主要分析了构建过程中需要的几个核心委托对象是怎么创建的,关于创建的这些对象如何使用我建议还是看官方 API 文档比较直接,后面还会分析其他的,我们慢慢循序渐进吧,限于最近身体不太舒服,所以更新比较慢了。官方文档太多、看不过来,看来得长期战线慢慢看了,类似 Android 文档。
声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。

我要回帖

更多关于 build.gradle 的文章

 

随机推荐