728x90
SringApplication
context = this.createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
우리가 사용하는 SpringApplication이 실행되면 application context를 생성하고, 초기화 작업이 수행된다. 여기서 빈이 등록되는 부분은 this.refreshContext을 호출하는 라인이며 기본적으로 DefaultListableBeanFactory를 이용하게 된다.
DefaultListableBeanFactory
본격적으로 Bean을 등록하기 위해서 PostProcessorRegistrationDelegate에서 등록된 Post processor를 수행하며 ClassPathBeanDefinitionScanner에서 등록된 base package 하위 .class 파일을 순회하며 Bean definition을 수집한다.
AbstractAutowireCapableBeanFactory
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
...
} else {
return this.autowireConstructor(beanName, mbd, ctors, args);
}
}
ConstructorResolver
for(int paramIndex = 0; paramIndex < paramTypes.length; ++paramIndex) {
Class<?> paramType = paramTypes[paramIndex];
String paramName = paramNames != null ? paramNames[paramIndex] : "";
...
Object sourceHolder;
if (valueHolder != null) {
...
} else {
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
if (!autowiring) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Ambiguous argument values for parameter of type [" + paramType.getName() + "] - did you specify the correct bean references as arguments?");
}
try {
ConstructorDependencyDescriptor desc = new ConstructorDependencyDescriptor(methodParam, true);
Set<String> autowiredBeanNames = new LinkedHashSet(2);
sourceHolder = this.resolveAutowiredArgument(desc, paramType, beanName, autowiredBeanNames, (TypeConverter)converter, fallback);
if (sourceHolder != null) {
this.setShortcutIfPossible(desc, paramType, autowiredBeanNames);
}
allAutowiredBeanNames.addAll(autowiredBeanNames);
args.rawArguments[paramIndex] = sourceHolder;
args.arguments[paramIndex] = sourceHolder;
args.preparedArguments[paramIndex] = desc;
args.resolveNecessary = true;
} catch (BeansException var25) {
...
}
}
}
실질적으로 Bean instance가 생성되는 곳으로, 생성자 주입 방식을 사용하는 Bean의 경우 주입받는 하위 Bean을 차례대로 생성하며, 최종적으로 대상 Bean이 생성된다.
'공부' 카테고리의 다른 글
Redis cluster spec (0) | 2024.09.22 |
---|---|
교육 AI (0) | 2024.06.09 |
🍎 레디스 톺아보기 - pub/sub (0) | 2023.12.19 |
🍎 레디스 톺아보기 - 데이터 타입 이해하기 (0) | 2023.12.17 |
JWT 인가 처리, 이거 모르면 제발 Spring security 쓰지 마세요. (0) | 2023.11.19 |