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
우리가 등록한 JdbcTemplate, DataSource, TransactionManager가 분명히 스프링 빈으로 등록되지 않았다는 것이다.
테스트는 정상 통과하고 심지어 출력결과에 JdbcTemplate, DataSource, TransactionManager 빈들이 존재하는 것을 확인할 수있다.
이 빈들은 모두 스프링 부트가 자동으로 등록해 준 것이다.
4️⃣ 스프링 부트의 자동 구성
스프링 부트는 자동 구성(Auto Configuration)이라는 기능을 제공하는데, 일반적으로 수 많은 빈들을 자동으로 등록해주는 기능이다.
jdbcTemplate, DataSource, TransactionManager 모두 스프링 부트가 자동 구성을 제공해서 자동으로 스프링 빈으로 등록된다.
이러한 자동 구성 덕분에 개발자는 반복적이고 복잡한 빈 등록과 설정을 최소화하고 애플리케이션 개발을 빠르게 시작할 수 있게됨.
/* * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */packageorg.springframework.boot.autoconfigure.jdbc;
importjavax.sql.DataSource;
importorg.springframework.boot.autoconfigure.AutoConfiguration;
importorg.springframework.boot.autoconfigure.EnableAutoConfiguration;
importorg.springframework.boot.autoconfigure.condition.ConditionalOnClass;
importorg.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
importorg.springframework.boot.context.properties.EnableConfigurationProperties;
importorg.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
importorg.springframework.context.annotation.Import;
importorg.springframework.jdbc.core.JdbcTemplate;
importorg.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
/** * {@link EnableAutoConfiguration Auto-configuration} for {@link JdbcTemplate} and * {@link NamedParameterJdbcTemplate}. * * @author Dave Syer * @author Phillip Webb * @author Stephane Nicoll * @author Kazuki Shimizu * @since 1.4.0 */@AutoConfiguration(after = DataSourceAutoConfiguration.class)
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(JdbcProperties.class)
@Import({ DatabaseInitializationDependencyConfigurer.class, JdbcTemplateConfiguration.class,
NamedParameterJdbcTemplateConfiguration.class })
publicclassJdbcTemplateAutoConfiguration {
}
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.
-
섹션6. 자동 구성(Auto Configuration)
1️⃣ 프로젝트 설정
✅ 프로젝트 설정 순서
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-jdbc' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' //테스트에서 lombok 사용 testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' } tasks.named('test') { useJUnitPlatform() }2️⃣ 예제 만들기
JdbcTemplate을 사용해서 회원을 관리하는 리포지토리
DbConfig에서 JdbcTemplate을 빈으로 등록했기 때문에 바로 주입받아서 사용할 수 있다.
initTable : 보통 리포지토리에 테이블을 생성하는 스크립트를 두지를 않는다. 여기서는 예제를 단순화 하기 위해 이곳에 사용했다
MemberRepositoryTest
3️⃣ 자동 구성 확인
해당 빈들을 DbConfig 설정을 통해 스프링 컨테이너에 등록했기 때문에, null이면 안된다.
테스트는 정상이고 모두 의존관계 주입이 정상 처리된 것을 확인할 수 있다.
출력 결과
➡️ 빈 등록 제거
jdbcTemplate, DataSource, TransactionManager 빈 모두 DbConfig를 통해서 스프링 컨테이너에 빈으로 등록되었다.
이번에는 DbConfig에서 해당 빈들을 등록하지 않고 제거
DbConfig 빈 등록 제거 방법 2가지
➡️ 기본 빈 등록 로그
4️⃣ 스프링 부트의 자동 구성
모든 것을 깊이있게 이해하지 않기 ! 대략 동작 원리만 감 잡고 천천히 강의로 풀어나가기
@autoConfiguration : 자동 구성을 사용하려면 이 애노테이션을 등록해야 한다.
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalXxx시리즈가 있다. 자동 구성의 핵심이므로 뒤에서 자세히 알아본다.JdbcTemplate은DataSource,JdbcTemplate라는 클래스가 있어야 동작할 수 있다.@import : 스프링에서 자바 설정을 추가할 때 사용한다.
@import의 대상이 되는 JdbcTemplateConfiguration를 추가로 확인해보자.
JdbcTemplateConfiuartion
자동 등록 설정
그래서 개발자가 직접 빈을 등록하지 않아도
JdbcTemplate,DataSource,TransactionManager가 스프링빈으로 등록된 것이다.✅ 스프링 부트가 제공하는 자동 구성(AutoConfiguration)
✅ AutoConfiguration -용어
➡️ 자동 설정
➡️ 자동 구성
Configuration 이라는 단어는 구성, 배치라는 뜻도 가지고 있다.
예) 컴퓨터라고 하면 CPU, 메모리등을 배치해야 컴퓨터가 동작한다. 이렇게 배치하는 것을 구성이라고 한다.
스프링도 스프링 실행에 필요한 빈들을 적절하게 배치해야 한다.
자동 구성은 스프링 실행에 필요한 빈들을 자동으로 배치해주는 것이다.
자동 설정, 자동 구성 두 용어 모두 맞는 말이다. 자동 설정은 넓게 사용되는 의미이고, 자동 구성은 실행에 필요한 컴포넌트 조각을 자동으로 배치한다는 더 좁은 의미에 가깝다.
Auto Configuration은 자동 구성이라는 단어를 주로 사용하고, 문맥에 따라서 자동 설정이라는 단어도 사용하겠다.
Configuration이 단독으로 사용될 때는 설정이라는 단어를 사용하겠다.
5️⃣ 자동 구성 직접 만들기 - 기반 예제
used : 사용중인 메모리
max : 최대 메모리
used가 max를 넘게 되면 메모리 부족 오류가 발생한다.
MemoryFinder
JVM에서 메모리 정보를 실시간으로 조회하는 기능이다.
max는 JVM이 사용할 수 있는 최대 메모리, 이 수치를 넘어가면 OOM이 발생한다.total은 JVM이 확보한 전체 메모리(JVM은 처음부터max까지 다 확보하지 않고 필요할 때 마다 조금씩 확보한다.)
free는total중에 사용하지 않은 메모리(JVM이 확보한 전체 메모리 중에 사용하지 않은 것)used는 JVM이 사용중인 메모리이다. (used = total - free)MemoryController
메모리 정보를 조회하는 컨트롤러이다.
앞서 만든 memoryFinder를 주입 받아 사용한다.
MemoryConfig
memoryController,memoryFinder를 빈으로 등록실행 결과
{"used":40477936,"max":4294967296}6️⃣ @conditional
앞서 만든 메모리 조회 기능을 향상. 사용하는 것이 아니라 특정 조건일 때만 해당 기능이 활성화 되도록 해보자.
예를 들어서 개발 서버에서 확인 용도로만 해당 기능을 사용하고, 운영 서버에서는 해당 기능을 사용하지 않는 것이다.
여기서 핵심은 소스코드를 고치지 않고 이런 것이 가능해야 한다는 점이다.
같은 소스 코드인데 특정 상황일 때만 특정 빈들을 등록해서 사용하도록 도와주는 기능이 바로 @conditional이다.
참고로 이 기능은 스프링 부트 자동 구성에서 자주 사용한다.
Condition
matches() 메서드가 true를 반환하면 조건에 만족해서 동작하고, false를 반환하면 동작하지 않는다.
ConditionContext : 스프링 컨테이너, 환경 정보등을 담고 있다.
AnnotatedTypeMetadata : 애노테이션 메타 정보를 담고 있다.
Condition 인터페이스를 구현해서 자바 시스템 속성이 memory=on이라고 되어 있을 때만 메모리 기능이 동작하도록 만들어보자.
@conditional(MemoryCondition.class)
결과
{"used":38952680,"max":4294967296}7️⃣ @conditional - 다양한 기능
@Conditional을 사용한다. 그리고 그 안에
Condition인터페이스를 구현한OnPropertyCondition를 가지고 있다.✅@ConditionalOnXxx
스프링은 @conditional과 관련해서 개발자가 편리하게 사용할 수 있도록 수 많은 @ConditionalOnXxx를 제공한다.
대표적인 몇가지를 알아보자.
@ConditionalOnClass,@ConditionalOnMissingClass클래스가 있는 경우 동작한다. 나머지는 그 반대
@ConditionalOnBean,@ConditionalOnMissingBean@ConditionalOnProperty@ConditionalOnResource@ConditionalOnWebApplication,@ConditionalOnNotWebApplication@ConditionalOnExpressionConditionalOnXXX 공식 메뉴얼
8️⃣ 순수 라이브러리 만들기
참고로 라이브러리를 만들 떄는 스프링 부트 플러그인 기능을 사용하지 않고 진행한다.
➡️ 프로젝트 설정 순서
9️⃣ 순수한 라이브러리 사용하기 1
✅ 프로젝트 설정
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() }🔟 순수한 라이브러리 사용하기 2
memory-v1.jar라이브러리를project-v1에 적용라이브러리 추가
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' }MemoryFinder : init memoryFinder1️⃣1️⃣ 자동 구성 라이브러리 만들기
만든 라이브러리를 사용해주는 고객을 위해 프로젝트에 라이브러리를 추가만 하면 모든 구성이 자동으로 처리되도록 만들어보자.
@autoConfiguration
@ConditionalOnProperty
➡️자동 구성 대상 지정
부트 자동 구성을 적용하려면 다음 파일에 자동 구성 대상을 꼭 지정해줘야함
파일 생성
src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
1️⃣2️⃣ 자동 구성 라이브러리 사용하기 1
기존 프로젝트를 유지하기 위해 새로운 프로젝트에 자동 구성 라이브러리를 적용
✅ 프로젝트 설정
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() }1️⃣3️⃣ 자동 구성 라이브러리 사용하기 2
➡️라이브러리 추가
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' }lib가 아니라libs인 점을 주의하자!➡️ 라이브러리 설정
Beta Was this translation helpful? Give feedback.
All reactions