jar 파일은 jar를 포함할 수 없다. 따라서 라이브러리에 들어있는 jar를 풀어 나오는 class를 새롭게 jar로 만들도록 한다. (= fat jar)
//Fat Jar 생성
task buildFatJar(type: Jar) {
manifest {
attributes 'Main-Class': 'hello.embed.EmbedTomcatSpringMain'
}
duplicatesStrategy = DuplicatesStrategy.WARN
from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
위와 같이 라이브러리 클래스를 다 가져와 jar 파일로 만든다. 하지만 war의 외장 톰캣에 비해 장점이 존재하지만, 단점도 존재한다.
@SpringBootApplication
public class BootApplication {
public static void main(String[] args) {
SpringApplication.run(BootApplication.class, args);
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
@SpringBootApplication
어노테이션 내에서는 componentScan이 존재해, 해당 클래스가 존재하는 패키지 하위가 컴포넌트 스캔 대상이 되도록 한다. ./gradlew clean build
로 jar 파일을 만든 후, jar -xvf boot-0.0.1-SNAPSHOT
jar 파일을 열어보면 아래와 같은 구조를 가진다. (모두 class로 가지는 fat jar와는 다르다)
자바 표준이 아닌 스프링부트에서 정의한 Executable Jar
는 (1)어떤 라이브러리가 포함되어 있는지 쉽게 확인할 수 있고, (2) 폴더 구조이므로 파일명 중복을 해결하게 해준다.
MANIFEST.MF 에서 실행 정보를 받아온다.