Что такое layered JAR в Spring Boot и как его использовать с Docker?
Layered JAR — это механизм Spring Boot (начиная с версии 2.3), разделяющий JAR-файл на логические слои для оптимизации кэширования Docker-образов при пересборке.
Обычный JAR при каждом изменении кода полностью пересобирается, и Docker не может использовать кэш для зависимостей. Layered JAR разделяет содержимое на слои:
dependencies— внешние зависимости (меняются редко)spring-boot-loader— загрузчик Spring Boot (почти никогда не меняется)snapshot-dependencies— SNAPSHOT-зависимости (меняются чаще)application— код приложения (меняется при каждой сборке)
Dockerfile с layered JAR
Пример кода
# Стадия сборки
FROM maven:3.9-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn package -DskipTests -B
# Стадия извлечения слоёв
FROM eclipse-temurin:17-jre-alpine AS layers
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
RUN java -Djarmode=layertools -jar app.jar extract
# Финальная стадия
FROM eclipse-temurin:17-jre-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
# Копируем слои по отдельности (от редко меняющихся к часто меняющимся)
COPY --from=layers /app/dependencies/ ./
COPY --from=layers /app/spring-boot-loader/ ./
COPY --from=layers /app/snapshot-dependencies/ ./
COPY --from=layers /app/application/ ./
RUN chown -R appuser:appgroup /app
USER appuser
EXPOSE 8080
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]
Преимущество
При изменении только кода приложения Docker пересобирает лишь последний слой (application), а остальные три берутся из кэша. Это значительно ускоряет пересборку образа.
Включение в pom.xml
Для Spring Boot 2.3+ (в Spring Boot 3.x включён по умолчанию):
Пример
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>
<enabled>true</enabled>
</layers>
</configuration>
</plugin>
На собеседовании: layered JAR — это продвинутая оптимизация Docker-сборки для Spring Boot. Объясните проблему: обычный COPY jar пересобирает один большой слой при каждом изменении кода, включая неизменившиеся зависимости. Layered JAR решает это, разделяя JAR на 4 слоя по частоте изменений. Знание этого механизма показывает глубокое понимание Docker + Spring Boot.