1. War배포의 불편함

    1. 대표적으로 톰캣같은 WAS를 별도로 설치 → 버전을 바꾸려면 삭제, 재설치 필요
    2. 코드를 War형식으로 빌드해야함
    3. 빌드한 War파일을 WAS에 배포해야하며 연동되기 위한 복잡한 설정이 요구됨
    4. 이러한 불편함 때문에 스프링 부트의 필요성이 생김
  2. 내장 톰캣의 형식의 빌드와 배포(일반적인 jar)

    1. 내장 톰캣방식은 main() 메서드를 실행하면 톰캣이 작동되는 방식(라이브러리 형태로 서버가 내장)

    2. main() 메서드를 실행하기 위해서는 jar형식으로 빌드되어야함

    3. 그리고 jar파일 안에는 META-INF/MANIFAST.MF파일에 실행할 main()메서드의 클래스의 위치를 지정해줘야함(해당 파일에서 main() 메서드를 가진 클래스를 확인)

      Untitled

      Untitled

    4. 위 빌드방식으로 빌드했을 때는 치명적인 오류가 있다.

    5. 기본적으로 jar방식으로 빌드했을 때 jar파일은 내부에 jar파일을 못가지므로 해당 프로젝트를 빌드하는 과정에서 프로젝트가 의존하는 라이브러리 jar파일이 실행하려는 jar파일 내부에 존재하지 않는 것

    6. 이에 따라 main() 메서드를 실행하지 못하게 됨

    7. war파일의 경우 libs폴더에 의존 라이브러리를 가지고 있었음

    8. jar구조

      1. META-INF
      2. hello(java코드 최상단 패키지)
  3. jar파일은 jar파일을 포함할 수 없다

    1. 기본적으로 jar파일은 내부에 jar파일을 가질 수 없으며, 가지고 있다고 하더라도 인식이 불가능
    2. 그렇다고 war를 사용하고자 한다면, war는 WAS위에서만 실행됨
    3. 대안으로 jar파일을 모두 구해서 MANIFAST파일에 해당 경로를 모두 적어주면 되지만 동적으로 구성되지 못하고, 번거로움
  4. Fat jar

    Untitled

    1. 일반적이 jar파일이 jar형태의 라이브러리를 가지지 못하는 대안 jar
    2. 일반 jar와 같이 내부에 jar파일을 못가지지만 클래스는 가질 수 있음
    3. jar파일 자체가 java class의 압축 파일이기 때문에 압축을 푼 jar의 java파일을 가질 수 있게 됨
    4. 여기서 가지는 많은 클래스파일 때문에 Fat Jar라는 이름을 가지게 됨
    5. 이에 따라 톰캣등 라이브러리를 포함하고 있기 때문에 main() 메서드만 실행하면, 애플리케이션이 구동되는 jar파일을 만들 수 있게 됨
    6. 단점
      1. 일단 압축이 풀린 jar파일의 클래스파일만 가지기 때문에 어떤 라이브러리인지 파악 어려움
      2. 파일명 중복을 해결할 수 없음(파일명이 겹치는 경우 하나만 선택되기 때문에 정상 동작하지 못하게 됨)
  5. 스프링 부트 jar

    1. 구조

      1. META-INF
        1. MANIFAST.MF
      2. org/springframework/boot/loader
        1. JarLauncher.class(스프링 부트 main() 메서드 실행 클래스)
      3. BOOT-INF
        1. classes(개발자가 작성한 로직 코드 클래스들)
        2. lib(외부 라이브러리 jar파일)
        3. classpath.idx(외부 라이브러리 경로)
        4. layers.idx(스프링 부트 구조 경로)
    2. jar파일은 내부에 jar를 못가지는데 부트에서 빌드한 jar파일을 내부에 jar라이브러리를 가짐

    3. boot-0.0.1-SNAPSHOT-plain.jar 파일도 빌드하면 생기는데, 이 파일은 우리가 개발한 코드만 가지는 순수한 jar파일

    4. 실행방식

      Untitled

      1. 기존의 jar와는 실행방식이 조금 다르다
      2. 일단 jar파일은 우선적으로 MANIFAST.MF파일에서 main-class를 읽어서 main() 메서드를 실행
      3. 하지만, 부트의 jar는 Main-Class에 개발자가 작성한 메인 클래스가 아닌, JarLauncher가 있음(Start-Class에 개발자가 작성한 메인 클래스가 있음)
      4. 이부분은 부트가 빌드시에 저렇게 작성
      5. JarLauncher내부의 jar파일을 읽어들이는 역할을 하게 되고, 읽는 것을 마무리하면 Start-Class에 있는 클래스의 main() 메서드를 실행함
      6. 여기서 Main-Class부분을 제외하고는 자바 표준은 아님
      7. Spring-Boot-Version을 제외하고는 경로를 명시하는 부분
      8. classpath.idx: 외부 라이브러리 모음
      9. layers.idx: 스프링 부트 구조 정보
      10. 하지만, IDE에서 실행하는 경우 main() 메서드를 바로 실행함 → IDE가 필요한 라이브러리를 모두 인식 가능하기 때문