(1)使用 spring run .\hello.groovy -- --server.port=9000 时报错
注意下图中的最后一句话:
Could not transfer artifact org.springframework.boot:spring-boot-starter:pom:2.1.6.RELEASE from/to central (https://repo.maven.apache.org/maven2/): Connect to repo.maven.apache.org:443 timed out
这说明无法从 https://repo.maven.apache.org/maven2/ 拉取 jar 包,但是我明明在 conf\settting.xml 中配置了 maven 的 aliyun 的远程仓库镜像,为什么还是要从 https://repo.maven.apache.org/maven2/ 这个地方拉取呢?
通过下载 SpringBoot-Cli 的源码以及查看 org.springframework.boot.cli.compiler.maven.MavenSettingsReader 的 loadSetttings 方法可以得知 SprintBoot-Cli 在加载 maven 配置的时候默认是从 ${user.home}/.m2/setting.xml 这个位置加载(我本身的maven路径放在了 D 盘,当然配置文件也就是在 D:\maven\...\conf\setting.xml 中),因此我将 conf\setting.xml 文件复制到 ${user.home}/.m2/setting.xml 即可解决拉取不到 jar 包的问题。
(2) 使用 spring init 时报错,如下图所示:
从上面的报错可以看到:无法连接到 https://start.spring.io(顺便说一句,spring init 的逻辑就是访问 https://start.spring.io 并得到结果返回回来,而访问 https://start.spring.io 可以方便的建立一个空的 SpringBoot 项目),但是在浏览器中就可以直接访问该网址,于是自然而然想到是不是 SpringBoot-Cli 里面没有使用到代理的原因?
查看 SpringBoot-Cli 的源码:org.springframework.boot.cli.command.init.InitializrService 可以看到上图中的报错就是从下图这段开始的,
于是一路跟踪下去:
从上图中可以看到 SpringBoot-Cli 使用的是 org.apache.http.impl.client.HttpClientBuilder 的 build 方法得到 CloseableHttpClient 来访问 https://start.spring.io 的,而 HttpClientBuilder 又提供了 http.proxyHost,http.proxyPort,https.proxyHost,https.proxyPort 等参数来设定代理,因此只需要在 spring init 执行的时候传入这些参数就可以使用代理来访问 https://start.spring.io 了。
那么 spring init 是怎么运行的呢?
其实是使用 spring-boot-cli-2.1.6.RELEASE\spring-2.1.6.RELEASE\bin 目录下的 spring.bat 来执行的,因此打开 spring.bat 可以看到:所有的命令执行都是通过下面这个语句来执行的,里面就是我们熟悉的平时控制台下运行 java 程序的指令,因此可以在这个地方添加我们需要传入的参数,那么 spring init 执行的时候就自然而然的会使用代理了。因此加入 -Dhttps.proxyHost=xx.xx.xx.xx -Dhttps.proxyPort=xxxx (当然也可以传入针对 http 请求的代理,这里设置的是 https 请求的代理)后 spring init 就可以正常运行了。