brunch

You can make anything
by writing

C.S.Lewis

by 에디의 기술블로그 Jun 09. 2019

Spring Boot AutoConfiguration

스프링부트 AutoConfiguration 에 대해서 샘플코드로 이해하기


추가의견 - 2020.1.25

 글을 다시 읽어보니 스프링부트의 AutoConfiguration  대한 내용 보다는, EnableConfigurationProperties  사용해서 프로퍼티 빈을 생성하는 내용이 주요 내용이다. AutoConfiguration  대해서는 @EnableAutoConfiguration @Condition.... 등에 대한 설명  스프링부트에서 어떻게 오토컨피그레이션를 해주는지에 대해서 설명을 해야하지만 그런 내용이 전혀 없는 허접한 글이었다. 부끄럽게 생각하며... 스프링부트의 오토컨피그레이션에 대해서 궁금한 개발자는 차라리 다른 글을 찾아보길 바란다. 필자가 나중에 시간이 되면 내용을 다시 정리해서 글을 새로 작성해보겠다.




스프링부트의 가장 중요한 특징은 무엇일까? 필자가 생각하는 가장 중요한 특징은 바로 AutoConfiguration 이다. 이번 글에서는, 스프링 부트 AutoConfiguration 에 대해서 알아보기로 하자.


AutoConfiguration에 대해서 생각하기 전에, 필자가 설명을 위해 만든 샘플코드를 먼저 보자.


Configuration 샘플 코드(1)


예제는, 네이버 오픈API 를 사용하는 샘플 코드이다. 개념 설명을 위한 코드라서, 코드를 자세히 보진 않아도 된다.


Template 코드 작성


오픈API 호출하는 코드를 Template 패턴으로 작성하였다. NaverBlogTemplate 라는 클래스를 생성하였고, 생성자에서는 OpenAPI 호출을 위한 기본 정보를 주입한다. NaverOpenAPI 를 위해 필요한 필수 정보는 아래오 같다.

Open API Url

Client ID

Client Secret

필자는 이미 Key 발급을 한 상황이다. 이 글을 보는 개발자중에서 해당 샘플을 실행하고 싶다면, 네이버 개발자센터에서 인증을 받아야 한다. OpenAPI 인증 관련해서 자세한 내용은 생략하겠다.

https://developers.naver.com/docs/search/blog/

샘플 코드는 블로그 데이터를 조회하는 메서드를 구현하였다. WebFlux 의 WebClient 를 사용하였고, 리턴 타입은 Mono<ResponseNaverBlog> 로 하였다.

리턴 타입 ResponseNaverBlog 클래스는 아래와 같다.



Template @Bean 정의


필자가 구현한 Template 를 스프링 환경에서 의존성주입을 하기 위해서 빈으로 정의해야 한다. @Bean 어노테이션을 사용하겠다. @Configuration 어노테이션을 선언해줘야 하며, @Value 어노테이션으로 프로퍼티에 이미 정의된 속성 값을 주입해준다.

application.properties 에 속성값을 작성하였다.


naverBlogTemplate 라는 이름의 빈이 정의가 되었다. 이제 우리는 프로젝트에서 naverBlogTemplate 를 빈주입하여 사용할 수 있다.


Template 사용


아주 간단한 Controller 을 만들어서 데이터를 호출해보자. 위에서 정의한 naverBlogTemplate 빈을 주입해서 사용할 것이다.

결과는 아래와 같다.

만약 OpenAPI 에 대한 인증이 안되어있다면 인증오류가 발생한다. 필자의 코드를 그대로 실행하면 아래와 같이 에러가 발생할 것이다. 제대로 보고 싶다면 네이버개발자센터에서 인증을 받고 오길 바란다.



(가정)만약 모든 개발자가 Template 를 정의해야 한다면??


네이버오픈API 를 사용하는 모든개발자는, Template 코드를 동일하게 작성해야 한다고 가정해보자. 처음 애플리케이션을 구축하는 초기 개발자는 네이버 Open API 연동 로직에 대해서 사전에 공부를 해야할 것이다. 또한 네이버 Open API 연동을 위해서 Template 코드를 작성해야 하고, Template  를 정의하는 @Bean 메서드 역시 작성을 해야 한다. 모든 귀찮은 작업을 반복해야 한다.


만약에...

해당 초기 셋팅 코드를 스프링 부트가 기본으로 제공해주면 얼마나 좋을까?

애플리케이션 구축할 때 빠르게 구축을 할 수 있고, 작성해야하는 코드가 줄어들 것이다.


