diff --git a/README.md b/README.md index 7d92f9a..6e4c064 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,6 @@ > 2. 提供两种在线阅读方式:[电子书在线阅读](https://imlql.cn/JavaYouth/#/),[个人博客](https://imlql.cn/)浏览。 > 3. 转载须知:转载请注明GitHub出处,让我们一起维护一个良好的技术创作环境。 > 4. 如果你要提交 issue 或者 pr 的话建议到 [Github](https://github.com/youthlql/JavaYouth) 提交。笔者会持续更新,如果对你有所帮助,不妨[Github](https://github.com/youthlql/JavaYouth)点个**Star~**,你的**Star**是我创作的动力。 -> 5. 所有更新日志,写作计划,公告等均在此发布 ==> [时间轴](https://imlql.cn/timeline/)。 @@ -138,7 +137,7 @@ -## 源码【01.27更新】 +## 源码【02.13更新】 @@ -150,6 +149,8 @@ [04.第4章-Bean初始化流程](docs/spring-sourcecode-v1/04.第4章-Bean初始化流程.md) +[05.第5章-容器刷新流程](docs/spring-sourcecode-v1/05.第5章-容器刷新流程.md) + # Netty diff --git a/docs/spring-sourcecode-v1/05.第5章-容器刷新流程.md b/docs/spring-sourcecode-v1/05.第5章-容器刷新流程.md new file mode 100644 index 0000000..2a42cec --- /dev/null +++ b/docs/spring-sourcecode-v1/05.第5章-容器刷新流程.md @@ -0,0 +1,1807 @@ +--- +title: Spring源码系列-第5章-容器刷新流程 +tags: + - Spring源码 +categories: + - Spring + - 源码V1 +keywords: Spring,框架,spring源码 +description: 容器刷新全流程 +cover: 'https://gitee.com/youthlql/randombg/raw/master/logo/spring.png' +abbrlink: a1b8c236 +date: 2022-02-13 18:01:02 +--- + + + +# 第5章-容器刷新流程 + +## 流程图-容器刷新 + + + +## 容器创建 + +```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 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 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个后置处理器 + + + +##### 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 void doRegisterBean(Class beanClass, @Nullable String name, + @Nullable Class[] qualifiers, @Nullable Supplier 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 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")); + } + } +``` + +走完之后,注册中心肯定多了咱们的配置类 + + + + + +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) { + } +``` + + + + + + + +### 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())); + } + } +``` + +这一步有个很关键的后置处理器 + + + + + + + + + +#### 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 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 candidates = new LinkedHashSet<>(configCandidates); + Set alreadyParsed = new HashSet<>(configCandidates.size()); + do { + StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse"); + parser.parse(candidates); //解析配置类;所有需要扫描进来的组件的BeanDefinition信息都已经完成 + parser.validate(); + + Set 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 oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames)); + Set 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(); + } + } +``` + + + + + + + +#### ConfigurationClassParser#parse() + +```java + public void parse(Set 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 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 configurationClasses = new LinkedHashMap<>(); + + private final Map knownSuperclasses = new HashMap<>(); + + protected final SourceClass doProcessConfigurationClass( + ConfigurationClass configClass, SourceClass sourceClass, Predicate 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 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 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 readerClass = importResource.getClass("reader"); + for (String resource : resources) { + String resolvedResource = this.environment.resolveRequiredPlaceholders(resource); + configClass.addImportedResource(resolvedResource, readerClass); + } + } + + //处理@Bean Process individual @Bean methods + Set 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 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 doScan(String... basePackages) { + Assert.notEmpty(basePackages, "At least one base package must be specified"); + Set beanDefinitions = new LinkedHashSet<>(); + for (String basePackage : basePackages) { + Set 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 findCandidateComponents(String basePackage) { + if (this.componentsIndex != null && indexSupportsIncludeFilters()) { + return addCandidateComponentsFromIndex(this.componentsIndex, basePackage); + } + else { + return scanCandidateComponents(basePackage); //扫描所有组件 + } + } + + + private Set scanCandidateComponents(String basePackage) { + Set 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注解。然后挨个遍历每一个资源是不是候选的组件(根据前面准备的一些条件,在这里进行判断) + + + + + + + +最后我们看一下执行完之后的BeanDefinition信息 + + + + + +### 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 priorityOrderedPostProcessors = new ArrayList<>(); + List internalPostProcessors = new ArrayList<>(); + List orderedPostProcessorNames = new ArrayList<>(); + List 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 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 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 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是怎么解决的。 + + + + + +## 核心代码 + +### AbstractBeanFactory + +```java + protected T doGetBean( + String name, @Nullable Class 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. + *

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 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组件 + + + +2. 然后走到pos_2调用pos_5的`getSingleton()`开始创建A的流程 +3. 在pos_5的`getSingleton()`中走到pos_6的`beforeSingletonCreation()`,就变成下面这样 + + + +4. 接着pos_7的会调用pos_2的lamda表达式里的`createbean()`,里面再调用`doCreateBean()`。前面讲过不多说,最终调用A的无参构造(pos_8),创建完之后发现A的B属性是null。 + + + + 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); + } + } + } +``` + + + + + +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赋值 + + + +7. 继续走,发现要想获得B还是要调用getBean + + + +```java + public Object resolveCandidate(String beanName, Class requiredType, BeanFactory beanFactory) + throws BeansException { + + return beanFactory.getBean(beanName); //所有自动注入的属性都是beanFactory.getBean(beanName);的结果 + } +``` + + + +然后图就是这样子 + + + + + +8. B也是走这一套 + + + +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; + } +``` + + + + + +10. + + + + + +11. 得到A之后,B赋值结束。B进入初始化 + + ```java + populateBean(beanName, mbd, instanceWrapper); //给创建好的对象每个属性进行赋值,@Autowired发生在这里 + exposedObject = initializeBean(beanName, exposedObject, mbd);//初始化bean + ``` + +12. B初始化完之后,回到getSingleton,把自己放到单例池里 + + + +```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); + } +} +``` + + + + + + + +13. B全部结束之后回到A的流程,A赋值工作结束了,然后就开始A的初始化。初始化的过程中 + + + +```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); + } +} +``` + + + + + + + + + + + +## 全部的流程图 + + + + + + + + + + + + + + + + + + + + +