diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index d88630a950d951a0a34fbdf8867a5b9886917881..3a6aa8867233c0407cab1c003ab9044b9c20ca3b 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -575,6 +575,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. + // 提前暴露对象 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { @@ -582,13 +583,13 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } - addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); + addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); // 加入三级缓存 } // Initialize the bean instance. Object exposedObject = bean; try { - populateBean(beanName, mbd, instanceWrapper); + populateBean(beanName, mbd, instanceWrapper); // 填充属性 exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { @@ -939,7 +940,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac */ protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; - if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { + if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { // aop for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; @@ -1289,6 +1290,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac getAccessControlContext()); } else { + // 获取实例化策略(CGLIB反射生成对象) beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index dd498ce0f1e1c5934d63b2b337918fec465d5e02..d299a25a67dd90fe621c4c6e5a0b8d73b84d1095 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -261,6 +261,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. + // 判断当前对象是否是正在创建的原型对象 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } @@ -286,17 +287,22 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp return (T) parentBeanFactory.getBean(nameToLookup); } } - + // typeCheckOnly => 是否为类型检查而不是实际使用获取实例 if (!typeCheckOnly) { + // 移除mergedBeanDefinitions中的bean定义,然后将当前正在创建的bean,加入到alreadyCreated中,表示该bean至少已经创建一次 markBeanAsCreated(beanName); } try { + // getMergedLocalBeanDefinition => 获取RootBeanDefinition, 如果不存在则会根据给定的beanName去获取bean定义信息 + // 该RootBeanDefinition是此bean与其父类合并得到的bean定义信息,并将其存储在mergedBeanDefinitions中, + // 尽管markBeanAsCreated获取会移除该信息,但是此处仍然会添加进去。 + RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); - checkMergedBeanDefinition(mbd, beanName, args); + checkMergedBeanDefinition(mbd, beanName, args); // 校验该mbd是否是抽象类 // Guarantee initialization of beans that the current bean depends on. - String[] dependsOn = mbd.getDependsOn(); + String[] dependsOn = mbd.getDependsOn(); // 获取该bean依赖的对象 if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { @@ -1136,6 +1142,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp * @return the transformed bean name */ protected String transformedBeanName(String name) { + // transformedBeanName => 返回实际的bean名称,删除工厂取消引用前缀(&) + // canonicalName => 确定原始名称,将别名解析为规范名称 return canonicalName(BeanFactoryUtils.transformedBeanName(name)); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java index 0a81aef4e9feffe74cf2adf4c22bde2a6f2062e4..d5cb54e582ec82a3b008b42392fa717da1916805 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java @@ -179,8 +179,11 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { // Quick check for existing instance without full singleton lock + // 去一级缓存中获取bean, 一级缓存存储的是实例化与初始化完成的类。 Object singletonObject = this.singletonObjects.get(beanName); + // isSingletonCurrentlyInCreation 判断当前单例对象是否是正在创建中 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { + // 去二级缓存中获取bean对象 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { synchronized (this.singletonObjects) { @@ -189,6 +192,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements if (singletonObject == null) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { + // 去三级缓存中获取bean对象 ObjectFactory singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); @@ -224,6 +228,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } + // 创建单例前的回调,校验该类是否被排除在创建检查中,并将其加入到正在创建的集合中 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); @@ -254,7 +259,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements if (recordSuppressedExceptions) { this.suppressedExceptions = null; } - afterSingletonCreation(beanName); + afterSingletonCreation(beanName); // 校验该类是否被排除在创建检查中,并将其移出到正在创建的集合中 } if (newSingleton) { addSingleton(beanName, singletonObject); diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index 532637718602485ed1fca4baa99a7c209f75b865..f907995f1f5d74ff59e0e5d49d76ebb9568f54cb 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -522,6 +522,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. + // 1. 开启应用上下文启动标识 + // 2. 加载用户自定义资源,校验必需字段 + // 3. 设置应用监听器与初始化刷新前应用事件 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. @@ -589,6 +592,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader */ protected void prepareRefresh() { // Switch to active. + // 设置上下文启动标志以及启动时间 this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); @@ -601,15 +605,19 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader logger.debug("Refreshing " + getDisplayName()); } } - + /** { @see com.czf.extra.ExtraInitPropertySourcesApplicationContext } */ // 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); } @@ -621,6 +629,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... + // 初始化刷新前应用事件 this.earlyApplicationEvents = new LinkedHashSet<>(); } diff --git a/spring-core/src/main/java/org/springframework/core/io/DefaultResourceLoader.java b/spring-core/src/main/java/org/springframework/core/io/DefaultResourceLoader.java index 936c1d3e50fceebdcf141516a34398cf058d89f0..ed3c62ea71b91aef110f081fdd55ab59541cec49 100644 --- a/spring-core/src/main/java/org/springframework/core/io/DefaultResourceLoader.java +++ b/spring-core/src/main/java/org/springframework/core/io/DefaultResourceLoader.java @@ -62,6 +62,7 @@ public class DefaultResourceLoader implements ResourceLoader { * @see java.lang.Thread#getContextClassLoader() */ public DefaultResourceLoader() { + // 获取默认类加载器。类加载器种类,双亲委托模型? this.classLoader = ClassUtils.getDefaultClassLoader(); } diff --git a/spring-demo/src/main/java/com/czf/extra/ExtraApplication.java b/spring-demo/src/main/java/com/czf/extra/ExtraApplication.java index 9f72f56d67caa06da46dab7be4ef5327900262fe..6142d62f129b0ea675c34f3740a07a4418a9197e 100644 --- a/spring-demo/src/main/java/com/czf/extra/ExtraApplication.java +++ b/spring-demo/src/main/java/com/czf/extra/ExtraApplication.java @@ -5,4 +5,8 @@ package com.czf.extra; * @date 2021/5/27 上午10:30 */ public class ExtraApplication { + public static void main(String[] args) { + ExtraInitPropertySourcesApplicationContext extraInitPropertySourcesApplicationContext = new ExtraInitPropertySourcesApplicationContext("application-loop.xml"); + + } } diff --git a/spring-demo/src/main/java/com/czf/extra/ExtraInitPropertySourcesApplicationContext.java b/spring-demo/src/main/java/com/czf/extra/ExtraInitPropertySourcesApplicationContext.java index e22bf9c82f21e5d9b4d58c4daa85bbc88cf55d84..70846a14b7572dd3a2b2280adc2a656e7bac747b 100644 --- a/spring-demo/src/main/java/com/czf/extra/ExtraInitPropertySourcesApplicationContext.java +++ b/spring-demo/src/main/java/com/czf/extra/ExtraInitPropertySourcesApplicationContext.java @@ -1,5 +1,7 @@ package com.czf.extra; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** @@ -8,4 +10,16 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; * @date 2021/5/27 上午10:25 */ public class ExtraInitPropertySourcesApplicationContext extends ClassPathXmlApplicationContext { + + public ExtraInitPropertySourcesApplicationContext(String configLocation) throws BeansException { + super(configLocation); + } + + @Override + protected void initPropertySources() { + System.out.println("======自定义init property source========="); + getEnvironment().getSystemProperties().put("author", "scott"); + // 校验必填属性 + getEnvironment().setRequiredProperties("author"); + } } diff --git a/spring-demo/src/main/java/com/czf/loop/spring-circleReference.md b/spring-demo/src/main/java/com/czf/loop/spring-circleReference.md index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..38fb0ef14b8ae7919e42916feb36d31e358e9ca8 100644 --- a/spring-demo/src/main/java/com/czf/loop/spring-circleReference.md +++ b/spring-demo/src/main/java/com/czf/loop/spring-circleReference.md @@ -0,0 +1,9 @@ +### 循环依赖 + +#### 解析A,B互相引用过程 +1. 实例化A +2. 对象A填充属性B +3. + +#### 三级缓存的作用 +1. \ No newline at end of file