springboot 에서@Value 의 작업 원리 설명
7621 단어 springboot@Value
다음은@Value 의 작업 원 리 를 간략하게 분석 하 겠 습 니 다.
springboot 버 전:springboot-2.0.6.RELEASE
개술
springboot 시작 과정 에서 두 가지 중요 한 과정 이 있 습 니 다.다음 과 같 습 니 다.
1.용기 에 있 는 bean 을 스 캔 하여 beanFactory 에 등록 하 는 것 은 마치 정보 등록 과 같다.
2 스 캔 한 bean 을 실례 화하 고 초기 화 합 니 다.
@Value 의 해석 은 두 번 째 단계 입 니 다.BeanPostProcessor 는 bean 초기 화 전후 사용자 가 bean 을 조작 할 수 있 는 인터페이스 방법 을 정의 합 니 다.중요 한 실현 클래스 인 Autowired Annotation BeanPostProcessor 는 javadoc 가 말 한 것 처럼 bean 의@Autowired 와@Value 주해 의 주입 기능 을 지원 합 니 다.
해석 절차
호출 체인 순차 도
@Value 분석 과정 에서 주요 호출 체인 은 다음 순서 그림 으로 표시 합 니 다.
여기 서 먼저 그림 의 몇 가지 작용 을 간단하게 소개 합 니 다.
AbstractAutowireCapableBeanFactory
bean 생 성,속성 충전,자동 조립,초기 후 를 제공 합 니 다.자동 조립 구조 함 수 를 지원 하고 속성 은 이름과 유형 에 따라 조립 합 니 다.AutowireCapableBeanFactory 인터페이스 정 의 를 실현 한 createBean 방법 입 니 다.AutowiredAnnotationBeanPostProcessor
bean 에 표 시 된 구성원 변수,setter 방법,임 의 설정 방법 을 사용 합 니 다.전형 적 인 것 은@Autowired 주해 와@Value 주해 입 니 다.InjectionMetadata
클래스 의 주입 메타 데이터,클래스 의 방법 이나 속성 등 이 있 을 수 있 습 니 다.Autowired Annotation BeanPostProcessor 류 에서 사 용 됩 니 다.AutowiredFieldElement
Autowired Annotation BeanPostProcessor 의 개인 내부 클래스 로 Injection Metadata.Injected Element 를 계승 하여 주 해 를 설명 하 는 필드 입 니 다.StringValueResolver
:문자열 값 을 처리 하 는 인 터 페 이 스 를 정의 합 니 다.인터페이스 방법 인 resolve StringValue 만 있 습 니 다.자리 차지 문자 문자열 을 해결 할 수 있 습 니 다.본 논문 의 주요 실현 클래스 는 Property SourcesPlaceholder Configure\#processProperties 방법 에서 lamda 표현 식 을 통 해 정 의 됩 니 다.ConfigurableBeanFactory 클래스 에서 사용 할 수 있 습 니 다.PropertySourcesPropertyResolver
속성 자원 프로세서,주요 기능 은 Property Sources 속성 자원 의 설정 키 쌍 을 가 져 오 는 것 입 니 다.PropertyPlaceholderHelper
자리 표시 자 를 가 진 문자열 을 처리 하 는 도구 클래스 입 니 다.${name}과 같은 문자열 은 이 도구 류 의 도움 을 받 아 사용자 가 제공 하 는 값 으로 대체 할 수 있 습 니 다.대체 경 로 는 Properties 인 스 턴 스 나 Placeholder Resolver(내부 정의 인터페이스)를 통 해 이 루어 질 수 있 습 니 다.PropertyPlaceholderConfigurerResolver
:이전 줄 에서 말 한 Placeholder Resolver 인터페이스의 실현 류 는 Property Placeholder Configure 류 의 개인 내부 류 입 니 다.구현 방법 resolve Placeholder 에서 외부 클래스 의 resolve Placeholder 방법 을 호출 하 였 습 니 다.호출 체인 설명
여기 서 주로 체인 을 호출 하 는 비교적 중요 한 방법 을 소개 한다.
AbstractAutowireCapableBeanFactory\#populateBean 방법 은 bean 속성 을 채 우 는 데 사용 되 며,실행 후 속성 조립 후의 bean 을 얻 을 수 있 습 니 다.
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
...
if (hasInstAwareBpps) {
// InstantiationAwareBeanPostProcessor 。
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// AutowiredAnnotationBeanPostProcessor
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
// ,bw.getWrappedInstance() @Value bean
if (pvs == null) {
return;
}
}
}
}
...
}
InjectionMetadata\#inject 는 bean 의 설정 속성 을 하나씩 조립 합 니 다.
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
//
for (InjectedElement element : elementsToIterate) {
if (logger.isDebugEnabled()) {
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
PropertyPlaceholder Helper\#parseStringValue 분석 속성 값
/**
* value = "${company.ceo}"
*
*/
protected String parseStringValue(
String value, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) {
StringBuilder result = new StringBuilder(value);
// this.placeholderPrefix = "${"
int startIndex = value.indexOf(this.placeholderPrefix);
while (startIndex != -1) {
// , value = "${company.ceo}" ,endIndex=13
int endIndex = findPlaceholderEndIndex(result, startIndex);
if (endIndex != -1) {
// {} , "company.ceo"
String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);
String originalPlaceholder = placeholder;
if (!visitedPlaceholders.add(originalPlaceholder)) {
throw new IllegalArgumentException(
"Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
}
// Recursive invocation, parsing placeholders contained in the placeholder key.
// ,
placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
// Now obtain the value for the fully resolved key...
// placeholder
String propVal = placeholderResolver.resolvePlaceholder(placeholder);
// company.ceo=${bi:li} ,company.ceo li
// , ${} , spring
if (propVal == null && this.valueSeparator != null) {
int separatorIndex = placeholder.indexOf(this.valueSeparator);
if (separatorIndex != -1) {
String actualPlaceholder = placeholder.substring(0, separatorIndex);
String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
if (propVal == null) {
propVal = defaultValue;
}
}
}
if (propVal != null) {
// Recursive invocation, parsing placeholders contained in the
// previously resolved placeholder value.
propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
// ${company.ceo} li
result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
if (logger.isTraceEnabled()) {
logger.trace("Resolved placeholder '" + placeholder + "'");
}
startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());
}
else if (this.ignoreUnresolvablePlaceholders) {
// Proceed with unprocessed value.
startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
}
else {
throw new IllegalArgumentException("Could not resolve placeholder '" +
placeholder + "'" + " in value \"" + value + "\"");
}
visitedPlaceholders.remove(originalPlaceholder);
}
else {
startIndex = -1;
}
}
return result.toString();
}
총결산@Value 주석 에 표 시 된 bean 속성 조립 은 Autowired Annotation BeanPostProcessor 에 의 해 bean 의 예화,초기 화 단계 에서 이 루어 졌 습 니 다.이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin Springboot -- 파트 14 사용 사례 REST로 전환하여 POST로 JSON으로 전환前回 前回 前回 記事 の は は で で で で で で を 使っ 使っ 使っ て て て て て リクエスト を を 受け取り 、 reqeustbody で 、 その リクエスト の ボディ ボディ を を 受け取り 、 関数 内部 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.