Springboot启动入口源码
默认是org.springframework.boot.loader.JarLauncher
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
</dependency>
启用SpringBoot的PropertiesLauncher
使用SpringBoot的PropertiesLauncher可以优先加载外部的jar文件, 这样可以在程序运行前替换jar包,
官方文档: Launching Executable Jars
使用演示
- 建立一个SpringBoot工程, 工程中依赖一个叫自定义的utils包, 版本是1.0.0, 通过http接口返回utils版本, 正常打包后访问, 返回1.0.0版本
@Slf4j
@RestController
public class HelloController {
@RequestMapping("/version")
public String version() {
String version = VersionUtil.getVersion();
log.info("请求version: " + version);
return VersionUtil.getVersion();
}
@RequestMapping("spi-version")
public Object spiVersion() {
ArrayList<String> objects = new ArrayList<>();
ServiceLoader<AgentInterface> load = ServiceLoader.load(AgentInterface.class);
for (AgentInterface registry : load) {
objects.add(registry.hello());
}
return objects;
}
@RequestMapping("/spring-res")
public Object springRes() throws IOException {
ArrayList<String> objects = new ArrayList<>();
PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
Resource[] resources = pathMatchingResourcePatternResolver.getResources("classpath*:META-INF/services/com.example.utils.AgentInterface");
for (Resource resource : resources) {
objects.add(resource.toString());
}
return objects;
}
}
- 在启用应用程序时通过
-Dloader.path=/libs
指定外部jar的目录, 再启动, 访问接口返回2.0.0版本, 说明包替换成功
指定PropertiesLauncher启动类执行
java -cp demo1-0.0.1-SNAPSHOT.jar org.springframework.boot.loader.PropertiesLauncher
java -cp demo1-0.0.1-SNAPSHOT.jar -Dloader.path=/Users/admin/.m2/repository/com/example/utils/2.0.0/ org.springframework.boot.loader.PropertiesLauncher
访问java spi
可以正常只加载2.0.0版本中的实现类, 这个符合预期
访问资源文件
访问资源文件, 会发现本应只从2.0.0版本中加载文件, 结果1.0.0版本中的也被加载了