티스토리 뷰
기존 Spring 애플리케이션 환경을 구축할 때 주로 XML파일을 기반으로 개발에 필요한 모든설정을 잡아줬다.
가령 Spring MVC로 개발환경을 구성할 때 servlet-context.xml과 root-context.xml에 세팅하는데 설정을 잘못해서 예외가 발생하면 디버깅이 힘들었고 구축하는데에도 많은시간이 걸렸다.
그리고 컨트롤러에서 View를 렌더링 하는게 아닌 JSON 데이터를 전달하려고 할 때 jackson 라이브러리를 디펜던시에 추가해줘야하고 프론트에서 텍스트데이터가 아닌 파일형식의 데이터를 받아줄 때도 Multipart 디펜던시도 추가해줘야 한다.
이처럼 개발할 때 필요한 디펜던시들을 개발자가 하나하나 직접 찾아가면서 Spring 프로젝트 버전에 호환되게 등록해줬어야 했고 이러한 개발자의 수고스러움을 덜어주기 위해 Spring Boot가 등장했다.
Spring Boot가 등장하면서 Spring 애플리케이션 개발환경구성을 보다 쉽고 간편하게 해줄 수 있도록 많은것들을 지원해주는데 대표적으로 몇가지정도 살펴보자.
Spring Boot Starter 제공
Spring Boot Starter는 의존성과 설정을 자동화 해주며 일부 모듈들을 application.properties 파일에 정의하여 간단히 구성할 수 있다.
가장 대표적으로 쓰이는 starter-web이 있는데 이 의존성 하나를 추가해주면 jackson, servlet, multipart, logging 등 의존성이 추가된다. Spring Boot를 사용하기 이전엔 일일이 하나씩 다 해줘야하는 번거로움을 Spring Boot를 이용함으로써 간단히 구성할 수 있게된다.
Embedded Tomcat 지원
위 사진에서 보면 starter-web 하위에 starter-tomcat이라는 의존성이 추가되있는걸 볼 수 있는데 별도로 Tomcat을 설치하지 않아도 jar파일에 Tomcat이 내장되있기 때문에 간단하게 main 메서드 실행만으로 서버를 구동할 수 있다. 그래서 애플리케이션을 배포할 때 Tomcat이 설치되있지 않아도 jar로 빌드해서 배포할 수 있다.
디펜던시 버전관리
위 사진에서 보면 starter-web 의존성을 추가하고 version을 따로 명시하지 않았다. 근데 어떻게 2.5.5 version에 맞게끔 가져온 것일까? 해답은 아래사진을 보면 나와있다.
Spring Boot 프로젝트를 생성하면 spring-boot-starter-parent라는 부모pom을 상속받는데 spring-boot-starter-parent
은 spring-boot-dependencies를 상속받는다. spring-boot-dependencies에는 Spring Boot 애플리케이션 개발시 필요하는 디펜던시를 등록하면 현재 Spring Boot 프로젝트 버전에 최적화된 버전을 알아서 관리해준다는 장점이 있다.
spring-boot-dependencies.pom을 확인해보면 Spring Boot 애플리케이션 개발과 관련된 의존성들이 있고 각 라이브러리들이 현재 Spring Boot 프로젝트 버전과 최적화되는 버전이 몇인지 명시되어 있다. 물론 여기에 없는 의존성들은 pom.xml에 추가할 때 version도 명시해줘야 한다.
DevTools 지원
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
Spring Boot에서 제공해주는 것 중 하나인데 서버가 실행중인 상태에서 Java 파일을 수정하게되면 서버를 재기동 하지않는이상 반영되지않는데 해당 의존성을 추가해주면 Java 파일을 수정후 서버를 재기동 하지않아도 알아서 변경된 Java 파일의 컴파일한 결과를 서버에 반영한다.
설정파일 간편구성
Spring Boot을 사용하기전에 Config 파일같은걸 생성할 때 주로 XML이나 Java로 설정을 많이했었는데 Spring Boot를 사용하게되면 Spring Boot에서 제공하는 @ConfigurationProperties, @ConstructorBinding 어노테이션으로 보다 간편하고 가독성있게 Java 코드로 환경설정을 잡을 수 있다. (이건 제가 Spring Boot를 썻었을때 느꼈던 개인적인 장점)
Auto Configuration
Spring Boot가 자랑하는 가장 대표적인 장점이 아닌가 싶다. 아래사진을 보자
main 메서드에 @SpringBootApplication어노테이션이 있다. 내부를 살펴보면 가장중요시하게 봐야할건
@Component와 @EnableAutoConfiguration이다. @Component는 Java파일에 해당 어노테이션을 정의하면 Spring한테 이 클래스를 Bean으로 관리해달라게끔 하는것이고 @EnableAutoConfiguration는 정의된 의존성들을 Bean으로 등록해주는 어노테이션을 말한다.
Spring Boot를 사용하기 이전에 Controller, Service, DAO 파일을 생성후 Bean으로 관리할 땐 servlet-context.xml, root-context.xml에 각 파일들이 있는 패키지 경로를 적어줘야 했지만 Spring Boot를 사용하게되면 패키지 경로를 적어주지 않고 어노테이션만 선언하면 알아서 Bean등록이 된다. 단, 현재 main 메서드가 있는 패키지를 root 경로라 가정할 때 root 하위에 생성된 패키지들에 대해서만 적용되며 root 경로와 다른경로에 정의된게 있을땐 main 메서드에 @ComponentScan 어노테이션을 별도로 정의해야한다.
@EnableAutoConfiguration로 인해 Spring Boot 프로젝트를 생성하면 자동으로 생성되는 Bean들이 있는데 그 Bean들은 아래사진에서 확인할 수 있다. spring.factories 파일참고
자동으로 생성되는 Bean들중에 대표적으로 JacksonAutoConfiguration, MultipartAutoConfiguration 2개가 있다. spring.factories에 정의되어진 목록이여도 무조건 Bean이 생성되지는 않는다. 특정조건을 갖춰야하는데 아래사진을 보자
해당클래스를 보면 @ConditionalOnClass 어노테이션이 선언된 걸 볼 수있다. 이 어노테이션이 선언되면 classpath에 특정 class가 존재할 경우 Bean이 생성되는데 현재 classpath에는 ObjectMapper.class와, MultipartResolver.class, Servlet.class가 존재한다. 맨위에 starter-web 의존성을 추가할 때 위 3개들도 다 같이 추가되었기 때문이다.
Spring Boot를 사용하지 않았더라면 의존성도 추가해야되고 그 의존성들 Spring이 관리하게끔 Bean으로 설정을 해야했지만 Spring Boot를 사용함으로써 이런기능들을 다 자동으로 설정해주는 것이다.
그리고 자동으로 설정을 잡아줘도 application.properties(yaml) 파일로 간단하게 일부요소를 변경해서 잡아줄 수 있다. 예를들어 Multipart 같은경우 MultipartProperties.class에 정의된 내용으로 Bean을 생성하는데 파일의 MAX-SIZE가 1메가로 되어있는데 1메가보다 더 큰 요청이 들어올 경우 예외가 나기때문에 그 값을 변경해서 구성할 수 있다.
자동설정과 관련해서 각 모듈마다 Properties 클래스를 제공해준다. JDBC는 DataSourceProperties.class, WAS는 ServerProperties.class, Thymeleaf는 ThymeleafProperties.class가 있다.
개인적인 의견
Spring을 입문한분들이 간혹 질문하는 내용중에 "Spring과 Spring Boot의 차이"에 대해 많이들 여쭤본다. 사실 Spring과 Spring Boot 두개를 비교하는건 조금 애매모호한 부분이 있다. Spring은 애플리케이션을 개발하기위한 Java 기반의 프레임워크이고 그 안에 애플리케이션을 개발하기위한 여러개의 기능들이 있는데 예를들어 보안/인증과 관련된 Spring Security, 배치처리를 위한 Spring Batch, 기본 데이터 저장소의 특수한 특성을 유지하면서 데이터 접근을 위한 Spring Data가 있는데 이 3개를 Spring과 비교를 하는건 본적이 없다. Spring Boot도 마찬가지로 Spring이 제공하는 기능중 하나일 뿐 Spring 자체와 비교대상은 아닌 것 같다는 생각이 든다.
Spring과 Spring Boot의 차이에 대한 것 보다는 Spring Boot에서 제공해주는 기능들로 개발했을때의 이점을 궁금해하는게 더 낫다는 생각이 든다.