【问题标题】:Customize the way the spring-initializr works?自定义 spring-initializr 的工作方式?
【发布时间】:2017-09-11 03:27:41
【问题描述】:

作为一家企业,我们希望在我们的 PCF 实例上内部托管 initializr,我可以这样做。我还能够修改 application.yml 以默认某些选择。

我通过简单地创建自己的 spring-boot 应用程序来做到这一点,该应用程序使用 io.spring.initializr:initializr-web:0.3.0.RELEASE 作为运行时依赖项。

我有两个主要问题:

  1. UI 上有没有办法默认选择某些 UI 首次出现时的依赖项(即预选 Web & 例如安全性)?
  2. 我可以自定义生成的输出吗?例如我们有 我们自己的 Gradle 自定义发行版,并希望生成 build.gradle 文件看起来与 initializr 有点不同 生成。我们还想生成一个 gradle.properties 文件 项目的一部分。

【问题讨论】:

    标签: spring spring-boot


    【解决方案1】:

    我已经为我们的内部使用做了很多这样的事情,并将在明天 gr8conf 的一次演讲中展示这些内容。

    放入自定义文件并添加默认选择非常简单,并且需要一些修改 java、css 和 html 的知识。您可以在此处获取我为演示此所做的工作的源代码:https://github.com/Grails-Plugin-Consortium/initializr/tree/master

    需要更改的代码很长,因此了解我必须完成的工作的最简单方法是通过添加“默认”选择和应用配置文件来链接差异。

    https://github.com/Grails-Plugin-Consortium/initializr/commit/feae678fdd4503c2314635cebdaabc04b4d80ace

    添加自定义文件以添加到生成的应用程序中稍微容易一些,只需要您将文件添加到 initializr-generator 中的模板,然后在 ProjectGenerator.java 中添加一个链接以复制文件,类似于现有代码的复制方式已经实现了。

    protected void generateDockerFile(File dir, Map<String, Object> model){
        write(new File(dir, "Dockerfile"), "Dockerfile", model);
        write(new File(dir, "docker.sh"), "docker.sh", model);
        write(new File(dir, "docker-run.sh"), "docker-run.sh", model);
    }
    

    上面添加到ProjectGenerator中的方法会添加下面存储在initializr/initializr-generator/src/main/resources/templates/中的文件

    所有繁重的工作都在这个文件中:https://github.com/Grails-Plugin-Consortium/initializr/blob/9b302d31bb069c9c702f36ed765ad3f55debff84/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectGenerator.java

    【讨论】:

    • 为了这个问题,我尽可能地增加了清晰度。但是,没有“简单”的方法来解决原始发帖人的问题。我的分叉存储库需要几个小时的工作才能完成一些“增强”初始化的项目。我们在工作中进一步提升了这几个层次,并投入了数周的工作来调整 Initializr 以完成一系列简洁的工作。你只需要卷起袖子潜入代码中。
    【解决方案2】:

    有一个参考指南walk you through the creation of your own instance。关于您的主要问题:

    是的,这在自定义实例中是可能的。实现 ProjectRequestPostProcessor 并将这两个依赖项添加到项目中。

    @Component
    class PreselectedDependenciesRequestPostProcessor implements ProjectRequestPostProcessor {
    
        private final InitializrMetadataProvider metadataProvider;
    
        public PreselectedDependenciesRequestPostProcessor(
                InitializrMetadataProvider metadataProvider) {
            this.metadataProvider = metadataProvider;
        }
    
        @Override
        public void postProcessAfterResolution(ProjectRequest request,
                InitializrMetadata metadata) {
            DependenciesCapability dependencies = metadataProvider.get().getDependencies();
            if (!hasDependencies(request, "web")) {
                request.getResolvedDependencies().add(dependencies.get("web"));
            }
            if (!hasDependencies(request, "security")) {
                request.getResolvedDependencies().add(dependencies.get("security"));
            }
        }
    
        private boolean hasDependencies(ProjectRequest request, String... dependenciesId) {
            for (String id : dependenciesId) {
                if (getDependency(request, id) == null) {
                    return false;
                }
            }
            return true;
        }
    
        private Dependency getDependency(ProjectRequest request, String id) {
            return request.getResolvedDependencies().stream()
                    .filter(d -> id.equals(d.getId())).findFirst().orElse(null);
        }
    }
    

    它们不会在 UI 中被选中,但它们会以与用户选择它们相同的方式集成到项目中。我推荐这种方法的原因是您的自定义实例可以像主 (start.spring.io) 实例一样被 IDE 集成定位。破解 Web UI 只会让这个特定的客户端工作,这在 IMO 是一个问题。

    对于第二个问题,大多数 fork 都从 ProjectGenerator 扩展而来,并为所欲为(包括覆盖 gradle 构建)。查看该类以获取更多详细信息。

    Spring Initializr 还没有达到 1.0,所以它还没有处于合约足够成熟的状态。

    【讨论】:

    • 感谢@stephane-nicoll。在过去的一年里,我们的定制 Initializr 已经成熟了很多。我们已经升级到 0.5.0 版,并且有许多自定义模板,并且我们确实覆盖了您提到的 ProjectGenerator
    猜你喜欢
    • 1970-01-01
    • 2016-05-04
    • 2020-06-10
    • 1970-01-01
    • 2017-02-23
    • 2020-08-09
    • 1970-01-01
    • 2012-07-05
    • 1970-01-01
    相关资源
    最近更新 更多