참고
WAR 배포 방식의 단점
NOTE
WAR배포 방식은 너무나 복잡했다 단순히 main()을 실행하면 서버가 실행되는 방식은 없는가?
JAR은 main()을 통해 동작한다 (톰캣을 라이브러리(내장 톰캣)로 사용함!)
//내장 톰켓 추가
implementation 'org.apache.tomcat.embed:tomcat-embed-core:10.1.5'
Java
복사
내장 톰캣 실제로 사용해보기
NOTE
public class EmbedTomcatServletMain {
public static void main(String[] args) throws LifecycleException {
System.out.println("EmbedTomcatServletMain.main");
// tomcat setting
Tomcat tomcat = new Tomcat();
Connector connector = new Connector();
connector.setPort(8080);
tomcat.setConnector(connector);
// Servlet add
Context context = tomcat.addContext("", "/");
// 예와발생시 코드추가
File docBaseFile = new File(context.getDocBase());
if (!docBaseFile.isAbsolute()) {
docBaseFile = new File(((org.apache.catalina.Host) context.getParent()).getAppBaseFile(), docBaseFile.getPath());
}
docBaseFile.mkdirs();
// 코드추가 끝
tomcat.addServlet("", "helloServlet", new HelloServlet());
context.addServletMappingDecoded("/hello-servlet", "helloServlet");
tomcat.start();
}
}
Java
복사
서블렛 등록 (코드는 참고만해라, 내장 톰캣을 실제로 다룰일이 거의없다.)
public class EmbedTomcatSpringMain {
public static void main(String[] args) throws LifecycleException {
System.out.println("EmbedTomcatServletMain.main");
// tomcat setting
Tomcat tomcat = new Tomcat();
Connector connector = new Connector();
connector.setPort(8080);
tomcat.setConnector(connector);
// 스프링 컨테이너 생성
AnnotationConfigWebApplicationContext appContext = new
AnnotationConfigWebApplicationContext();
appContext.register(HelloConfig.class);
// 스프링 MVC 디스패쳐 서블릿 생성, 스프링 컨테이너 연결
DispatcherServlet dispatcher = new DispatcherServlet(appContext);
// 디스패쳐 서블릿 등록
Context context = tomcat.addContext("", "/");
tomcat.addServlet("", "dispatcher", dispatcher);
context.addServletMappingDecoded("/", "dispatcher");
tomcat.start();
}
}
Java
복사
스프링 등록
빌드와 배포 (jar, fat-jar)
NOTE
내장 톰캣은 어떻게 빌드하고 배포하는가?
Manifest-Version: 1.0
Main-Class: hello.embed.EmbedTomcatSpringMain
Groovy
복사
META-INF/MANIFEST.MF (main 메서드의 클래스 지정)
일반 JAR
//일반 Jar 생성
task buildJar(type: Jar) {
manifest {
attributes 'Main-Class': 'hello.embed.EmbedTomcatSpringMain'
}
with jar
}
Groovy
복사
위의 파일을 만드는 gradle 코드
# 압축해제 코드 (./build/libs로 먼저 이동)
jar -xvf embed-0.0.1-SNAPSHOT.jar
Bash
복사
파일 생성됨
압축파일 내용 (WAR과 비교해서 lib폴더가 없다)
•
./gradlew clean buildJar 를 입력하면 위의 코드가 실행된다. (에러발생)
•
lib 폴더가 없기 떄문에 스프링 라이브러리나, 톰캣 내장 라이브러리가 없으므로 에러가 발생한다.
•
JAR은 WAR과 다르게 내부에 라이브러리 역할을 하는 파일을 포함할 수 없다.
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
}
Groovy
복사
Jar안에는 라이브러리가 없지만 클래스는 포함이 가능하다. (라이브러리의 class를 모두 넣는다.)
# 압축해제 코드 (./build/libs로 먼저 이동)
jar -xvf embed-0.0.1-SNAPSHOT.jar
Bash
복사
폴더를 열면 수많은 파일들이 나온다.
•
이제 build는 되는데, 아직 단점들이 많다.
•
모든 클래스를 압축해제해서 어떤 라이브러리를 쓰는지 알기 힘들며, 파일명 중복을 해결할 수 없다.
편리한 스프링부트 클래스 만들기
NOTE
@MySpringBootApplication
public class MySpringBootMain {
public static void main(String[] args) {
MySpringApplication.run(MySpringBootMain.class, args);
}
}
Java
복사
Springboot의 main
public class MySpringApplication {
public static void run(Class ConfigClass, String[] args) {
System.out.println("MySpringApplication.main args=" + List.of(args));
// tomcat setting
Tomcat tomcat = new Tomcat();
Connector connector = new Connector();
connector.setPort(8080);
tomcat.setConnector(connector);
// 스프링 컨테이너 생성
AnnotationConfigWebApplicationContext appContext = new
AnnotationConfigWebApplicationContext();
appContext.register(HelloConfig.class);
// 스프링 MVC 디스패쳐 서블릿 생성, 스프링 컨테이너 연결
DispatcherServlet dispatcher = new DispatcherServlet(appContext);
// 디스패쳐 서블릿 등록
Context context = tomcat.addContext("", "/");
tomcat.addServlet("", "dispatcher", dispatcher);
context.addServletMappingDecoded("/", "dispatcher");
try {
tomcat.start();
} catch (LifecycleException e) {
throw new RuntimeException(e);
}
}
}
Java
복사
내장 톰캣, 스프링 등록을 처리
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ComponentScan
public @interface MySpringBootApplication {
}
Java
복사
컴포넌트 스캔 동작
스프링 부트와 웹 서버
NOTE
@SpringBootApplication
public class BootApplication {
public static void main(String[] args) {
SpringApplication.run(BootApplication.class, args);
}
}
Java
복사
스프링 부트 main
•
단순해 보이는 저 코드 한줄에는 수 많은 일들이 발생하지만 핵심은 2가지다.
1.
스프링 컨테이너를 생성한다.
2.
WAS(내장 톰캣)을 생성한다.
빌드와 배포, executable jar(실행가능한 jar)
# 빌드
./gradlew clean build
# 실행 (Fat JAR보다 압도적으로 용량이 가벼움)
java -jar boot-0.0.1-SNAPSHOT.jar
# 압축해제
jar -xvf boot-0.0.1-SNAPSHOT.jar
Bash
복사
plain은 신경쓰지 않아도된다.
압축해제 - lib가 존재한다 (왜?)
Fat-Jar가 아니라 새로운 구조로 만들어짐.
•
스프링부트가 Fat-jar 문제를 해결하기 위해 특별한 구조의 jar을 만들었으며 이 구조를 실행 가능한 Jar이라고 한다.
•
동시에 이러한 jar를 내부 jar를 포함해서 실행할 수 있게한다.
•
여러 설명이 있었는데 그냥 참고하는 정도로만 기억하자.