[Spring Boot] 자동 설정 @EnableAutoConfiguration

Junseo Kim·2020년 2월 2일
5

메인 클래스에 붙어 있는 @SpringBootApplication은 크게 3가지가 합쳐진 것이라고 생각할 수 있다.
1. @SpringBootConfiguration
2. @ComponentScan
3. @EnableAutoConfiguration

스프링 부트 어플리케이션은 Bean을 2번 등록한다. 처음에 ComponentScan으로 등록하고, 그 후에 EnableAutoConfiguration으로 추가적인 Bean들을 읽어서 등록한다.

@ComponentScan

@ComponentScan은 해당 패키지에서 @Component 어노테이션을 가진 Bean들을 스캔해서 등록하는 것이다.(@Configuration, @Repository, @Service, @Controller, @RestController 포함)

@EnableAutoConfiguration

AutoConfiguration은 결국 Configuration이다. 즉, Bean을 등록하는 자바 설정 파일이다.

spring.factories 내부에 여러 Configuration 들이 있고, 조건에 따라 Bean을 등록한다.

따라서 메인 클래스(@SpringBootApplication)를 실행하면, @EnableAutoConfiguration에 의해 spring.factories 안에 들어있는 수많은 자동 설정들이 조건에 따라 적용이 되어 수 많은 Bean들이 생성되고, 스프링 부트 어플리케이션이 실행되는 것이다.

자동 설정 구현

의존성 추가

먼저 의존성을 추가해준다. pom.xml에 아래의 코드를 추가한다.

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-autoconfigure</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-autoconfigure-processor</artifactId>
		<optional>true</optional>
	</dependency>
</dependencies>

<!-- 위에 추가해준 2개의 의존성 버전 관리를 하기 위함  -->
<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-dependencies</artifactId>
			<version>2.0.3.RELEASE</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

패키지를 만들어주고, 임의로 Solo라는 클래스를 만들어준다.

Configuration 파일 작성

그런 다음 Configuration 클래스를 만들어준다.

원래는 설정하는 대상이 되는 클래스는 다른 프로젝트에 있는 것이 흔하다. 다른 프로젝트에 있는 어떤 라이브러리에 대한 자동 설정파일을 또 다른 프로젝트에서 만드는 것이 보통이다.

spring.factories 파일 생성

main - resources에 META-INF 디렉토리를 만들어준다. 그 후, 해당 디렉토리에 spring.factories 파일을 만들어준다.

spring.factories 파일에 아래와 같은 코드를 추가해준다.(만들어준 설정 파일을 명시적으로 정의)

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  패키지이름.Configuration파일이름

이렇게 하면 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 이 key에 해당하는 것을 스프링 부트 EnableAutoConfiguration이 켜져있을 경우 적어준 설정파일(Configuration파일)을 자동으로 읽어온다.

mvn install

그 후, mvn install을 해준다.

만약 Source option 5 is no longer supported, Target option 5 is no longer supported 에러가 발생하면 pom.xml에 아래코드를 추가해준다.

 <properties>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
 </properties>

빌드가 완성되면 jar파일이 생성되고, 이 파일은 다른 메이븐 프로젝트에서도 사용할 수 있게 local 메이븐 저장소에 설치한다.

다른 프로젝트에서 Bean 사용해보기

이제 다른 프로젝트에서 의존성을 추가해주면 사용할 수 있다.

먼저 pom.xml의 아래부분을 복사한다.

그 후, 다른 프로젝트에 에 복사한 정보를 붙여넣으면, 다른 프로젝트에서 사용할 수 있는 것이다.

그러면 추가된 것을 볼 수 있다.

이제 다른 프로젝트에서도 사용할 수 있는지 확인 하기 위해 SoloRunner라는 클래스를 만들어준다.

ApplicationRunner는 스프링부트 애플리케이션이 만들어지고 실행됐을때 자동으로 실행되는 Bean을 만들고 싶을 때 사용하는 것이다

SoloRunner에서 @Autowired로 Solo를 주입받을 수 있다. Solo를 주입받아 출력해보면, 이 프로젝트에 Solo라는 것이 없지만, 값이 제대로 출력됨을 볼 수 있다.

문제점

그러나 이렇게 하는 경우, 이 프로젝트에 새로 Solo라는 Bean을 등록해도, 출력하면 무시된다.

왜냐하면, 스프링부트는 Bean을 2번 등록하는데, 먼저 componentScan을 하고, 그 후에 EnableAutoConfiguration을 하기때문에, 새로 만들어준 Bean이 componentScan에 의해 먼저 등록된 후에 EnableAutoConfiguration에 의해 덮어써지기 때문이다.

그러나 스프링부트 2.1 부터 default로 overriding 옵션이 false로 설정되어 있어서 아에 error가 발생한다.

이 덮어씀을 방지하기 위해서는 componentScan이 우선시되게 바꿔주어야한다.

그러려면 Configuration 파일에 @ConditionalOnMissingBean를 추가해준다.

다시 mvn install을 해주고 실행시키면 덮어씀이 없어짐을 볼 수 있다.

application.properties 설정

이 경우 Bean의 내용을 바꾸고 싶을 때, 번거롭다.

main - resources에 application.properties 파일을 만들어준다.

사용할 값을 아래 형식으로 적어준다. key값과 value값은 임의로 해줘도 된다.

이 properties를 사용하여 값을 변경할 수 있게 하려면, Properites에 해당하는 것을 정의해줘야한다.

pom.xml에 아래의 의존성을 추가해준다.(프로퍼티 자동완성 지원)

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-configuration-processor</artifactId>
	<optional>true</optional>
</dependency>

그리고 Properties 파일을 만들어준다. @ConfigurationProperties 어노테이션을 붙여주고, 사용할 prefix를 괄호안에 적어준다.

이 properties 파일을 사용하려면 Configuration 파일에 @EnableConfigurationProperties 어노테이션을 붙여준다. 그리고 괄호안에 아까 만들어준 property 파일을 설정해준다.

이렇게하면, 원본에서 override 해서 Bean을 새로 만들 필요없이 application.properties에서 값만 바꿔주면 된다.

4개의 댓글

comment-user-thumbnail
2021년 10월 3일

@EnableAutoConfiguration 가물가물해서 찾아왔는데 역시 대박 정리입니다!!

한 가지 질문이 있습니다.

@EnableAutoConfiguration 을 main이 있는 클래스 말고 다른 곳에서 사용할 수도 있을텐데, 여러 곳에 붙는건 어떤걸 의미하는지가 궁금합니다! main이 존재하는 클래스 말고 다른 클래스에서 @EnableAutoConfiguration을 사용하는 경우와 main에서 사용하는 경우처럼요!

1개의 답글