kok202
스프링 부트 강의 정리 (1~3 : 인트로, Jar, MainApplication)

2019. 4. 20. 18:10[공부] 영상/스프링 부트 강의

강의 출처 : https://www.youtube.com/playlist?list=PLfI752FpVCS8tDT1QEYwcXmkKDz-_6nm3

 

스프링 부트 - YouTube

 

www.youtube.com

 

 

 

 

 

스프링 릴리즈 버전 관리 방법

Snapshot  - Daily 
M1, M2  Milestone 짧은 주기, 기능이 완성 되자마자 공개
RC Release Candiate 출시 직전, 마일 스톤 이후의 더 큰 주기
GA General Available 안정적인 버전, 시장에서 사용 될 수 있음

 

 

 

 

 

@EnableAutoConfiguration

= class-path 에 존재하는 관련 라이브러리들을 읽어들임

 

 

 

 

 

Executable Jar 파일

의존성을 가지고 있는 클래스나 라이브러리도 가지고 있어서 실행가능한 jar 파일

* 자바에서는 nested jar를 읽어들이는 표준 방법이 존재하지 않는다.

보통 이런 문제를 해결하기 위해 uber jar 를 많이 사용하는데 uber jar는 다음과 같은 문제점이 있다,

1. 모든 의존성이 걸린 jar 파일을 single archive로 만들기 때문에 의존성 파악이 어렵다. 

2. 같은 이름을 가진 jar 파일이 있으면 문제가 생길 수 있다.

그래서 스프링에서는 uber jar를 쓰지 않고 Fat jar라는 형태로 nested jar를 읽어들인다.

 

 

 

 

 

Launcher

스프링부트에서 고안해낸 Fat jar 파일을 읽어서 실행하는 것이 목적.

nested jar 파일에서 리소스를 읽어들이는것이 주목적이다.

메이븐 프러그인이 알아서 nested jar 파일을 보고 class path 를 추론 할 수 있으므로 따로 정의해줄 필요가 없다.

* Executable jar 파일을 사용할 때의 제약사항

1. Zip entry 로 압축

2. System class Loader : 스프링 컨테이너가 custom 한 클래스 로더를 사용하므로 SystemClassLoader만으로 스프링 컨테이너에 있는 객체들을 읽어들이려 하면 에러가 난다. 그러므로 어플리케이션을 스레드에 있는 Thread.getContextClassLoader()를 사용해야한다. ClassLoader.getSystemClassLoader()를 사용하는 것이 있다면 실패할 것이다. 대표적으로 java.util.Logging 은 SystemClassLoader를 사용하므로 실패한다.  그러므로 @Slf4j 를 쓰는 것이 좋다.

 

 

 

 

 

MainApplication의 위치

* 디폴트 패키지 : 자바 용어, src

* 루트 패키지 : 스프링 용어, src/com.company.project

com.company.project 패키지 이름은 자바에서 권장하는 방식이다.

 

무작정 Autowired 한다고 Bean이 불려와 지는 것이 아니다. MainApplication 클래스(Main 메소드가 있는 클래스) 위에 @ComponentScan 또는 @Import 를 달아줘서 Service, Repository, Configuration의 위치를 달아줘야 컨테이너의 Bean으로 생성이 가능해진다.

MainApplication 클래스의 위치는 루트 패키지(com.company.project) 에 두는 것을 추천한다. MainApplication 위에 달아두는 Annotation 들이 Main Application을 기준으로 하위 패키지를 탐색하여 설정을 읽어들이기 때문에 사용하기 편해지고 코드가 깨끗해진다. 

ex1. @EnableAutoConfiguration 이 @Entity 파일을 검색할 때 MainApplication의 하위 패키지를 검색한다.

ex2. @ComponentScan 에 basepackage 설정을 안해줘도 MainApplication이 루트 패키지에 있다면 하위 패키지를 알아서 탐색할 수 있다.

 

더불어 루트패키지를 사용하면 MainApplication에  @SpringBootApplication을 사용할 수 있다. (@SpringBootApplication = @ComponentScan + @EnableAutoConfiguration + @SpringBootConfiguration ... 등을 모아둔 Annotation)만약 디폴트 패키지에 MainApplication을 둘경우 컴포넌트 스캔의 대상이 너무 커진다. 성능이 저하 될 수도 있다.

 

 

 

 

 

@Autowired

무작정 @Autowired 빈을 주입받을 수 있는게 아니다. 컨테이너에서 빈 파일을 읽어들이기 위해선 컨테이너에 해당하는 빈파일이 존재해야한다. 그리고 컨테이너에 빈을 만들기 위해선 @ComponentScan 이나 @Import 같은 것들로 Service, Repository, Configuration의 위치가 정의되어 있어야한다. 이러한 Annotation은 MainApplication에 달아두는것이 바람직하다. 

 

 

 

 

 

@ConfigurationProperties

Configuration key로 정의된 값을 읽어들임. 스프링 부트에서 사용하는 Configuration key 를 사용하지 마라 (ex. application.properties 나 application.yml의 spring.datasource.url 등...) 개인의 프로젝트가 Spring boot에 의존성이 생기는 행위다. 스프링 부트의 버전이 바뀌면 프로젝트가 망가질 수 있다.

자세한 내용 : https://kok202.tistory.com/129

 

스프링 부트 강의 정리 (8~10 : Properties 읽어들이기)

스프링 부트는 설정파일을 밖으로 빼낼 수 있게 해져있다. properties, yml, Environment, command line 등을 사용하여 정의할 수 있다. 정의된 설정 값은 @Value로 주입받거나 스프링이 제공하는 Environment int..

kok202.tistory.com

 

 

 

 

spring-boot-starter

스프링에서 제공하는 편리한 의존성 모듈들. 의존성 충돌 관리 등을 해준다.

 

 

 

 

 

가능하면 컴포넌트 등록 방식은 단순하게 해라. 아래 코드는 지양한다.

@Configuration
public class MyBeansConfig{
   @Bean
   public MyController myController(){ return new MyController(); }
   @Bean
   public MyService myService(){ return new MyService(); }
   @Bean
   public MyRepository myRepository(){ return new MyRepository(); }
}

이렇게 쓸 수 는 있는데 프로젝트이 복잡도만 올라간다. MyController, MyService, MyRepository 클래스에 @Controller, @Service, @Repository 를 달아주지 않고 위 방식대로 만들면 어노테이션이 달려있지도 않은데 왜 빈이 생성됬는지 코드를 괜히 한번 더 추적해서 봐야한다. 그냥 MyController, MyService, MyRepository  클래스 위에 그냥 각각 @Controller, @Service, @Repository를 달아주면 될 일이다.