mirror of
https://github.com/youthlql/JavaYouth.git
synced 2026-04-15 22:45:08 +00:00
1808 lines
71 KiB
Markdown
1808 lines
71 KiB
Markdown
---
|
||
title: Spring源码系列-第5章-容器刷新流程
|
||
tags:
|
||
- Spring源码
|
||
categories:
|
||
- Spring
|
||
- 源码V1
|
||
keywords: Spring,框架,spring源码
|
||
description: 容器刷新全流程
|
||
cover: 'https://npm.elemecdn.com/lql_static@latest/logo/spring.png'
|
||
abbrlink: a1b8c236
|
||
date: 2022-02-13 18:01:02
|
||
---
|
||
|
||
|
||
|
||
# 第5章-容器刷新流程
|
||
|
||
## 流程图-容器刷新
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.7/spring-sourcecode-v1/flow_chart/%E5%AE%B9%E5%99%A8%E5%88%B7%E6%96%B0%E6%B5%81%E7%A8%8B.jpg">
|
||
|
||
## 容器创建
|
||
|
||
```java
|
||
public class AnnotationMainTest {
|
||
|
||
public static void main(String[] args) {
|
||
|
||
ApplicationContext applicationContext =
|
||
new AnnotationConfigApplicationContext(MainConfig.class);
|
||
}
|
||
```
|
||
|
||
|
||
|
||
### AnnotationConfigApplicationContext有参构造
|
||
|
||
```java
|
||
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
|
||
this();
|
||
register(componentClasses);
|
||
refresh(); //容器完整刷新(创建出所有组件,组织好所有功能)
|
||
}
|
||
```
|
||
|
||
#### AnnotationConfigApplicationContext#this()无参构造
|
||
|
||
```java
|
||
// 上面的this()就是调用的这里
|
||
public AnnotationConfigApplicationContext() {
|
||
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
|
||
this.reader = new AnnotatedBeanDefinitionReader(this);
|
||
createAnnotatedBeanDefReader.end();
|
||
this.scanner = new ClassPathBeanDefinitionScanner(this);
|
||
}
|
||
```
|
||
|
||
##### AnnotatedBeanDefinitionReader有参构造
|
||
|
||
```java
|
||
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
|
||
this(registry, getOrCreateEnvironment(registry));
|
||
}
|
||
|
||
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
|
||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
||
Assert.notNull(environment, "Environment must not be null");
|
||
this.registry = registry;
|
||
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
|
||
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
|
||
}
|
||
```
|
||
|
||
##### AnnotationConfigUtils#registerAnnotationConfigProcessors()注册Spring内部几个核心组件
|
||
|
||
```java
|
||
/**
|
||
* The bean name of the internally managed Configuration annotation processor.
|
||
*/
|
||
public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =
|
||
"org.springframework.context.annotation.internalConfigurationAnnotationProcessor";
|
||
|
||
/**
|
||
* The bean name of the internally managed BeanNameGenerator for use when processing
|
||
* {@link Configuration} classes. Set by {@link AnnotationConfigApplicationContext}
|
||
* and {@code AnnotationConfigWebApplicationContext} during bootstrap in order to make
|
||
* any custom name generation strategy available to the underlying
|
||
* {@link ConfigurationClassPostProcessor}.
|
||
* @since 3.1.1
|
||
*/
|
||
public static final String CONFIGURATION_BEAN_NAME_GENERATOR =
|
||
"org.springframework.context.annotation.internalConfigurationBeanNameGenerator";
|
||
|
||
/**
|
||
* The bean name of the internally managed Autowired annotation processor.
|
||
*/
|
||
public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
|
||
"org.springframework.context.annotation.internalAutowiredAnnotationProcessor";
|
||
|
||
/**
|
||
* The bean name of the internally managed Required annotation processor.
|
||
* @deprecated as of 5.1, since no Required processor is registered by default anymore
|
||
*/
|
||
@Deprecated
|
||
public static final String REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
|
||
"org.springframework.context.annotation.internalRequiredAnnotationProcessor";
|
||
|
||
/**
|
||
* The bean name of the internally managed JSR-250 annotation processor.
|
||
*/
|
||
public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME =
|
||
"org.springframework.context.annotation.internalCommonAnnotationProcessor";
|
||
|
||
/**
|
||
* The bean name of the internally managed JPA annotation processor.
|
||
*/
|
||
public static final String PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME =
|
||
"org.springframework.context.annotation.internalPersistenceAnnotationProcessor";
|
||
|
||
private static final String PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME =
|
||
"org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor";
|
||
|
||
/**
|
||
* The bean name of the internally managed @EventListener annotation processor.
|
||
*/
|
||
public static final String EVENT_LISTENER_PROCESSOR_BEAN_NAME =
|
||
"org.springframework.context.event.internalEventListenerProcessor";
|
||
|
||
/**
|
||
* The bean name of the internally managed EventListenerFactory.
|
||
*/
|
||
public static final String EVENT_LISTENER_FACTORY_BEAN_NAME =
|
||
"org.springframework.context.event.internalEventListenerFactory";
|
||
|
||
|
||
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
|
||
registerAnnotationConfigProcessors(registry, null);
|
||
}
|
||
|
||
|
||
|
||
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
|
||
BeanDefinitionRegistry registry, @Nullable Object source) {
|
||
|
||
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
|
||
if (beanFactory != null) {
|
||
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
|
||
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
|
||
}
|
||
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
|
||
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
|
||
}
|
||
}
|
||
|
||
//下面是注册Spring底层的核心组件,主要是就是Spring自己的BeanPostproPostProcessor或者BeanFactoryPostProcessor
|
||
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
|
||
//注册底层的 配置文件处理器
|
||
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
|
||
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
|
||
def.setSource(source);
|
||
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
|
||
}
|
||
//注册底层的自动装配处理器
|
||
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
|
||
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
|
||
def.setSource(source);
|
||
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
|
||
}
|
||
//注册支持JSR-250的处理
|
||
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
|
||
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
|
||
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
|
||
def.setSource(source);
|
||
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
|
||
}
|
||
|
||
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
|
||
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
|
||
RootBeanDefinition def = new RootBeanDefinition();
|
||
try {
|
||
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
|
||
AnnotationConfigUtils.class.getClassLoader()));
|
||
}
|
||
catch (ClassNotFoundException ex) {
|
||
throw new IllegalStateException(
|
||
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
|
||
}
|
||
def.setSource(source);
|
||
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
|
||
}
|
||
|
||
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
|
||
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
|
||
def.setSource(source);
|
||
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
|
||
}
|
||
|
||
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
|
||
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
|
||
def.setSource(source);
|
||
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
|
||
}
|
||
|
||
return beanDefs;
|
||
}
|
||
|
||
```
|
||
|
||
上面的方法走完,我们可以看看到主要是下面4个后置处理器
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211008212541000.png"/>
|
||
|
||
##### RootBeanDefinition
|
||
|
||
```java
|
||
public RootBeanDefinition(@Nullable Class<?> beanClass) {
|
||
super();
|
||
setBeanClass(beanClass);
|
||
}
|
||
```
|
||
|
||
##### AbstractBeanDefinition
|
||
|
||
```java
|
||
protected AbstractBeanDefinition() {
|
||
this(null, null);
|
||
}
|
||
```
|
||
|
||
##### ClassPathBeanDefinitionScanner
|
||
|
||
```java
|
||
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
|
||
Environment environment, @Nullable ResourceLoader resourceLoader) {
|
||
|
||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
||
this.registry = registry;
|
||
|
||
if (useDefaultFilters) {
|
||
registerDefaultFilters();
|
||
}
|
||
setEnvironment(environment); //准备环境
|
||
setResourceLoader(resourceLoader);//准备资源加载器
|
||
}
|
||
```
|
||
|
||
#### AnnotationConfigApplicationContext#register()
|
||
|
||
```java
|
||
public void register(Class<?>... componentClasses) {
|
||
//componentClasses就是咱们的配置类
|
||
Assert.notEmpty(componentClasses, "At least one component class must be specified");
|
||
StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
|
||
.tag("classes", () -> Arrays.toString(componentClasses));
|
||
this.reader.register(componentClasses);
|
||
registerComponentClass.end();
|
||
}
|
||
```
|
||
|
||
|
||
|
||
##### AnnotatedBeanDefinitionReader#register()注册主配置类BeanDefinition
|
||
|
||
```java
|
||
public void register(Class<?>... componentClasses) {
|
||
for (Class<?> componentClass : componentClasses) {
|
||
registerBean(componentClass);
|
||
}
|
||
}
|
||
|
||
public void registerBean(Class<?> beanClass) {
|
||
doRegisterBean(beanClass, null, null, null, null);
|
||
}
|
||
|
||
|
||
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
|
||
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
|
||
@Nullable BeanDefinitionCustomizer[] customizers) {
|
||
|
||
// 主配置类也被封装成一个Bean定义信息了
|
||
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
|
||
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
|
||
return;
|
||
}
|
||
|
||
abd.setInstanceSupplier(supplier);
|
||
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
|
||
abd.setScope(scopeMetadata.getScopeName());
|
||
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
|
||
//完善主配置类的BeanDefinition
|
||
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
|
||
if (qualifiers != null) {
|
||
for (Class<? extends Annotation> qualifier : qualifiers) {
|
||
if (Primary.class == qualifier) {
|
||
abd.setPrimary(true);
|
||
}
|
||
else if (Lazy.class == qualifier) {
|
||
abd.setLazyInit(true);
|
||
}
|
||
else {
|
||
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
|
||
}
|
||
}
|
||
}
|
||
if (customizers != null) {
|
||
for (BeanDefinitionCustomizer customizer : customizers) {
|
||
customizer.customize(abd);
|
||
}
|
||
}
|
||
|
||
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
|
||
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
|
||
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
|
||
}
|
||
|
||
```
|
||
|
||
|
||
|
||
##### AnnotationConfigUtils#processCommonDefinitionAnnotations()感知@Lazy,@Primary等注解
|
||
|
||
这里传进来的是主配置类,解析的就是主配置类的注解,其它的Bean这里还没有解析@Lazy,@Primary这些注解
|
||
|
||
```java
|
||
public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
|
||
processCommonDefinitionAnnotations(abd, abd.getMetadata());
|
||
}
|
||
//解读所有Bean定义信息需要感知的注解
|
||
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
|
||
AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
|
||
if (lazy != null) {
|
||
abd.setLazyInit(lazy.getBoolean("value"));
|
||
}
|
||
else if (abd.getMetadata() != metadata) {
|
||
lazy = attributesFor(abd.getMetadata(), Lazy.class);
|
||
if (lazy != null) {
|
||
abd.setLazyInit(lazy.getBoolean("value"));
|
||
}
|
||
}
|
||
|
||
if (metadata.isAnnotated(Primary.class.getName())) {
|
||
abd.setPrimary(true);
|
||
}
|
||
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
|
||
if (dependsOn != null) {
|
||
abd.setDependsOn(dependsOn.getStringArray("value"));
|
||
}
|
||
|
||
AnnotationAttributes role = attributesFor(metadata, Role.class);
|
||
if (role != null) {
|
||
abd.setRole(role.getNumber("value").intValue());
|
||
}
|
||
AnnotationAttributes description = attributesFor(metadata, Description.class);
|
||
if (description != null) {
|
||
abd.setDescription(description.getString("value"));
|
||
}
|
||
}
|
||
```
|
||
|
||
走完之后,注册中心肯定多了咱们的配置类
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211008213900796.png"/>
|
||
|
||
|
||
|
||
1. 接下来就是想办法让主配置类里的配置生效
|
||
2. 目前Spring就靠上面的4个后置处理器和一个主配置类白手起家了,开始我们后面最重要的refresh()容器刷新流程了
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
## AbstractApplicationContext#refresh()开始容器刷新
|
||
|
||
```java
|
||
@Override //容器刷新的十二大步。模板模式
|
||
public void refresh() throws BeansException, IllegalStateException {
|
||
synchronized (this.startupShutdownMonitor) {
|
||
//容器启动过程状态的封装类
|
||
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
|
||
|
||
//准备上下文环境 Prepare this context for refreshing.
|
||
prepareRefresh();
|
||
|
||
// Tell the subclass to refresh the internal bean factory.
|
||
// 工厂创建:BeanFactory第一次开始创建的时候,有xml解析逻辑。注解版这一步什么都没做,直接返回this()环节早就new好的工厂
|
||
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
|
||
|
||
//给容器中注册了环境信息作为单实例Bean方便后续自动装配;放了一些后置处理器处理(监听、xxAware功能) Prepare thebean factory for use in this context.
|
||
prepareBeanFactory(beanFactory);
|
||
|
||
try {
|
||
//留给子类的模板方法,允许子类继续对工厂执行一些处理; Allows post-processing of the bean factory in context subclasses.
|
||
postProcessBeanFactory(beanFactory);
|
||
|
||
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
|
||
//【核心】工厂增强:执行所有的BeanFactory后置增强器;利用BeanFactory后置增强器对工厂进行修改或者增强,配置类会在这里进行解析。 Invoke factory processors registered as beans in the context.
|
||
invokeBeanFactoryPostProcessors(beanFactory);
|
||
|
||
//【核心】注册所有的Bean的后置处理器 Register bean processors that intercept bean creation.
|
||
registerBeanPostProcessors(beanFactory);
|
||
beanPostProcess.end();
|
||
|
||
//初始化国际化功能 Initialize message source for this context.
|
||
initMessageSource();
|
||
|
||
//初始化事件多播功能(事件派发) Initialize event multicaster for this context.
|
||
initApplicationEventMulticaster();
|
||
|
||
// Initialize other special beans in specific context subclasses.
|
||
onRefresh();
|
||
|
||
//注册监听器,从容器中获取所有的ApplicationListener; Check for listener beans and register them.
|
||
registerListeners();
|
||
|
||
// Instantiate all remaining (non-lazy-init) singletons.
|
||
//【大核心】bean创建;完成 BeanFactory 初始化。(工厂里面所有的组件都好了)
|
||
finishBeanFactoryInitialization(beanFactory);
|
||
|
||
//发布事件 Last step: publish corresponding event.
|
||
finishRefresh();
|
||
}
|
||
|
||
catch (BeansException ex) {
|
||
if (logger.isWarnEnabled()) {
|
||
logger.warn("Exception encountered during context initialization - " +
|
||
"cancelling refresh attempt: " + ex);
|
||
}
|
||
|
||
// Destroy already created singletons to avoid dangling resources.
|
||
destroyBeans();
|
||
|
||
// Reset 'active' flag.
|
||
cancelRefresh(ex);
|
||
|
||
// Propagate exception to caller.
|
||
throw ex;
|
||
}
|
||
|
||
finally {
|
||
// Reset common introspection caches in Spring's core, since we
|
||
// might not ever need metadata for singleton beans anymore...
|
||
resetCommonCaches();
|
||
contextRefresh.end();
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
|
||
### prepareRefresh()准备上下文环境
|
||
|
||
```java
|
||
protected void prepareRefresh() {
|
||
// Switch to active.
|
||
this.startupDate = System.currentTimeMillis();
|
||
this.closed.set(false);
|
||
this.active.set(true);
|
||
|
||
if (logger.isDebugEnabled()) {
|
||
if (logger.isTraceEnabled()) {
|
||
logger.trace("Refreshing " + this);
|
||
}
|
||
else {
|
||
logger.debug("Refreshing " + getDisplayName());
|
||
}
|
||
}
|
||
|
||
//其他子容器自行实现(比如:WebApplicationContext) Initialize any placeholder property sources in the context environment.
|
||
initPropertySources();
|
||
|
||
//准备环境变量信息 Validate that all properties marked as required are resolvable:
|
||
// see ConfigurablePropertyResolver#setRequiredProperties
|
||
getEnvironment().validateRequiredProperties();
|
||
|
||
// 存储子容器早期运行的一些监听器; Store pre-refresh ApplicationListeners...
|
||
if (this.earlyApplicationListeners == null) {
|
||
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
|
||
}
|
||
else {
|
||
// Reset local application listeners to pre-refresh state.
|
||
this.applicationListeners.clear();
|
||
this.applicationListeners.addAll(this.earlyApplicationListeners);
|
||
}
|
||
|
||
//早期的一些事件存储到这里 Allow for the collection of early ApplicationEvents,
|
||
// to be published once the multicaster is available...
|
||
this.earlyApplicationEvents = new LinkedHashSet<>();
|
||
}
|
||
```
|
||
|
||
#### initPropertySources()
|
||
|
||
```java
|
||
protected void initPropertySources() {
|
||
// For subclasses: do nothing by default. 自行在此处加载一些自己感兴趣的信息。【WebApplicationContextUtils.initServletPropertySources】
|
||
// web-ioc容器启动的时候一般在此加载当前应用的上下文信息(ApplicationContext)
|
||
}
|
||
```
|
||
|
||
|
||
|
||
### prepareBeanFactory()给BeanFactory准备一些核心组件
|
||
|
||
```java
|
||
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
|
||
// Tell the internal bean factory to use the context's class loader etc.
|
||
beanFactory.setBeanClassLoader(getClassLoader());
|
||
if (!shouldIgnoreSpel) { //解释器模式 ,解析el表达式
|
||
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
|
||
}
|
||
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
|
||
|
||
// Configure the bean factory with context callbacks.
|
||
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); //准备一个处理Aware接口功能的后置处理器
|
||
beanFactory.ignoreDependencyInterface(EnvironmentAware.class); //告诉Spring先别管这些接口
|
||
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
|
||
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
|
||
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
|
||
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
|
||
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
|
||
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
|
||
|
||
/*
|
||
1.注册可以解析到的依赖,直接保存到容器的resolvableDependencies池里
|
||
2.意思就是在我们自定义的类中,我们可以直接用@Autowired注解注入下面4个东西,并直接使用
|
||
*/
|
||
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
|
||
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
|
||
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
|
||
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
|
||
|
||
// 注册应用监听器的探测器,用来探测应用中有哪些监听器。这也是一个后置处理器
|
||
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
|
||
|
||
// Detect a LoadTimeWeaver and prepare for weaving, if found.
|
||
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
|
||
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
|
||
// Set a temporary ClassLoader for type matching.
|
||
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
|
||
}
|
||
|
||
//注册默认组件: Register default environment beans.
|
||
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
|
||
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
|
||
}
|
||
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
|
||
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
|
||
}
|
||
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
|
||
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
|
||
}
|
||
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
|
||
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
|
||
}
|
||
}
|
||
|
||
String ENVIRONMENT_BEAN_NAME = "environment";
|
||
|
||
String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
|
||
|
||
String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";
|
||
|
||
/**
|
||
* Name of the {@link ApplicationStartup} bean in the factory.
|
||
* @since 5.3
|
||
*/
|
||
String APPLICATION_STARTUP_BEAN_NAME = "applicationStartup";
|
||
|
||
```
|
||
|
||
|
||
|
||
### postProcessBeanFactory()留给子类的模板方法
|
||
|
||
这里是一个空方法,主要是留给子类实现,比如Web里的
|
||
|
||
```java
|
||
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
|
||
}
|
||
```
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009105903816.png"/>
|
||
|
||
|
||
|
||
|
||
|
||
### invokeBeanFactoryPostProcessors()工厂增强【核心】
|
||
|
||
```java
|
||
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
|
||
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); //执行所有的工厂增强器
|
||
//上面的类叫:后置处理器的注册代理(门面模式-装饰模式)
|
||
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
|
||
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
|
||
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
|
||
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
|
||
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
|
||
}
|
||
}
|
||
```
|
||
|
||
这一步有个很关键的后置处理器
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009113419863.png"/>
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009114151034.png"/>
|
||
|
||
|
||
|
||
#### ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry()开始解析@Configuration标注的所有配置类相关信息,并生成Bean
|
||
|
||
`AnnotationConfigApplicationContext#register()`这里解析的是主配置类
|
||
|
||
```java
|
||
@Override //把配置类中所有bean的定义信息导入进来。
|
||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
|
||
int registryId = System.identityHashCode(registry);
|
||
if (this.registriesPostProcessed.contains(registryId)) {
|
||
throw new IllegalStateException(
|
||
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
|
||
}
|
||
if (this.factoriesPostProcessed.contains(registryId)) {
|
||
throw new IllegalStateException(
|
||
"postProcessBeanFactory already called on this post-processor against " + registry);
|
||
}
|
||
this.registriesPostProcessed.add(registryId);
|
||
|
||
processConfigBeanDefinitions(registry); //处理配置的BeanDefinition信息
|
||
}
|
||
|
||
|
||
|
||
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
|
||
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
|
||
String[] candidateNames = registry.getBeanDefinitionNames(); //拿到工厂所有的bean定义信息
|
||
|
||
for (String beanName : candidateNames) {
|
||
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
|
||
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
|
||
if (logger.isDebugEnabled()) {
|
||
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
|
||
}
|
||
}
|
||
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
|
||
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); //将配置类加到候选集合里面,等待处理
|
||
}
|
||
}
|
||
|
||
// Return immediately if no @Configuration classes were found
|
||
if (configCandidates.isEmpty()) {
|
||
return;
|
||
}
|
||
|
||
// 对所有的配置类进行排序,Sort by previously determined @Order value, if applicable
|
||
configCandidates.sort((bd1, bd2) -> {
|
||
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
|
||
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
|
||
return Integer.compare(i1, i2);
|
||
});
|
||
|
||
// Detect any custom bean name generation strategy supplied through the enclosing application context
|
||
SingletonBeanRegistry sbr = null;
|
||
if (registry instanceof SingletonBeanRegistry) {
|
||
sbr = (SingletonBeanRegistry) registry;
|
||
if (!this.localBeanNameGeneratorSet) {
|
||
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
|
||
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR); //getBean--getSingleton,获取创建一个internalConfigurationBeanNameGenerator来用来生成配置类的名字
|
||
if (generator != null) {
|
||
this.componentScanBeanNameGenerator = generator;
|
||
this.importBeanNameGenerator = generator;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (this.environment == null) {
|
||
this.environment = new StandardEnvironment();
|
||
}
|
||
|
||
//由ConfigurationClassParser解析每一个配置类 Parse each @Configuration class
|
||
ConfigurationClassParser parser = new ConfigurationClassParser(
|
||
this.metadataReaderFactory, this.problemReporter, this.environment,
|
||
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
|
||
|
||
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
|
||
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
|
||
do {
|
||
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
|
||
parser.parse(candidates); //解析配置类;所有需要扫描进来的组件的BeanDefinition信息都已经完成
|
||
parser.validate();
|
||
|
||
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
|
||
configClasses.removeAll(alreadyParsed);
|
||
//每一个组件都可以当配置类,@Import之类的都能进行处理
|
||
// Read the model and create bean definitions based on its content
|
||
if (this.reader == null) {
|
||
this.reader = new ConfigurationClassBeanDefinitionReader(
|
||
registry, this.sourceExtractor, this.resourceLoader, this.environment,
|
||
this.importBeanNameGenerator, parser.getImportRegistry());
|
||
}
|
||
this.reader.loadBeanDefinitions(configClasses);
|
||
alreadyParsed.addAll(configClasses);
|
||
processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
|
||
|
||
candidates.clear();
|
||
if (registry.getBeanDefinitionCount() > candidateNames.length) {
|
||
String[] newCandidateNames = registry.getBeanDefinitionNames();
|
||
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
|
||
Set<String> alreadyParsedClasses = new HashSet<>();
|
||
for (ConfigurationClass configurationClass : alreadyParsed) {
|
||
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
|
||
}
|
||
for (String candidateName : newCandidateNames) {
|
||
if (!oldCandidateNames.contains(candidateName)) {
|
||
BeanDefinition bd = registry.getBeanDefinition(candidateName);
|
||
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
|
||
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
|
||
candidates.add(new BeanDefinitionHolder(bd, candidateName));
|
||
}
|
||
}
|
||
}
|
||
candidateNames = newCandidateNames;
|
||
}
|
||
}
|
||
while (!candidates.isEmpty());
|
||
|
||
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
|
||
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
|
||
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
|
||
}
|
||
|
||
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
|
||
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
|
||
// for a shared cache since it'll be cleared by the ApplicationContext.
|
||
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009115044348.png"/>
|
||
|
||
|
||
|
||
#### ConfigurationClassParser#parse()
|
||
|
||
```java
|
||
public void parse(Set<BeanDefinitionHolder> configCandidates) {
|
||
for (BeanDefinitionHolder holder : configCandidates) {
|
||
BeanDefinition bd = holder.getBeanDefinition();
|
||
try {
|
||
if (bd instanceof AnnotatedBeanDefinition) {
|
||
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
|
||
}
|
||
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
|
||
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
|
||
}
|
||
else {
|
||
parse(bd.getBeanClassName(), holder.getBeanName());
|
||
}
|
||
}
|
||
catch (BeanDefinitionStoreException ex) {
|
||
throw ex;
|
||
}
|
||
catch (Throwable ex) {
|
||
throw new BeanDefinitionStoreException(
|
||
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
|
||
}
|
||
}
|
||
|
||
this.deferredImportSelectorHandler.process();
|
||
}
|
||
|
||
|
||
//解析配置类
|
||
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
|
||
processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
|
||
}
|
||
|
||
|
||
|
||
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
|
||
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
|
||
return;
|
||
}
|
||
//Spring底层大量使用缓存来保证框架速度
|
||
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
|
||
if (existingClass != null) {
|
||
if (configClass.isImported()) {
|
||
if (existingClass.isImported()) {
|
||
existingClass.mergeImportedBy(configClass);
|
||
}
|
||
// Otherwise ignore new imported config class; existing non-imported class overrides it.
|
||
return;
|
||
}
|
||
else {
|
||
// Explicit bean definition found, probably replacing an import.
|
||
// Let's remove the old one and go with the new one.
|
||
this.configurationClasses.remove(configClass);
|
||
this.knownSuperclasses.values().removeIf(configClass::equals);
|
||
}
|
||
}
|
||
|
||
// Recursively process the configuration class and its superclass hierarchy.
|
||
SourceClass sourceClass = asSourceClass(configClass, filter);
|
||
do { //解析配置类里面的所有注解,
|
||
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
|
||
}
|
||
while (sourceClass != null);
|
||
//只要这个配置类解析过,就放在已经解析好的集合中防止重复解析
|
||
this.configurationClasses.put(configClass, configClass);
|
||
}
|
||
|
||
|
||
```
|
||
|
||
#### ConfigurationClassParser#doProcessConfigurationClass()解析配置类中诸如@ComponentScan,@Import,@Bean等注解
|
||
|
||
```java
|
||
private final Environment environment;
|
||
|
||
private final BeanDefinitionRegistry registry;
|
||
|
||
private final ComponentScanAnnotationParser componentScanParser;
|
||
|
||
private final Map<ConfigurationClass, ConfigurationClass> configurationClasses = new LinkedHashMap<>();
|
||
|
||
private final Map<String, ConfigurationClass> knownSuperclasses = new HashMap<>();
|
||
|
||
protected final SourceClass doProcessConfigurationClass(
|
||
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
|
||
throws IOException {
|
||
|
||
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
|
||
// Recursively process any member (nested) classes first
|
||
processMemberClasses(configClass, sourceClass, filter);
|
||
}
|
||
|
||
// Process any @PropertySource annotations
|
||
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
|
||
sourceClass.getMetadata(), PropertySources.class,
|
||
org.springframework.context.annotation.PropertySource.class)) {
|
||
if (this.environment instanceof ConfigurableEnvironment) {
|
||
processPropertySource(propertySource);
|
||
}
|
||
else {
|
||
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
|
||
"]. Reason: Environment must implement ConfigurableEnvironment");
|
||
}
|
||
}
|
||
|
||
// Process any @ComponentScan annotations
|
||
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
|
||
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
|
||
if (!componentScans.isEmpty() &&
|
||
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
|
||
for (AnnotationAttributes componentScan : componentScans) {
|
||
//使用Scanner把ComponentScan指定的包下的所有组件都扫描进来 The config class is annotated with @ComponentScan -> perform the scan immediately
|
||
Set<BeanDefinitionHolder> scannedBeanDefinitions =
|
||
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
|
||
// Check the set of scanned definitions for any further config classes and parse recursively if needed
|
||
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
|
||
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
|
||
if (bdCand == null) {
|
||
bdCand = holder.getBeanDefinition();
|
||
}
|
||
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
|
||
parse(bdCand.getBeanClassName(), holder.getBeanName());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//处理@Import注解的地方【AOP就是利用这个地方导入一个后置处理器的】 Process any @Import annotations
|
||
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
|
||
|
||
//处理@ImportResource Process any @ImportResource annotations
|
||
AnnotationAttributes importResource =
|
||
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
|
||
if (importResource != null) {
|
||
String[] resources = importResource.getStringArray("locations");
|
||
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
|
||
for (String resource : resources) {
|
||
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
|
||
configClass.addImportedResource(resolvedResource, readerClass);
|
||
}
|
||
}
|
||
|
||
//处理@Bean Process individual @Bean methods
|
||
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
|
||
for (MethodMetadata methodMetadata : beanMethods) {
|
||
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
|
||
}
|
||
|
||
// Process default methods on interfaces
|
||
processInterfaces(configClass, sourceClass);
|
||
|
||
// Process superclass, if any
|
||
if (sourceClass.getMetadata().hasSuperClass()) {
|
||
String superclass = sourceClass.getMetadata().getSuperClassName();
|
||
if (superclass != null && !superclass.startsWith("java") &&
|
||
!this.knownSuperclasses.containsKey(superclass)) {
|
||
this.knownSuperclasses.put(superclass, configClass);
|
||
// Superclass found, return its annotation metadata and recurse
|
||
return sourceClass.getSuperClass();
|
||
}
|
||
}
|
||
|
||
// No superclass -> processing is complete
|
||
return null;
|
||
}
|
||
|
||
|
||
```
|
||
|
||
|
||
|
||
#### ComponentScanAnnotationParser#parse()具体如何解析@ComponentScan注解。这里也是@Component注解生效的地方
|
||
|
||
```java
|
||
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
|
||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
|
||
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
|
||
// ...省略不重要
|
||
return scanner.doScan(StringUtils.toStringArray(basePackages)); //扫描器进行扫描
|
||
}
|
||
```
|
||
|
||
##### ClassPathBeanDefinitionScanner#doScan()
|
||
|
||
```java
|
||
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider{
|
||
|
||
//...
|
||
|
||
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
|
||
Assert.notEmpty(basePackages, "At least one base package must be specified");
|
||
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
|
||
for (String basePackage : basePackages) {
|
||
Set<BeanDefinition> candidates = findCandidateComponents(basePackage); //找到候选组件(我们需要扫描进来的组件),这里是调用父类的方法
|
||
for (BeanDefinition candidate : candidates) {
|
||
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
|
||
candidate.setScope(scopeMetadata.getScopeName());
|
||
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
|
||
if (candidate instanceof AbstractBeanDefinition) {
|
||
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
|
||
}
|
||
if (candidate instanceof AnnotatedBeanDefinition) {
|
||
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
|
||
}
|
||
if (checkCandidate(beanName, candidate)) {
|
||
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
|
||
definitionHolder =
|
||
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
|
||
beanDefinitions.add(definitionHolder);
|
||
registerBeanDefinition(definitionHolder, this.registry);
|
||
}
|
||
}
|
||
}
|
||
return beanDefinitions;
|
||
}
|
||
|
||
|
||
// ...
|
||
}
|
||
```
|
||
|
||
##### ClassPathScanningCandidateComponentProvider#findCandidateComponents()
|
||
|
||
```java
|
||
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
|
||
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
|
||
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
|
||
}
|
||
else {
|
||
return scanCandidateComponents(basePackage); //扫描所有组件
|
||
}
|
||
}
|
||
|
||
|
||
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
|
||
Set<BeanDefinition> candidates = new LinkedHashSet<>();
|
||
try {
|
||
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
|
||
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
|
||
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
|
||
boolean traceEnabled = logger.isTraceEnabled();
|
||
boolean debugEnabled = logger.isDebugEnabled();
|
||
for (Resource resource : resources) {
|
||
if (traceEnabled) {
|
||
logger.trace("Scanning " + resource);
|
||
}
|
||
if (resource.isReadable()) {
|
||
try { //生成每一个资源的元数据信息
|
||
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
|
||
if (isCandidateComponent(metadataReader)) { //如果当前类在扫描范围
|
||
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
|
||
sbd.setSource(resource);
|
||
if (isCandidateComponent(sbd)) {
|
||
if (debugEnabled) {
|
||
logger.debug("Identified candidate component class: " + resource);
|
||
}
|
||
candidates.add(sbd);
|
||
}
|
||
else {
|
||
if (debugEnabled) {
|
||
logger.debug("Ignored because not a concrete top-level class: " + resource);
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
if (traceEnabled) {
|
||
logger.trace("Ignored because not matching any filter: " + resource);
|
||
}
|
||
}
|
||
}
|
||
catch (Throwable ex) {
|
||
throw new BeanDefinitionStoreException(
|
||
"Failed to read candidate component class: " + resource, ex);
|
||
}
|
||
}
|
||
else {
|
||
if (traceEnabled) {
|
||
logger.trace("Ignored because not readable: " + resource);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (IOException ex) {
|
||
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
|
||
}
|
||
return candidates;
|
||
}
|
||
```
|
||
|
||
拿到所有类(资源),不管你有没有标@Component注解。然后挨个遍历每一个资源是不是候选的组件(根据前面准备的一些条件,在这里进行判断)
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009145119146.png"/>
|
||
|
||
|
||
|
||
|
||
|
||
最后我们看一下执行完之后的BeanDefinition信息
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009150338205.png"/>
|
||
|
||
|
||
|
||
### registerBeanPostProcessors()注册所有的Bean后置处理器
|
||
|
||
前面讲过
|
||
|
||
```java
|
||
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
|
||
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
|
||
}
|
||
```
|
||
|
||
#### PostProcessorRegistrationDelegate#registerBeanPostProcessors()
|
||
|
||
```java
|
||
public static void registerBeanPostProcessors(
|
||
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
|
||
|
||
// WARNING: Although it may appear that the body of this method can be easily
|
||
// refactored to avoid the use of multiple loops and multiple lists, the use
|
||
// of multiple lists and multiple passes over the names of processors is
|
||
// intentional. We must ensure that we honor the contracts for PriorityOrdered
|
||
// and Ordered processors. Specifically, we must NOT cause processors to be
|
||
// instantiated (via getBean() invocations) or registered in the ApplicationContext
|
||
// in the wrong order.
|
||
//
|
||
// Before submitting a pull request (PR) to change this method, please review the
|
||
// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
|
||
// to ensure that your proposal does not result in a breaking change:
|
||
// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
|
||
//获取到容器中所有的 BeanPostProcessor; Bean的后置处理器
|
||
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
|
||
|
||
// Register BeanPostProcessorChecker that logs an info message when
|
||
// a bean is created during BeanPostProcessor instantiation, i.e. when
|
||
// a bean is not eligible for getting processed by all BeanPostProcessors.
|
||
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
|
||
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
|
||
|
||
// Separate between BeanPostProcessors that implement PriorityOrdered,
|
||
// Ordered, and the rest.
|
||
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
|
||
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
|
||
List<String> orderedPostProcessorNames = new ArrayList<>();
|
||
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
|
||
for (String ppName : postProcessorNames) {
|
||
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { //获取所有实现了 PriorityOrdered 的 BeanPostProcessor
|
||
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
|
||
priorityOrderedPostProcessors.add(pp);
|
||
if (pp instanceof MergedBeanDefinitionPostProcessor) {
|
||
internalPostProcessors.add(pp);
|
||
}
|
||
}
|
||
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
|
||
orderedPostProcessorNames.add(ppName);
|
||
}
|
||
else {
|
||
nonOrderedPostProcessorNames.add(ppName);
|
||
}
|
||
}
|
||
|
||
//首先,注册所有的实现了 PriorityOrdered 的 BeanPostProcessor ; First, register the BeanPostProcessors that implement PriorityOrdered.
|
||
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
|
||
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
|
||
|
||
//接下来,注册所有的实现了 Ordered 的 BeanPostProcessor Next, register the BeanPostProcessors that implement Ordered.
|
||
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
|
||
for (String ppName : orderedPostProcessorNames) {
|
||
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
|
||
orderedPostProcessors.add(pp);
|
||
if (pp instanceof MergedBeanDefinitionPostProcessor) {
|
||
internalPostProcessors.add(pp);
|
||
}
|
||
}
|
||
sortPostProcessors(orderedPostProcessors, beanFactory);
|
||
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
|
||
|
||
// 最后,注册所有普通的 BeanPostProcessor ;Now, register all regular BeanPostProcessors.
|
||
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
|
||
for (String ppName : nonOrderedPostProcessorNames) {
|
||
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); //从容器中获取这个组件
|
||
nonOrderedPostProcessors.add(pp);
|
||
if (pp instanceof MergedBeanDefinitionPostProcessor) {
|
||
internalPostProcessors.add(pp);
|
||
}
|
||
}
|
||
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
|
||
|
||
//最后,重新注册所有internal的BeanPostProcessors Finally, re-register all internal BeanPostProcessors.
|
||
sortPostProcessors(internalPostProcessors, beanFactory);
|
||
registerBeanPostProcessors(beanFactory, internalPostProcessors);
|
||
|
||
// 重新注册一下这个后置处理器 Re-register post-processor for detecting inner beans as ApplicationListeners,
|
||
// 把他放到后置处理器的最后一位; moving it to the end of the processor chain (for picking up proxies etc).
|
||
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
|
||
}
|
||
```
|
||
|
||
|
||
|
||
### initMessageSource()
|
||
|
||
初始化国际化功能
|
||
|
||
1. 看容器中是否有MessageSource的定义信息
|
||
2. 如果没有就注册一个默认的
|
||
3. 把国际化组件(MessageSource) 放到单例池中
|
||
|
||
|
||
|
||
### initApplicationEventMulticaster()
|
||
|
||
初始化事件多播功能(事件派发)
|
||
|
||
1. 看容器中是否有applicationEventMulticaster的定义信息,按照id找
|
||
2. 如果没有就注册一个默认的
|
||
3. 把事件多播器组件(ApplicationEventMulticaster) 放到单例池中
|
||
|
||
|
||
|
||
|
||
|
||
### onRefresh()模板方法留给子类继续增强处理
|
||
|
||
留给子类继续增强处理,模板模式。
|
||
|
||
|
||
|
||
|
||
|
||
### registerListeners()
|
||
|
||
注册监听器,从容器中获取所有的ApplicationListener
|
||
|
||
```java
|
||
/** 多播器和监听器是观察者模式(里面包含了所有的监听器)
|
||
* Add beans that implement ApplicationListener as listeners.
|
||
* Doesn't affect other listeners, which can be added without being beans.
|
||
*/
|
||
protected void registerListeners() {
|
||
//把所有监听器保存到多播器的集合中 Register statically specified listeners first.
|
||
for (ApplicationListener<?> listener : getApplicationListeners()) {
|
||
getApplicationEventMulticaster().addApplicationListener(listener);
|
||
}
|
||
|
||
// Do not initialize FactoryBeans here: We need to leave all regular beans
|
||
// uninitialized to let post-processors apply to them! 获取ApplicationListener在ioc容器中注册的bean的名字
|
||
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
|
||
for (String listenerBeanName : listenerBeanNames) {
|
||
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); //获取所有的容器中的监听器,并保存他们的名字
|
||
}
|
||
|
||
//派发之前攒的一些早期事件 Publish early application events now that we finally have a multicaster...
|
||
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
|
||
this.earlyApplicationEvents = null;
|
||
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
|
||
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
|
||
getApplicationEventMulticaster().multicastEvent(earlyEvent);
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
监听器也是一个重点,后面细讲
|
||
|
||
|
||
|
||
|
||
|
||
### finishBeanFactoryInitialization()正式创建所有普通Bean
|
||
|
||
前面Bean的初始化流程讲的很仔细了
|
||
|
||
1. 主要就是遍历循环所有BeanDefinition里的BeanName,挨个创建Bean对象。注意BeanPostProcessor这些不算普通Bean,在registerBeanPostProcessors(),invokeBeanFactoryPostProcessors()已经创建完了,因为在普通Bean创建的过程中,后置处理器可能需要参与进来,所以需要比普通Bean提前创建好
|
||
2. 最后执行SmartInitializingSingleton.afterSingletonsInstantiated后初始化
|
||
|
||
|
||
|
||
### finishRefresh()主要是发送容器刷新完成的事件
|
||
|
||
最后进行一些清理和事件发送等
|
||
|
||
```java
|
||
protected void finishRefresh() {
|
||
// Clear context-level resource caches (such as ASM metadata from scanning).
|
||
clearResourceCaches();
|
||
|
||
// Initialize lifecycle processor for this context.
|
||
initLifecycleProcessor();
|
||
|
||
//告诉LifecycleProcessor容器onRefresh Propagate refresh to lifecycle processor first.
|
||
getLifecycleProcessor().onRefresh();
|
||
|
||
//发布事件 Publish the final event.
|
||
publishEvent(new ContextRefreshedEvent(this));
|
||
|
||
//jconsole(暴露MBean端点信息) Participate in LiveBeansView MBean, if active.
|
||
if (!NativeDetector.inNativeImage()) {
|
||
LiveBeansView.registerApplicationContext(this);
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
|
||
自此over
|
||
|
||
|
||
|
||
|
||
|
||
# 补充:循环引用解决方案
|
||
|
||
> 单开一节,讲一下之前一直忽略的这个。其实很简单的一个东西,被网上搞的很难一样。
|
||
|
||
## 测试类
|
||
|
||
### A
|
||
|
||
```java
|
||
@Component
|
||
public class A {
|
||
private B b;
|
||
|
||
public A() {
|
||
System.out.println("A...构造....");
|
||
}
|
||
|
||
@Autowired
|
||
public void setB(B b) {
|
||
this.b = b;
|
||
}
|
||
}
|
||
```
|
||
|
||
### B
|
||
|
||
```java
|
||
@Component
|
||
public class B {
|
||
|
||
private A a;
|
||
|
||
public B() {
|
||
System.out.println("B...构造....");
|
||
}
|
||
|
||
@Autowired
|
||
public void setA(A a) {
|
||
this.a = a;
|
||
}
|
||
}
|
||
```
|
||
|
||
这就是循环引用的场景,这种写法由于Spring内部获取Bean都是通过getBean方法来获取,就造成了下面的死循环。我们来看看Spring是怎么解决的。
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20210928203211130.png">
|
||
|
||
|
||
|
||
## 核心代码
|
||
|
||
### AbstractBeanFactory
|
||
|
||
```java
|
||
protected <T> T doGetBean(
|
||
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
|
||
throws BeansException {
|
||
|
||
String beanName = transformedBeanName(name); //转换Bean名字
|
||
Object beanInstance;
|
||
|
||
// 先检查单实例bean的缓存 Eagerly check singleton cache for manually registered singletons.
|
||
// ☆☆☆ pos_1
|
||
Object sharedInstance = getSingleton(beanName); //检查缓存中有没有,如果是第一次获取肯定是没有的
|
||
if (sharedInstance != null && args == null) {
|
||
if (logger.isTraceEnabled()) {
|
||
if (isSingletonCurrentlyInCreation(beanName)) {
|
||
// ...
|
||
}
|
||
else {
|
||
// ..
|
||
}
|
||
}
|
||
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
|
||
}
|
||
|
||
else { //默认第一次获取组件都会进入else环节
|
||
// ...
|
||
|
||
// 创建bean的实例;Create bean instance.
|
||
if (mbd.isSingleton()) {
|
||
// ☆☆☆ pos_2
|
||
sharedInstance = getSingleton(beanName, () -> {
|
||
try {
|
||
return createBean(beanName, mbd, args); //创建bean对象的实例
|
||
}
|
||
catch (BeansException ex) {
|
||
destroySingleton(beanName);
|
||
throw ex;
|
||
}
|
||
}); //看当前bean是否是FactoryBean
|
||
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
|
||
}
|
||
|
||
// ...
|
||
}
|
||
```
|
||
|
||
|
||
|
||
### DefaultSingletonBeanRegistry
|
||
|
||
```java
|
||
public Object getSingleton(String beanName) {
|
||
// ☆☆☆ pos_3
|
||
return getSingleton(beanName, true);
|
||
}
|
||
|
||
/**
|
||
* Return the (raw) singleton object registered under the given name.
|
||
* <p>Checks already instantiated singletons and also allows for an early
|
||
* reference to a currently created singleton (resolving a circular reference).
|
||
* @param beanName the name of the bean to look for
|
||
* @param allowEarlyReference whether early references should be created or not
|
||
* @return the registered singleton object, or {@code null} if none found
|
||
*/
|
||
//☆☆☆ pos_4
|
||
@Nullable //双检查锁
|
||
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
|
||
//先检查单例缓存池,获取当前对象 Quick check for existing instance without full singleton lock
|
||
Object singletonObject = this.singletonObjects.get(beanName); //一级缓存
|
||
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { //如果当前bean正在创建过程中,而且缓存中没有则继续
|
||
singletonObject = this.earlySingletonObjects.get(beanName); //二级
|
||
if (singletonObject == null && allowEarlyReference) {
|
||
synchronized (this.singletonObjects) {
|
||
// Consistent creation of early reference within full singleton lock
|
||
singletonObject = this.singletonObjects.get(beanName);
|
||
if (singletonObject == null) {
|
||
singletonObject = this.earlySingletonObjects.get(beanName);
|
||
if (singletonObject == null) {
|
||
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); //三级
|
||
if (singletonFactory != null) {
|
||
singletonObject = singletonFactory.getObject();
|
||
this.earlySingletonObjects.put(beanName, singletonObject);
|
||
this.singletonFactories.remove(beanName);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return singletonObject;
|
||
}
|
||
|
||
|
||
// ☆☆☆ pos_5
|
||
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
|
||
Assert.notNull(beanName, "Bean name must not be null");
|
||
synchronized (this.singletonObjects) {
|
||
Object singletonObject = this.singletonObjects.get(beanName);//再检查一次单例池
|
||
if (singletonObject == null) { //单实例池子里面没有当前对象(说明没有创建完成)
|
||
if (this.singletonsCurrentlyInDestruction) {
|
||
throw new BeanCreationNotAllowedException(beanName,
|
||
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
|
||
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
|
||
}
|
||
if (logger.isDebugEnabled()) {
|
||
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
|
||
}
|
||
// ☆☆☆ pos_6
|
||
beforeSingletonCreation(beanName); //单实例创建之前,这个就是加到
|
||
boolean newSingleton = false;
|
||
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
|
||
if (recordSuppressedExceptions) {
|
||
this.suppressedExceptions = new LinkedHashSet<>();
|
||
}
|
||
try {
|
||
singletonObject = singletonFactory.getObject();//会调用lamda表达式的内容,真正创建对象
|
||
newSingleton = true;
|
||
}
|
||
catch (IllegalStateException ex) {
|
||
// Has the singleton object implicitly appeared in the meantime ->
|
||
// if yes, proceed with it since the exception indicates that state.
|
||
// ☆☆☆ pos_7
|
||
singletonObject = this.singletonObjects.get(beanName);
|
||
if (singletonObject == null) {
|
||
throw ex;
|
||
}
|
||
}
|
||
catch (BeanCreationException ex) {
|
||
// ...
|
||
}
|
||
finally {
|
||
if (recordSuppressedExceptions) {
|
||
this.suppressedExceptions = null;
|
||
}
|
||
afterSingletonCreation(beanName);
|
||
}
|
||
if (newSingleton) {
|
||
addSingleton(beanName, singletonObject);
|
||
}
|
||
}
|
||
return singletonObject;
|
||
}
|
||
}
|
||
|
||
// 加到singletonsCurrentlyInCreation
|
||
protected void beforeSingletonCreation(String beanName) {
|
||
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
|
||
throw new BeanCurrentlyInCreationException(beanName);
|
||
}
|
||
}
|
||
|
||
```
|
||
|
||
### AbstractAutowireCapableBeanFactory
|
||
|
||
```java
|
||
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
|
||
throws BeanCreationException {
|
||
|
||
// Instantiate the bean.
|
||
BeanWrapper instanceWrapper = null;
|
||
if (mbd.isSingleton()) { //是否单例的
|
||
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
|
||
}
|
||
if (instanceWrapper == null) {
|
||
//创建Bean的实例,默认使用无参构造器创建的对象,组件的原始对象就创建了 ☆☆☆ pos_8
|
||
instanceWrapper = createBeanInstance(beanName, mbd, args);
|
||
}
|
||
Object bean = instanceWrapper.getWrappedInstance();
|
||
Class<?> beanType = instanceWrapper.getWrappedClass();
|
||
if (beanType != NullBean.class) {
|
||
mbd.resolvedTargetType = beanType;
|
||
}
|
||
|
||
// ...
|
||
|
||
// 提前暴露单实例。专门来解决循环引用问题;Eagerly cache singletons to be able to resolve circular references
|
||
// even when triggered by lifecycle interfaces like BeanFactoryAware.
|
||
// ☆☆☆ pos_9
|
||
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
|
||
isSingletonCurrentlyInCreation(beanName));
|
||
if (earlySingletonExposure) {
|
||
if (logger.isTraceEnabled()) {
|
||
logger.trace("Eagerly caching bean '" + beanName +
|
||
"' to allow for resolving potential circular references");
|
||
}
|
||
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); //三级缓存中的Bean也会被后置处理来增强,
|
||
}
|
||
|
||
// Initialize the bean instance.
|
||
Object exposedObject = bean;
|
||
try {
|
||
// ☆☆☆ pos_10
|
||
populateBean(beanName, mbd, instanceWrapper); //给创建好的对象每个属性进行赋值,@Autowired发生在这里
|
||
exposedObject = initializeBean(beanName, exposedObject, mbd);//初始化bean
|
||
}
|
||
catch (Throwable ex) {
|
||
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
|
||
throw (BeanCreationException) ex;
|
||
}
|
||
else {
|
||
throw new BeanCreationException(
|
||
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
|
||
}
|
||
}
|
||
//早期单实例暴露
|
||
if (earlySingletonExposure) {
|
||
Object earlySingletonReference = getSingleton(beanName, false); //检查早期缓存中是否存在这个组件
|
||
if (earlySingletonReference != null) {
|
||
if (exposedObject == bean) {
|
||
exposedObject = earlySingletonReference;
|
||
}
|
||
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
|
||
String[] dependentBeans = getDependentBeans(beanName);
|
||
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
|
||
for (String dependentBean : dependentBeans) {
|
||
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
|
||
actualDependentBeans.add(dependentBean);
|
||
}
|
||
}
|
||
if (!actualDependentBeans.isEmpty()) {
|
||
throw new BeanCurrentlyInCreationException(beanName,
|
||
"Bean with name '" + beanName + "' has been injected into other beans [" +
|
||
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
|
||
"] in its raw version as part of a circular reference, but has eventually been " +
|
||
"wrapped. This means that said other beans do not use the final version of the " +
|
||
"bean. This is often the result of over-eager type matching - consider using " +
|
||
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Register bean as disposable.
|
||
try {
|
||
registerDisposableBeanIfNecessary(beanName, bean, mbd);
|
||
}
|
||
catch (BeanDefinitionValidationException ex) {
|
||
throw new BeanCreationException(
|
||
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
|
||
}
|
||
|
||
return exposedObject;
|
||
}
|
||
```
|
||
|
||
|
||
|
||
## 流程
|
||
|
||
1. pos_1位置先进入pos_3位置的`getSingleton(beanName, true)`,查看缓存中有没有A组件
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009165057518.png"/>
|
||
|
||
2. 然后走到pos_2调用pos_5的`getSingleton()`开始创建A的流程
|
||
3. 在pos_5的`getSingleton()`中走到pos_6的`beforeSingletonCreation()`,就变成下面这样
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009165924811.png"/>
|
||
|
||
4. 接着pos_7的会调用pos_2的lamda表达式里的`createbean()`,里面再调用`doCreateBean()`。前面讲过不多说,最终调用A的无参构造(pos_8),创建完之后发现A的B属性是null。
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009170632290.png"/>
|
||
|
||
5.在pos_9处的`addSingletonFactory()`来准备解决循环引用
|
||
|
||
```java
|
||
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
|
||
Assert.notNull(singletonFactory, "Singleton factory must not be null");
|
||
synchronized (this.singletonObjects) {
|
||
if (!this.singletonObjects.containsKey(beanName)) { //当前对象如果没有在单例池中
|
||
this.singletonFactories.put(beanName, singletonFactory);
|
||
this.earlySingletonObjects.remove(beanName);
|
||
this.registeredSingletons.add(beanName);
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009171641665.png"/>
|
||
|
||
|
||
|
||
6. 接着在pos_10处的`populateBean()`开始给属性赋值,这一步就是要把`B b`自动装配进来。主要是
|
||
|
||
```java
|
||
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
|
||
if (bw == null) {
|
||
if (mbd.hasPropertyValues()) {
|
||
throw new BeanCreationException(
|
||
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
|
||
}
|
||
else {
|
||
// Skip property population phase for null instance.
|
||
return;
|
||
}
|
||
}
|
||
|
||
// @Autowired赋值也在这里(但是没做事)。可以中断初始化行为; 在属性赋值之前,后置处理器可以提前准备些东西 Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
|
||
|
||
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
|
||
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
|
||
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
|
||
return;
|
||
}
|
||
}
|
||
} //以上的后置处理器可以中断以下的行为
|
||
|
||
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
|
||
|
||
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
|
||
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
|
||
// ...
|
||
}
|
||
|
||
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
|
||
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
|
||
|
||
PropertyDescriptor[] filteredPds = null;
|
||
if (hasInstAwareBpps) {
|
||
if (pvs == null) {
|
||
pvs = mbd.getPropertyValues(); //xml中property标签指定的
|
||
} //使用后置处理器处理属性
|
||
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
|
||
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
|
||
if (pvsToUse == null) {
|
||
if (filteredPds == null) {
|
||
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
|
||
}
|
||
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
|
||
if (pvsToUse == null) {
|
||
return;
|
||
}
|
||
}
|
||
pvs = pvsToUse; //封装了当前bean的所有属性名和值,可以由后置处理器处理得到
|
||
}
|
||
}
|
||
// ...
|
||
|
||
if (pvs != null) { //把以前处理好的PropertyValues给bean里面设置一下。主要是上面步骤没有给bean里面设置的属性
|
||
applyPropertyValues(beanName, mbd, bw, pvs); //xml版的所有配置会来到这里给属性赋值
|
||
}
|
||
}
|
||
```
|
||
|
||
通过前面讲过的AutowiredAnnotationBeanPostProcessor来注入B,最后发现要调用setB方法给B赋值
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009172602037.png"/>
|
||
|
||
7. 继续走,发现要想获得B还是要调用getBean
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009172943987.png" />
|
||
|
||
```java
|
||
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
|
||
throws BeansException {
|
||
|
||
return beanFactory.getBean(beanName); //所有自动注入的属性都是beanFactory.getBean(beanName);的结果
|
||
}
|
||
```
|
||
|
||
|
||
|
||
然后图就是这样子
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009173310844.png"/>
|
||
|
||
|
||
|
||
8. B也是走这一套
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009175223998.png"/>
|
||
|
||
9. B为了获取A,还要再走一次getBean()流程,最终还是走到
|
||
|
||
```java
|
||
//☆☆☆ pos_4
|
||
@Nullable //双检查锁
|
||
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
|
||
//先检查单例缓存池,获取当前对象 Quick check for existing instance without full singleton lock
|
||
Object singletonObject = this.singletonObjects.get(beanName); //一级缓存
|
||
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { //如果当前bean正在创建过程中,而且缓存中没有则继续
|
||
singletonObject = this.earlySingletonObjects.get(beanName); //二级
|
||
if (singletonObject == null && allowEarlyReference) {
|
||
synchronized (this.singletonObjects) {
|
||
// Consistent creation of early reference within full singleton lock
|
||
singletonObject = this.singletonObjects.get(beanName);
|
||
if (singletonObject == null) {
|
||
singletonObject = this.earlySingletonObjects.get(beanName);
|
||
if (singletonObject == null) {
|
||
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); //三级
|
||
if (singletonFactory != null) {
|
||
singletonObject = singletonFactory.getObject();// 用那个lamda表达式拿对象
|
||
this.earlySingletonObjects.put(beanName, singletonObject);
|
||
this.singletonFactories.remove(beanName);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return singletonObject;
|
||
}
|
||
```
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009175603012.png"/>
|
||
|
||
|
||
|
||
10.
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009175756620.png"/>
|
||
|
||
|
||
|
||
11. 得到A之后,B赋值结束。B进入初始化
|
||
|
||
```java
|
||
populateBean(beanName, mbd, instanceWrapper); //给创建好的对象每个属性进行赋值,@Autowired发生在这里
|
||
exposedObject = initializeBean(beanName, exposedObject, mbd);//初始化bean
|
||
```
|
||
|
||
12. B初始化完之后,回到getSingleton,把自己放到单例池里
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009180127487.png"/>
|
||
|
||
```java
|
||
protected void addSingleton(String beanName, Object singletonObject) {
|
||
synchronized (this.singletonObjects) {
|
||
this.singletonObjects.put(beanName, singletonObject);
|
||
this.singletonFactories.remove(beanName);
|
||
this.earlySingletonObjects.remove(beanName);
|
||
this.registeredSingletons.add(beanName);
|
||
}
|
||
}
|
||
```
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009180214917.png"/>
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009180410898.png"/>
|
||
|
||
13. B全部结束之后回到A的流程,A赋值工作结束了,然后就开始A的初始化。初始化的过程中
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009180807630.png"/>
|
||
|
||
```java
|
||
protected void addSingleton(String beanName, Object singletonObject) {
|
||
synchronized (this.singletonObjects) {
|
||
this.singletonObjects.put(beanName, singletonObject); //加到一级
|
||
this.singletonFactories.remove(beanName); //移除三级
|
||
this.earlySingletonObjects.remove(beanName); //移除二级
|
||
this.registeredSingletons.add(beanName);
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/image-20211009180545206.png"/>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
## 全部的流程图
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_05/循环引用.jpg">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|