You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
참고: 스프링이 로딩되는 과정은 복잡해서 MemoryCondition이 여러번 호출될 수 있다. 이 부분은 크게 중요하지 않으니 무시하자.
참고: 스프링은 외부 설정을 추상화해서 Environment로 통합했다. 그래서 다음과 같은 다양한 외부 환경 설정을 Environment 하나로 읽어들일 수 있다. 여기에 대한 더 자세한 내용은 뒤에서 다룬다.
#VM Options
#java -Dmemory=on -jar project.jar
-Dmemory=on
#Program arguments
# -- 가 있으면 스프링이 환경 정보로 사용
#java -jar project.jar --memory=on
--memory=on
#application.properties
#application.properties에 있으면 환경 정보로 사용
memory=on
${\textsf{\color{orange}5.2. Conditional - 다양한 기능}}$
지금까지 Condition 인터페이스를 직접 구현해서 MemoryCondition 이라는 구현체를 만들었다. 하지만, 우리 스프링은 이미 필요한 대부분의 구현체를 만들어두었다. 이번에는 스프링이 제공하는 편리한 기능을 사용해보자
지금까지 @Conditional 에 대해서 알아보았으니, 지금부터는 @AutoConfiguration 을 알아보자.
0x06. 순수 라이브러리 만들기 & 사용하기
${\textsf{\color{orange}6.1. 순수 라이브러리 만들기}}$
@AutoConfiguration을 이해하기 위해서는 그 전에 먼저 라이브러리가 어떻게 사용되는지 이해하는 것이 필요하다.
여러분이 만든 실시간 자바 Memory 조회 기능이 좋다고 소문이 나서, 여러 프로젝트에서 사용하고 싶어한다. 이 기능을 아무데서나 사용할 수 있도록 라이브러리로 만들어보자.
참고로 라이브러리를 만들 때는 스프링 부트 플러그인 기능을 사용하지 않고 진행한다.
프로젝트 설정 순서
memory-v1-start 의 폴더 이름을 memory-v1 으로 변경하자.
프로젝트 임포트
File ⇒ Open ⇒ 해당 프로젝트의 build.gradle 선택 ⇒ Open as Project 선택
build.gradle 확인
plugins {
id 'java'
}
group ='memory'
sourceCompatibility ='17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web:3.0.2'
compileOnly 'org.projectlombok:lombok:1.18.24'
annotationProcessor 'org.projectlombok:lombok:1.18.24'
testImplementation 'org.springframework.boot:spring-boot-starter-test:3.0.2'
}
test {
useJUnitPlatform()
}
스프링 부트 플러그인을 사용하게 되면 앞서 설명한 실행 가능한 Jar 구조를 기본으로 만든다.
여기서는 실행 가능한 Jar가 아니라, 다른 곳에 포함되어서 사용할 순수 라이브러리 Jar를 만드는 것이 목적이므로 스프링 부트 플러그인을 사용하지 않았다.
그런데 라이브러리를 사용하는 클라이언트 개발자 입장을 생각해보면, 라이브러리 내부에 있는 어떤 빈을
등록해야하는지 알아야 하고, 그것을 또 하나하나 빈으로 등록해야 한다. 지금처럼 간단한 라이브러리가 아니라 초기 설정이 복잡하다면 사용자 입장에서는 상당히 귀찮은 작업이 될 수 있다.
이런 부분을 자동으로 처리해주는 것이 바로 스프링 부트 자동 구성(Auto Configuration)이다.
0x07. 자동 구성 라이브러리 만들기 & 사용하기
${\textsf{\color{orange}7.1. 자동 구성 라이브러리 만들기}}$
우리가 만든 라이브러리를 사용해주는 고마운 고객 개발자를 위해, 프로젝트에 라이브러리를 추가만 하면 모든 구성이 자동으로 처리되도록 해보자. 쉽게 이야기해서 스프링 빈들이 자동으로 등록되는 것이다. 여기에 추가로 memory=on 옵션도 적용할 수 있게 해보자.
이렇게 하려면 메모리 라이브러리의 기능을 업그레이드 해야한다.
기존 프로젝트를 유지하기 위해 프로젝트를 복사하고 일부 수정하자.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
0x05. @conditional
@Conditional이다.지금부터
@Conditional에 대해서 자세히 알아보자. 이름 그대로 특정 조건을 만족하는가 하지 않는가를 구별하는 기능이다.이 기능을 사용하려면 먼저
Condition인터페이스를 구현해야 한다. 그전에 잠깐Condition인터페이스를 살펴보자.Conditionmatches()메서드가true를 반환하면 조건에 만족해서 동작하고,false를 반환하면 동작하지 않는다.
ConditionContext: 스프링 컨테이너, 환경 정보 등을 담고 있다.AnnotatedTypeMetadata: 애노테이션 메타 정보를 담고 있다.Condition 인터페이스를 구현해서 다음과 같이 자바 시스템 속성이
memory=on이라고 되어 있을 때만 메모리 기능이 동작하도록 만들어보자.MemoryConditionmemory=on이라고 되어 있는 경우에만true를 반환한다.MemoryConfig- 수정@Conditional(MemoryCondition.class)MemoryConfig의 적용 여부는@Conditional에 지정한MemoryCondition의 조건에 따라 달라진다.MemoryCondition의matches()를 실행해보고 그 결과가true이면MemoryConfig는 정상 동작한다. 따라서memoryController,memoryFinder가 빈으로 등록된다.MemoryCondition의 실행결과가false이면MemoryConfig는 무효화 된다. 그래서memoryController,memoryFinder빈은 등록되지 않는다.먼저 아무 조건을 주지 않고 실행해보자.
실행
결과
memory=on을 설정하지 않았기 때문에 동작하지 않는다.다음로그를 통해서
MemoryCondition조건이 실행된 부분을 확인할 수 있다. 물론 결과는false를 반환한다.이번에는
memory=on조건을 주고 실행해보자.VM 옵션을 추가하는 경우
-Dmemory=on를 사용해야 한다.실행
결과
MemoryCondition조건이true를 반환해서 빈이 정상 등록된다.다음로그를 확인할 수 있다.
지금까지
Condition인터페이스를 직접 구현해서MemoryCondition이라는 구현체를 만들었다. 하지만, 우리 스프링은 이미 필요한 대부분의 구현체를 만들어두었다. 이번에는 스프링이 제공하는 편리한 기능을 사용해보자MemoryConfig- 수정@Conditional(MemoryCondition.class)를 주석처리하자@ConditionalOnProperty(name = "memory", havingValue = "on")를 추가하자memory=on이라는 조건에 맞으면 동작하고, 그렇지 않으면 동작하지 않는다.@ConditionalOnProperty
@ConditionalOnProperty도 우리가 만든 것과 동일하게 내부에는@Conditional을 사용한다. 그리고 그 안에Condition인터페이스를 구현한OnPropertyCondition을 가지고 있다.http://localhost:8080/memory실행해보면 앞서 만든 기능과 동일하게 동작하는 것을 확인할 수 있다.
(1) @ConditionalOnXxx
스프링은 @conditional 과 관련해서 개발자가 편리하게 사용할 수 있도록 수 많은
@ConditionalOnXxx를 제공한다.대표적인 몇가지를 알아보자.
@ConditionalOnClass,@ConditionalOnMissingClass@ConditionalOnBean,@ConditionalOnMissingBean@ConditionalOnProperty@ConditionalOnResource@ConditionalOnWebApplication,@ConditionalOnNotWebApplication@ConditionalOnExpression이름이 직관적이어서 바로 이해가 될 것이다.
@ConditionalOnXxx는 주로 스프링 부트 자동 구성에 사용된다.다음 자동 구성 클래스들을 열어서 소스 코드를 확인해보면
@ConditionalOnXxx가 아주 많이 사용되는 것을 확인할 수 있다.JdbcTemplateAutoConfiguration,DataSourceTransactionManagerAutoConfiguration,DataSourceAutoConfiguration정리
스프링 부트가 제공하는 자동 구성 기능을 이해하려면 다음 개념을 이해해야 한다.
@Conditional: 특정 조건에 맞을 때 설정이 동작하도록 한다.@AutoConfiguration: 자동 구성이 어떻게 동작하는지 내부 원리 이해@Conditional에 대해서 알아보았으니, 지금부터는@AutoConfiguration을 알아보자.0x06. 순수 라이브러리 만들기 & 사용하기
@AutoConfiguration을 이해하기 위해서는 그 전에 먼저 라이브러리가 어떻게 사용되는지 이해하는 것이 필요하다.여러분이 만든 실시간 자바 Memory 조회 기능이 좋다고 소문이 나서, 여러 프로젝트에서 사용하고 싶어한다. 이 기능을 아무데서나 사용할 수 있도록 라이브러리로 만들어보자.
참고로 라이브러리를 만들 때는 스프링 부트 플러그인 기능을 사용하지 않고 진행한다.
프로젝트 설정 순서
memory-v1-start의 폴더 이름을memory-v1으로 변경하자.File⇒Open⇒ 해당 프로젝트의build.gradle선택 ⇒Open as Project선택build.gradle 확인
plugins { id 'java' } group = 'memory' sourceCompatibility = '17' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web:3.0.2' compileOnly 'org.projectlombok:lombok:1.18.24' annotationProcessor 'org.projectlombok:lombok:1.18.24' testImplementation 'org.springframework.boot:spring-boot-starter-test:3.0.2' } test { useJUnitPlatform() }스프링 부트 플러그인을 사용하게 되면 앞서 설명한 실행 가능한 Jar 구조를 기본으로 만든다.
여기서는 실행 가능한 Jar가 아니라, 다른 곳에 포함되어서 사용할 순수 라이브러리 Jar를 만드는 것이 목적이므로 스프링 부트 플러그인을 사용하지 않았다.
스프링 컨트롤러가 필요하므로
spring-boot-starter-web라이브러리를 선택했다.스프링 부트 플러그인을 사용하지 않아서 버전을 직접 명시했다.
(1) 메모리 조회 기능 추가
앞서 개발한 것과 같은 실시간 메모리 조회 기능을 추가하자.
MemoryMemoryFinderMemoryControllerMemoryFinderTest(2) 빌드하기
JAR를 푼 결과
META-INFMANIFEST.MFmemoryMemoryFinder.classMemoryController.classMemory.classmemory-v1.jar는 스스로 동작하지는 못하고 다른 곳에 포함되어서 동작하는 라이브러리이다. 이제 이 라이브러리를 다른 곳에서 사용해보자.프로젝트 설정 순서
project-v1-start의 폴더 이름을project-v1으로 변경하자.File⇒Open⇒ 해당 프로젝트의build.gradle선택 ⇒Open as Project선택build.gradle 확인
plugins { id 'org.springframework.boot' version '3.0.2' id 'io.spring.dependency-management' version '1.1.0' id 'java' } group = 'hello' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() }스프링 부트에서 다음 라이브러리를 선택했다.
Lombok,Spring Web프로젝트가 동작하는지 확인하기 위해 간단한 컨트롤러를 하나 추가하자.
HelloController
실행
http://localhost:8080/hello
결과
hello앞서 만든
memory-v1.jar라이브러리를project-v1에 적용해보자.라이브러리 추가
project-v1/libs폴더를 생성 후memory-v1프로젝트에서 빌드한memory-v1.jar를 이곳에 복사하자. (libs임 철자 주의!)project-v1/build.gradle에memory-v1.jar를 추가하자.dependencies { implementation files('libs/memory-v1.jar') //추가 implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' }files로 지정하면 된다.gradle을 리로드하자.(1) 라이브러리 설정
우리가 직접 만든 외부 라이브러리를 → 스프링 빈으로 등록해서 동작하도록 만들어보자.
먼저
hello/config폴더를 생성 후 다음 내용을 담은MemoryConfig생성MemoryConfig
메모리 조회 기능이 잘 동작하는지 확인해보자.
서버 실행 로그
실행
결과
메모리 조회 라이브러리가 잘 동작하는 것을 확인할 수 있다.
(2) 정리
등록해야하는지 알아야 하고, 그것을 또 하나하나 빈으로 등록해야 한다. 지금처럼 간단한 라이브러리가 아니라 초기 설정이 복잡하다면 사용자 입장에서는 상당히 귀찮은 작업이 될 수 있다.
0x07. 자동 구성 라이브러리 만들기 & 사용하기
우리가 만든 라이브러리를 사용해주는 고마운 고객 개발자를 위해, 프로젝트에 라이브러리를 추가만 하면 모든 구성이 자동으로 처리되도록 해보자. 쉽게 이야기해서 스프링 빈들이 자동으로 등록되는 것이다. 여기에 추가로
memory=on옵션도 적용할 수 있게 해보자.이렇게 하려면 메모리 라이브러리의 기능을 업그레이드 해야한다.
기존 프로젝트를 유지하기 위해 프로젝트를 복사하고 일부 수정하자.
memory-v1프로젝트를 복사해서memory-v2를 만들자.settings.gradle- 수정(1) 자동 구성 추가
MemoryAutoConfig
@AutoConfiguration@ConditionalOnPropertymemory=on이라는 환경 정보가 있을 때 라이브러리를 적용한다. (스프링 빈을 등록한다.)(2) 자동 구성 대상 지정
파일 생성
org.springframework.boot.autoconfigure.AutoConfiguration.imports
memory.MemoryAutoConfig를 패키지를 포함해서 지정해준다.org.springframework.boot.autoconfigure.AutoConfiguration.imports의 정보를 읽어서 자동 구성으로 사용한다. 따라서 내부에 있는MemoryAutoConfig가 자동으로 실행된다.(3) 빌드하기
./gradlew clean buildbuild/libs/memory-v2.jar스프링 부트 자동 구성 기능이 포함된
memory-v2.jar를 이제 프로젝트에 적용해보자.기존 프로젝트를 유지하기 위해 새로운 프로젝트에 자동 구성 라이브러리를 적용해보자. 앞서 만든
project-v1과 비슷한 프로젝트이다.프로젝트 설정 순서
project-v2-start의 폴더 이름을project-v2으로 변경하자.File⇒Open⇒ 해당 프로젝트의build.gradle을 선택 ⇒ 선택창에서Open as Project선택build.gradle 확인
plugins { id 'org.springframework.boot' version '3.0.2' id 'io.spring.dependency-management' version '1.1.0' id 'java' } group = 'hello' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() }스프링 부트에서 다음 라이브러리를 선택했다.
Lombok,Spring Web프로젝트가 동작하는지 확인하기 위해 간단한 컨트롤러를 하나 추가하자.
HelloController
hello앞서 만든
memory-v2.jar라이브러리를project-v2에 적용해보자.라이브러리 추가
project-v2/libs폴더 생성memory-v2프로젝트에서 빌드한memory-v2.jar를 이곳에 복사project-v2/build.gradle에memory-v2.jar를 추가dependencies { implementation files('libs/memory-v2.jar') //추가 implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' }files로 지정하면 된다.gradle을 리로드하자.(1) 라이브러리 설정
project-v1에서는memory-v1을 사용하기 위해 스프링 빈을 직접 등록했다.project-v2에서 사용하는memory-v2라이브러리에는 스프링 부트 자동 구성이 적용되어 있다. 따라서, 빈을 등록하는 별도의 설정을 하지 않아도 된다.memory-v2의 자동 구성에는 다음과 같이 설정했기 때문에memory=on조건을 만족할 때만 실행된다.memory=on조건을 주고 실행해보자.-Dmemory=on을 사용해야 한다.메모리 조회 기능이 잘 동작하는지 확인해보자.
서버 실행 로그
실행
결과
(2) 정리
@ConditionalOnXxx덕분에 라이브러리 설정을 유연하게 제공할 수 있다.Beta Was this translation helpful? Give feedback.
All reactions