메인 클래스에 붙어 있는 @SpringBootApplication은 크게 3가지가 합쳐진 것이라고 생각할 수 있다.
1. @SpringBootConfiguration
2. @ComponentScan
3. @EnableAutoConfiguration
스프링 부트 어플리케이션은 Bean을 2번 등록한다. 처음에 ComponentScan으로 등록하고, 그 후에 EnableAutoConfiguration으로 추가적인 Bean들을 읽어서 등록한다.
@ComponentScan은 해당 패키지에서 @Component 어노테이션을 가진 Bean들을 스캔해서 등록하는 것이다.(@Configuration, @Repository, @Service, @Controller, @RestController 포함)
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 클래스를 만들어준다.
원래는 설정하는 대상이 되는 클래스는 다른 프로젝트에 있는 것이 흔하다. 다른 프로젝트에 있는 어떤 라이브러리에 대한 자동 설정파일을 또 다른 프로젝트에서 만드는 것이 보통이다.
main - resources에 META-INF 디렉토리를 만들어준다. 그 후, 해당 디렉토리에 spring.factories 파일을 만들어준다.
spring.factories 파일에 아래와 같은 코드를 추가해준다.(만들어준 설정 파일을 명시적으로 정의)
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
패키지이름.Configuration파일이름
이렇게 하면 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
이 key에 해당하는 것을 스프링 부트 EnableAutoConfiguration이 켜져있을 경우 적어준 설정파일(Configuration파일)을 자동으로 읽어온다.
그 후, 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 메이븐 저장소에 설치한다.
이제 다른 프로젝트에서 의존성을 추가해주면 사용할 수 있다.
먼저 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을 해주고 실행시키면 덮어씀이 없어짐을 볼 수 있다.
이 경우 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에서 값만 바꿔주면 된다.