자...이런 이유로 등장한 것이 바로 AutoConfiguration 이다.


AutoConfiguration


스프링부트 에서는 AutoConfiguration 을 제공하여, 개발자의 초기 설정 없이 심플하게 애플리케이션을 구축할 수 있도록 제공해준다. 스프링부트에서 제공하는 AutoConfiguration 에 대한 자세한 설명은 조금이따 다시 설명하겠다.


쉽게 설명하기 위해서, 샘플 코드를 예시로 작성했는데... 이 글을 보는 개발자분들께서 한번에 와닿을지는 모르겠다. 어쨋든, 이 글에서 작성한 OpenAPI 코드 연동 로직은 중요하지 않다. AutoConfiguration 을 이해하는 것이 훨씬 더 중요하다.


https://github.com/sieunkr/spring-boot-autoconfiguration-sample/tree/master/step01



Configuration 샘플 코드(2)


샘플 코드를 살짝 수정해보자. 기존 코드는 @Value 어노테이션을 통해서 속성 값을 설정했는데, 이번에는 @ConfigurationProperties 를 사용해서 좀 더 고급지게 만들어보자.



@ConfigurationProperties, @EnableConfigurationProperties


프로퍼티 값을 주입받기 위해서 @ConfigurationProperties 어노테이션을 적용한 Properties 클래스를 정의하였다. prefix 는 "naver.openapi" 로 정의하였고, Lombok 은 사용하지 않고 getter, setter 를 전부 작성하였다.

그리고, 이제 가장 중요한 AutoConfiguration 클래스를 작성하겠다. @EnableConfigurationProperties 를 선언해주고, 위에서 작성한 NaverBlogProperties.class 를 셋팅해준다. 이렇게 정의하면, application.properties 에 선언한 속성 값들... 즉, naver.openapi 프리픽스로 설정한 속성값을 모두 사용할 수 있다.

그리고, @Bean 어노테이션을 사용해서 naverBlogTemplate 이라는 빈을 생성해주자.



Pivotal(스프링개발회사)에서 AutoConfiguration 을 제공해준다고 가정해보자...


참고로, 나머지 코드는 샘플(1)과 같다. AutoConfiguration 코드를 필자가 직접 구현하였는데, 만약 Pivotal(스프링 개발회사)에서 네이버 Open API 연동에 대한 AutoConfiguration 을 제공해준다면 어떻게 될까? 우리는 BlogAutoConfiguration 를 직접 구현할 필요가 없다. 왜냐면, 스프링부트에 이미 작성이 되어있을 것이다. 우리가 해야하는 일은 무엇일까? 스프링부트 프로젝트에서는 기본적으로 org.springframework.boot.autoconfigure 디펜던시가 추가 되는데, 아래와 같이 수많은 기능이 작성이 되어있다. 스프링부트에서 이미 제공을 해준다면 아마도 해당 패키지에 AutoConfiguration 클래스가 정의가 되어있을 것이다.

AutoConfiguration 를 제공해주기 때문에, 우리는 속성만 잘 작성해주면 된다. 아래와 같은 속성값만 잘 정의해주고...

AutoConfiguration 에서 자동으로 생성해주는 Bean을 아래와 같이 사용하면 된다.



https://github.com/sieunkr/spring-boot-autoconfiguration-sample/tree/master/step02


이제 조금 AutoConfiguration 에 대해서 이해가 되기 시작했다. 혹시 이해가 안된다면... 필자의 글이 허접해서 그렇다. 시중에 나와있는 스프링부트 책을 구매해서 보는 것을 추천한다.



AutoConfiguration


아직도 이해가 안되는 개발자가 있을 것이다. 일단, 필자가 작성한 샘플코드는 잊자. 실제로 제공하는 AutoConfiguration 를 알아보는 것이 이해가 빠를 것이다. 수많은 기능을 제공하는데 필자가 생각할 때 가장 중요한 몇가지만 정리해보겠다.



Embedded Tomcat, Netty


첫번째 예시로 임베디드 WAS 에 대해서 설명하겠다.

참고로 필자의 샘플 코드가 리액티브 디펜던시... 암튼, Tomcat 을 사용하지 않고, Netty 서버를 사용한다.


스프링부트 애플리케이션을 실행할 때 특정 포트로 실행하기 위해서 우리는 applicatin.properties 에 아래와 같은 속성 값을 넣어준다.

스프링부트 애플리케이션을 구축하면서 복잡한 설정을 추가하지 않아도 된다. 심플하게 프로퍼티를 정의해주면 된다. 만약 프로퍼티에 정의를 해주지 않는다면, 기본으로 설정된 값이 셋팅 될 것이다. 참고로 현재 스프링부트 2.1.5.RELEASE 에서의 server.port 기본은 8080포트이다. 스프링부트 autoconfigure 패키지에서 해당 값을 셋팅해주는 곳을 찾아보자. org.springframework.boot.autoconfigure.web 패키지에서 ServerProperties 클래스를 보면, 필자의 샘플코드와 유사하게 @ConfigurationProperties 어노테이션을 사용해서 속성값을 매핑하는 클래스가 정의가 되어있다.

해당 속성을 사용해서 AutoConfiguration 을 해주는 핵심 클래스는 ReactiveWebServerFactoryAutoConfiguration 이다.

org.springframework.boot.autoconfigure.web.reactive 패키지에 있는 클래스인데, 아래와 같이 @EnableConfigurationProperties 어노테이션과 함께 ServerProperties.class 를 정의해주는 것을 확인할 수 있다.

디버깅을 해보자. server.port 값에 필자가 정의한 8081 포트가 설정되어있는 것을 확인할 수 있다.


WAS 관련 기타 XML 설정이나, @Bean 코드 등 귀찮은 작업이 하나도 추가되지 않았다. 스프링부트가 알아서 다 해준다. 아주 친절하다.


DataSource


애플리케이션에서 보통 RDBMS 를 연동하는 작업이 많다. 스프링부트 를 도입하기 전에는, DataSource 를 개발자가 직접 셋팅을 해줘야 한다. 예전에는 XML 설정으로 많이 했었고, Java 컨피그 설정으로 많이 셋팅한다. 하지만, 스프링부트에서는 DataSource Bean 정의를 별도로 하지 않아도 된다. Bean 은 자동으로 설정을 구성해준다. 우리는 필요한 프로퍼티 설정만 추가하면 된다.


하지만, 편하다고 해서 항상 정답일까?


스프링부트에서 자동으로 설정을 해주는 것은 매우 편하지만, 개발자는 이런 기능에 대해서 명확하게 알고 있어야 한다. 위 설정만으로 셋팅한다면 기본 연결 풀은 HikariCP 로 설정이 될 것이다. 하지만, 스프링부트 1.X 에서는 기본 풀이 Tomcat 이었다. 만약 기본설정인 HikariCP 를 사용하고 싶지 않다면 개발자는 프로퍼티 설정에서 spring.datasource.type 을 변경해야 한다.


지금 설명하는 내용은 하나의 예시일 뿐이고, 이런 경우가 매우 많을 것이다. 우리는 스프링부트에서 자동으로 구성해주는 것이 무엇인지에 대해서 어느정도는 알고 있어야 하고, 필요에 의해서는 변경을 할 수 있어야 한다.


참고로, 당연한 얘기지만, DataSource Bean 정의를 별도로 셋팅할 수도 있다.

https://www.baeldung.com/spring-boot-configure-data-source-programmatic


간단하게, 두가지 예시만 알아봤다. 심심하다면 org.springframework.boot.autoconfigure 패키지를 보는 것을 추천한다. 재미난 것이 꽤 많다.


마무리


이 글에서는, 스프링부트의 핵심 기능인 AutoConfiguration 에 대해서 알아봤다. 사실, 스프링부트에서 제공하는 기능은 매우 심플하고 편리하지만, 스프링부트의 모든 기능을 그대로 사용하기에는 조금은 무리가 있다. 물론 아주 작은 애플리케이션의 경우에는 별도의 커스터마이징 없이도 충분히 구축이 가능할 것이다. 필자 역시, 가능하다면 실무에서도 최대한 AutoConfiguration 제공 기능을 사용할려고 노력하지만, 경우에 따라서는 별도로 커스터마이징을 해야만 하는 경우도 꽤 있었다. 스프링부트의 기능을 그대로 사용하던, 커스터마이징 하던 어떤 방법을 사용할지에 대한 정답은 애플리케이션의 요구사항 및 상황에 따라서 잘 선택하면 될 것이다. 단, 확실한 사실은 우리는 스프링부트에서 제공하는 AutoConfiguration 에 대해서 명확하게 알아야 하고, 버전이 변경될때마다 Release Note 를 확인해서 어떤 사항이 변경되었는지 반드시 알아야 한다는 사실이다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari