缘由
Spring Framework 提供了除IOC之外的很多有意思的功能,深入研究其技术原理,可在项目技术选型上提供更多的思路和技术把控。Spring Framewrok 代码由大佬精心打磨,可以从功能实现上学习和模仿。另外Spring Framework是Java项目开发的基础,其他技术框架都会基于或者与Spring 兼容,研究其中的技术原理,可快速掌握其他技术框架的技术原理,比如 Spring boot \ Spring cloud...
简述
Spring Framework 出现的背景是,Java 对象之间调用关系复杂,为简化对象调用,Spring Framework 基于Dependency Injection,将对象的控制权转移到BeanFactory,由框架负责对象的生命周期,将对象与Bean进行映射,Bean的生命周期由完善的管理机制。
本文将会根据自己对Spring Framework的理解编辑。
正文
Spring Framework的核心技术非IOC莫属,BeanFactory接口可以将IOC的功能基本体现出来,子接口与子类实现各自的职责,层次清晰,职责明朗,可以作为面向对象的编程范文。
BeanFactory
注释中解释了Spring 的基本行为,基于Bean Definition创建Bean实例,由Bean Factory负责对象的创建、以及属性的赋值。
- 注释中提到一个说法,依赖 dependency injection 通常来说是比较好的。凭借 Dependency Injection 以推送的形式去配置应用对象通过setters 或者 constructors,而不是使用任何形式的拉去配置,比如BeanFactory lookup。
- BeanFactory会加载来自多种形式配置的 bean definition, 比如 xml 、配置bean的package ,bean definition 如何存储时无所谓的。鼓励支持bean之间引用的实现。
- 依赖注入功能是实现BeanFactory接口和子接口。
ListableBeanFactory
BeanFactory接口的扩展,可以列举所有的Bean实例,该接口的实现类要预加载所有单实例Bean.
HierarchicalBeanFactory
允许设置父容器,适用于web环境,Spring 有一个核心BeanFactory 还有一个Web BeanFactory.
ApplicationContext
BeanFactory定义了Spring Framework的基本思想和特性,解决了项目开发中核心痛点,另外还有其他的特性增加开发工作中的便利性,比如国际化、事件、资源加载等功能。
继承下列所有接口:
- EnvironmentCapable
- ListableBeanFactory
- HierarchicalBeanFactory
- MessageSource
- ApplicationEventPublisher
- ResourcePatternResolver
ConfigureableApplicationContext
BeanFactory接口的扩展,增加BeanFactory的配置能力,接口中的方法仅在容器启动或者销毁时使用,比如启动时需要的BeanFactoryPostProcessor, ApplicationListener, ResourceLoader ...
以上接口定义Spring Framework 框架的基本行为。
AbstractApplicationContext
ApplicationContext接口的抽象实现,已实现主要的Spring Frameword 特性,ApplicationContext接口定义的功能,都可以在此类中提供默认实现。
浏览源码,大致功能如下:
- 构造器中可设置 resourcePatternResolver 属性,创建PathMatchingResourcePatternResolver 对象。
- 构造器中可设置父容器,并融合父容器中的环境变量。
- 实现 ApplicationContext 中的接口,比如 publishEvent setStartupDate ...
- 实现 ConfigurationApplicationContext 中的接口,比如 addBeanFactoryPostProcessor addApplicationListener refresh() registerShutdownHook close ...
// refresh 方法涉及到的方法。
prepareRefresh prepareBeanFactory postProcessBeanFactory registryBeanPostProcessors invokeBeanFactoryPostProcessors initMessageSource initApplicationEventMulticaster initLifecycleProcessor registerListeners finishBeanFactoryInitialization finishRefresh
- 实现 BeanFactory 中的接口,比如 getBean isSingleton isTypeMatch
- 实现 ListableBeanFactory 中的接口,比如 containsBeanDefinition getBeanDefinitionNames findAnnotationOnBean ..
- 实现 HierarchicalBeanFactory 中的接口,比如 getParentBeanFactory getInternalParentBeanFactory ...
- 实现 MessageSource 中的接口,比如 getMessage getMessageSource ...
- 实现 ResourcePatternResolver 中的接口,比如getResources
- 实现 Lifecycle 中的接口,比如start stop isRunning
- 抽象方法 refreshBeanFactory ...
GenericApplicationContext
完整的ApplicationContext实现,实现了BeanDefinitionRegistry接口的方法,拥有注册BeanDefinition的能力,可以覆盖一些BeanFactory的属性。
- 构造器中创建 DefaultListableBeanFactory。
- 配置BeanFactory allowBeanDefinitionOverriding bean定义覆盖的问题 allowEagerClassLoading 是否加载标记为懒加载的类。
- 实现 AbstractApplicationContext 中的虚拟方法 refreshBeanFactory getBeanFactory ...
- 实现 BeanDefinitionRegistry 接口,比如 registerBeanDefinition isBeanNameInUse
- 手动注册Bean registerBean.
AnnotationConfigApplicationContext
接收 component class 、Configuration annotated class,@Component JSR330 javax.inject annotation.
允许一个接一个使用register方法注册类,扫描class path。Bean annotation 可以被后续的覆盖。
构造器中初始化 AnnotatedBeanDefinitionReader ClassPathBeanDefinitionScanner。或者手动注册一个启动类,并启动容器启动操作 refresh.
DefaultListableBeanFactory
一个很核心的类,可以说是IOC功能的承载者。继承抽象类 AbstractAutowireCapableBeanFactory。
- 实现 BeanFactory 剩余的接口实现 getBean getBeanProvider resolveBean ...
- 实现 ListableBeanFactory 接口,比如 getBeanDefinitionNames containsBeanDefinition ...
- 实现 ConfigurableListableBeanFactory 接口,比如 registerResolvableDependency isAutowireCandidate preInstantiateSingletons
- 实现 BeanDefinitionRegistry 接口,比如 registerBeanDefinition registerSingleton
- 处理依赖的一些方法。resolveNamedBean resolveDependency doResolveDependency resolveMultipleBeans
AbstractAutowireCapableBeanFactory
实现默认的Bean创建,具有RootBeanDefinition指定的全部功能。
使用构造器解析提供bean创建,属性填充,wiring,初始化。
支持构造器注入、名字或类型注入。
没有任何的bean注册能力。
通过上述的接口和类的介绍,BeanFactory的子类和相关子接口有个了大致的了解,使用由上至下的顺序介绍了spring Ioc 容器的功能,其中还有一些类或者接口没有介绍到,可以在源码中进入详细了解。
Spring Framework 启动流程。
Spring的启动流程可以简单描述为启动框架的提供功能,加载并初始化开发人员定义的类。
Spring Framework 目前几乎所有开发人员都会采用基于注解的形式开发应用。首先会使用new AnnotationConfigApplicationContext() 启动一个Spring Application Context。
AnnotationConfigApplicationContext 是继承了 GenericApplicationContext 和 AbstractApplicationContext,加载子类时会先加载父类,并使用父类的无参构造或者指定的有参构造创建父类。GenericApplicationContext的无参构造器中会创建一个DefaultListableBeanFactory,对于DefaultListableBeanFactory的父类AbstractAutowireCapableBeanFactory 同样也会被加载到Jvm中,创建对应Class对象。AbstractApplicationContext是一个抽象类,不过其中静态属性和静态方法也会被初始化,创建 PathMatchingResourcePatternResolver 作为默认的 ResourcePatternResolver。
初始化完父类后,就会执行 AnnotationConfigApplicationContext 无参构造器,创建 AnnotatedBeanDefinitionReader 和 ClassPathBeanDefininationScanner。
AnnotatedBeanDefinitionReader的构造器中,除了一些赋值外,会执行 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
这行代码对基于注解的应用尤为的至关重要。其中会将一批框架提供的配置类包装为Bean Definition放入BeanFactory,其中包括:
- ConfigurationClassPostProcessor
- AutowiredAnnotationBeanPostProcessor
- CommonAnnotationBeanPostProcessor
- EventListenerMethodProcessor
- DefaultEventListenerFactory
- AnnotationAwareOrderComparator
- ContextAnnotationAutowireCandidateResolver
大多是一些后置处理器和工具类。
ClassPathBeanDefininationScanner主要是用来扫描classpath路径下类,继承 ClassPathScanningCandidateComponentProvider 提供扫描过程中的一些配置。
以上就是AnnotationConfigApplicationContext对象创建的流程,即将进入 AbstractApplicationContext.refresh()
方法。
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.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean 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");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// 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();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
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();
}
}
}
这是一个Spring context的启动流程,有些context可以启动多次,有些只能启动一次,另外也会提供取消启动和重新启动的API.
prepareRefresh()
准备启动Spring context
- 设置启动时间
- 激活工作标识
- 初始化context中所有的 placeholder property sources
- 验证启动比如设置的变量
- 保存重新启动前的ApplicationListener
obtainFreshBeanFactory()
通知子类刷新内部的BeanFactory,其中子类比较关注 GenericApplicationContext。
- 原子更新刷新标识。
- 设置BeanFactory的唯一标识。
prepareBeanFactory()
准备上下文中的BeanFactory,配置标准context中的classLoader 和一些 PostProcessors
- 若要使用SPEL,则配置StandardBeanExpressionResolver。
- 增加ResourceEditorRegistrar 到 propertyEditorRegistrar。
- 配置分析依赖时需要忽略的接口 EnvironmentAware EmbeddedValueResolverAware ResourceLoaderAware
- 配置 ApplicationContextAwareProcessor ApplicationListenerDetector ApplicationEventPublisherAware MessageSourceAware ApplicationContextAware ApplicationStartupAware,这些接口需要框架提供支持,不需要在依赖注入时处理。
- 若要使用加载时创建代理,则配置LoadTimeWeaverAwareProcessor ContextTypeMatchClassLoader
- 配置处理依赖注入时需要注入的对象,比如Bean需要一个 ApplicationContext,在进行注入时会将配置的对象注入到Bean当中。
- 注册几个环境变量相关的Bean,systemProperties systemEnvironment。
postProcessBeanFactory()
处理 postProcessBeanFactory,暂未发现有效调用,是个空方法。
invokeBeanFactoryPostProcessors()
调用已注册的postProcessBeanFactory。
使用委托模式将PostProcessor的注册工作放置到 PostProcessorRegistrationDelegate中,调用 invokeBeanFactoryPostProcessors(),处理context中的BeanFactoryPostProcessor。
判断BeanFactory是否继承BeanDefinitionRegistry接口,没有继承就会直接调用 invokeBeanFactoryPostProcessors处理context中的beanFactoryPostProcessors。若继承BeanDefinitionRegistry:
- 对context中的beanFactoryPostProcessors,进行分类,属于BeanDefinitionRegistryPostProcessor的 postProcessor 执行 postProcessBeanDefinitionRegistry()。
- 获取BeanFactory中的 BeanDefinitionRegistryPostProcessor.class 类型的BeanName数组,接下来就会遍历BeanName数组。
- 若bean实现了 PriorityOrdered \ Ordered 类,就会调用 invokeBeanDefinitionRegistryPostProcessors 处理BeanDefinition的注册工作。逻辑较多,独立在后续说明。
- 接着会调用 invokeBeanFactoryPostProcessors 执行 postProcessBeanFactory().
- 对@Configuration的类创建代理,并注册 ImportAwareBeanPostProcessor 到 BeanPostProcessor 的 BeanPostProcessor.
- 对BeanFactoryPostProcessors进行分类和排序 invokeBeanFactoryPostProcessors.
此过程处理的postProcessors,可以是开发人员定义的,也有框架指定的。上面提到过:
AnnotatedBeanDefinitionReader的构造器中,除了一些赋值外,会执行 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
将处理 context 环境中开发人员定义的类 Service Controller ... ConfigurationClassPostProcessor 注入到 BeanFactory中。
registerBeanPostProcessors()
注册BeanPostProcessors 去拦截Bean的创建。
- PostProcessorRegistrationDelegate.registerBeanPostProcessors();
- 将BeanFactory中的 BeanPostProcessor BeanDefinition 转换为 BeanFactory的 BeanPostProcessor.
- 转换过程中会根据BeanDefiniton上面的Order \ PriorityOrdered 先排序再处理。
initMessageSource()
初始化context中的国际化。
过程和centext event 初始化过程相似,先检查 beanFactory 中的 MESSAGE_SOURCE_BEAN_NAME,若没有此BeanDefinition 就会使用默认实现 DelegatingMessageSource 并以单实例的方式注册到 context。另外会处理父子MessageSource,设置子MessageSource的时候会检查并设置父MessageSource。
initApplicationEventMulticaster()
初始化context中的事件机制。
BeanFactory中若有 APPLICATION_EVENT_MULTICASTER_BEAN_NAME BeanDefinition,就会采用Bean创建的模式为 context 中的applicationEventMulticaster 赋值,可以利用此特性去覆盖框架提供的默认实现,只需要自己实现的类被context 扫描到就行。
若没有的话就会使用默认实现 SimpleApplicationEventMulticaster ,并将对象以单实例的方式注入到 context.
onRefresh()
初始化在特定的子context中的特定Bean。空实现。
registerListeners()
检查context中的所有Listener,并注册他们。
首先会注册静态的Listener,接着会获取 BeanFactory 中的 ApplicationListener, 注意此处并不会对获取到BeanDefinition 进行初始化,而是将Beanname 放入到 applicationEventMulticaster的 ApplicationListenerBean 中。最后会检查是否有一批早期事件需要发布,需要的话会直接发布出去。
finishBeanFactoryInitialization()
实例化所有非懒加载的单实例Bean。
在BeanFactory走过了:
- 执行 BeanFactoryPostProcessors
- 注册BeanPostProcessors
- 初始化国际化、事件派发
- 注册context中的事件监听器
Context 中的BeanFactory 的初始化工作进入了尾声阶段,此时BeanFactory中的Bean实例全部是使用registrySingleton()注册,扫描到的组件并没有实例化,实例化工作集中在本方法中进行。
首先需要设置BeanFactory中的 embeddedValueResolver 处理注解中需要处理的placeholders.
接着是LoadTimeWeaverAware接口的子类Bean创建,先加载此接口的子类Bean,可以早点注册 transformers 。
停止使用BeanFactory中的临时的类加载器。
可以缓存所有BeanDefinition metadata,但是不能发生更改其中的内容。
开始初始化所有的非懒加载的单实例bean.
- 创建 beanDefinitionNames 副本,在副本上迭代处理BeanDefinition,允许在Bean创建过程中执行init methods是注册新的BeanDefinition.
触发所有非懒加载的单例Bean。
- 合并BeanDefinition。getMergedLocalBeanDefinition()
- 只处理非抽象类 & 单例 & 非懒加载的 BeanDefinition.
- 判断是否属于factoryBean。isFactoryBean()
- 先分析非factoryBean的情况,FactoryBean的逻辑部分会在后续补充。
- 进入AbstractBeanFactory中,创建Bean.
- 调用getBean() -> doGetBean() .
- transformedBeanName() 转换BeanName,转换bean aliases为一个规范的BeanName。
- 检查bean是否已存在于手动注册的单例缓存中,可能是完全创建的状态,也许是正在创建状态。
- 获取前期手动注册的单例Bean, 调用 getObjectForBeanInstance() 就可以返回BeanInstance.
若前期没有注册过BeanInstance,就进入下面的逻辑。
- 检查当前需要创建的Bean是多例Bean的话直接抛错。
- 检查父BeanFactory是否为空,并且父Bean Factory中包含此BeanDefinition.就会调用父Bean Factory的getBean(),去创建BeanInstance.
- 获取 BeanDefinition 的依赖 mbd.getDependsOn()。遍历依赖项 逐个先创建依赖项。
- 接着创建单例Bean的执行处理。进入 getSingleton().
- 从singletonObjects中获取是否已创建BeanInstance.
- 检查是否BeanSingleton正在销毁,若是则直接抛出异常。
- 开始执行 singletonFactory.getObject()。调用doGetBean中的匿名接口ObjectFactory。
- getSingleton()方法主要是控制BeanInstance的创建,加锁和创建的条件判断。
- 现在开始进入 AbstractAutowireCapableBeanFactory.createBean()方法。
- 第一步解析BeanDefinition中的BeanClass,加载BeanClass文件,获得Class对象。并创建BeanDefinition的本地变量,将Class对象设置进去。
- 第二步验证并准备BeanDefinition中重载方法的状态。
第三步应用BeanInstance Before Post Processor,判断BeanFactory中是否有 InstantiationAwareBeanPostProcessor 子类存在。若没有直接返回。
- 调用 applyBeanPostProcessorsBeforeInstantiation,执行实现类的 postProcessBeforeInstantiation().
- InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 有个默认实现先调用, 空方法而已。
- AbstractAutoProxyCreator#postProcessBeforeInstantiation,此方法会创建代理,详细内容可在后续中分析。
- 进入同类的doCreateBean()。
进入同类的createBeanInstance()。为指定的Bean创建Instance,使用合适的instance策略:工厂方法、构造装配、无参构造。
- 确保已执行resolveBeanClass。若Bean calss 不是public 直接抛错。
- 获取BeanDefinition.getInstanceSupplier() -> obtainFromSupplier()获取Instance.
- 获取BeanDefinition.getFactoryMethodName() -> instantiateUsingFactoryMethod() 工厂方法获取Instance。
- determineConstructorsFromBeanPostProcessors() 推断构造 -> autowireConstructor() 构造创建。
- 未指定处理,就使用无参构造,进入 instantiateBean().
- getInstantiationStrategy().instantiate() 使用无参构造创建Instance,BeanUtils.instantiateClass()返回无参构建的Instance Wrapper.
applyMergedBeanDefinitionPostProcessors -> postProcessMergedBeanDefinition ->
- ApplicationListenerDetector#postProcessMergedBeanDefinition
- AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
- CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
- 执行上述的三个实现方法。
- 有个三个条件,创建的是单例Bean,context允许循环引用,Bean正在实例化,若三个条件全部符合则执行
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
此方法最终会执行 singletonFactories.put 方法。 - 开始初始化BeanInstance. 先属性填充,再类初始化。
- 属性填充会执行 InstantiationAwareBeanPostProcessors.postProcessAfterInstantiation() 实现类去修改属性被赋值之前的Bean状态。
- InstantiationAwareBeanPostProcessor.postProcessProperties().
- 执行 aware 的注入 invokeAwareMethods()
- applyBeanPostProcessorsBeforeInitialization() postProcessBeforeInitialization(),执行初始化前回调。
- 调用 init method
- applyBeanPostProcessorsAfterInitialization() postProcessAfterInitialization(),执行初始化后回调。
- 触发所有应用Bean的初始化后置后调。
SmartInitializingSingleton.afterSingletonsInstantiated(),通知所有单例Bean已被创建完成。
finishRefresh()
发布事件。
扫描BeanDefinition的过程分析。
ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()
- 检查是否已执行过,不能重复执行。
- 进入 processConfigBeanDefinitions()。
获取Context中被@Configuration标注的类。
- 判断BeanDefinition是否拥有属性 ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE,作为已处理的标识。
借助工具类判断 ConfigurationClassUtils.checkConfigurationClassCandidate()
- BeanDefinition中有BeanClassName属性的,没有FactoryMethodName的。
- 获取BeanDefinition中的AnnotationMetadata,可通过AnnotationMetadata.introspect(beanClass) metadataReaderFactory.getMetadataReader(className) 获取。
- AnnotationMetadata 中有设置 @Configuration注解的并且注解的属性 proxyBeanMethods为TRUE的。可以作为 full configuration 进行后续的 parse处理。
- 那些有 AnnotationMetadata 或者有 Component ComponentScan Import ImportResource 的注解 或者 有类中有方法使用@Bean BeanDefinition 就是一个 lite configuration 类。可会进行后续的 parse处理。
- 若AnnotationMetadata中有Order注解,会设置到BeanDefinition中。
- 将符合条件的BeanDefinition收集起来。
- 对获取到的BeanDefinition进行排序。
- 获取并支持定制 componentScanBeanNameGenerator importBeanNameGenerator
- 检查并设置 StandardEnvironment
开始 parse @Configuration标识的类(BeanDefinition)
- 创建 ConfigurationClassParser 对象。
- 进入 processConfigurationClass() 开始进行解析工作。
- 进入 ConditionEvaluator.shouldSkip(),会对@Condition注解进行解析判断是否需要解析此Bean。
- 使用反射技术根据 className 转化为 SourceClass.
- 递归调用 doProcessConfiguration(SourceClass)。
processMemberClasses() 处理标有 @Component 注解的内部类。
- 解析内部类是否有被@Configuration的,会直接调用 processConfigurationClass 进行解析。
processPropertySource() 处理标有 @PropertySource 注解的类。
- AnnotationConfigUtils.attributesForRepeatable() 解析出类上的@PropertySource数组,逐个处理。
- 当前 environment 必须是 ConfigurableEnvironment 的子类。
- 获取注解中的 name \ encoding \ value \ ignoreResourceNotFound \ factory。
- 将加载到的信息放到当前环境当中。
ComponentScanAnnotationParser.parse() 处理标有 @ComponentScan 注解的类。
- 创建 ClassPathBeanDefinitionScanner 对象。
- 设置 BeanNameGenerator \ ScopedProxyMode \ ScopeMetadataResolver \ ResourcePattern \ IncludeFilter \ ExcludeFilter \ BeanDefinitionDefaults .
- 解析注解中的 basePackages \ basePackageClasses .
- 进入 doScan().
- 加载每个 package,将获取到的 metadataReader 作为创建 ScannedGenericBeanDefinition 的参数。
- 判断 ScannedGenericBeanDefinition 是否有被@Component注解,符合的放入方法结果集中。
- 遍历结果集。
- 判断是否实现 AbstractBeanDefinition,调用postProcessBeanDefinition进行处理。
- 判断是否实现 AnnotatedBeanDefinition,调用AnnotationConfigUtils.processCommonDefinitionAnnotations()进行处理。
- 根据BeanDefinition的冲突处理结果注册BeanDefinition.
- 从加载到BeanDefinition中过滤是否有@Configuration标注的类,有的话直接调用parse().
processImports() 处理标有 @Import 注解的类。
- 判断是否有循环导入的问题
处理导入的类实现ImportSelector 接口
- 加载被导入的类。
- ParserStrategyUtils.instantiateClass() 将注解解析为 ImportSelector 对象 selector。
- 若 selector 实现了 DeferredImportSelector,直接放入deferredImportSelectorHandler。
- 递归处理导入类上的@Import。
处理导入的类实现ImportBeanDefinitionRegistrar 接口
- 加载被导入的类。
- ParserStrategyUtils.instantiateClass() 将注解解析为 ImportBeanDefinitionRegistrar 对象 registrar。
- 添加到 ImportBeanDefinitionRegistrar 中,在@Configuration注解解析完成后再进行加载。
处理导入的其他类
- 直接使用 processConfigurationClass 处理。
addImportedResource() 处理标有 @ImportResource 注解的类。
- AnnotationConfigUtils.attributesFor() 解析出 AnnotationAttributes importResource 。
- 将解析出的resource 放入 ImportedResource 中。
addBeanMethod() 处理标有 @Bean 注解的方法。
- 获取类中使用@Bean的方法 使用Java反射和ASM获取两遍,并进行比较方法数量和方法名字的比较。
- 比较通过的方法放入结果集中。
- 将结果集逐个放入BeanMethod
processInterfaces() 处理接口的默认方法。
- 处理继承的抽象类非抽象方法或者接口的默认方法
- 将父类或者实现的接口中的@Bean标注的方法放入 BeanMethod
- 循环处理父类或者父接口.
解析 superclass.
- 处理父类,直接返回循环处理.
this.deferredImportSelectorHandler.process() 开始处理延迟导入队列.
- 将队列中的ImportSelector逐个放入 DeferredImportSelectorGroupingHandler.registry()
- 实现逻辑较复杂,后续会继续分析.
ConfigurationClassBeanDefinitionReader.loadBeanDefinitions()
registerBeanDefinitionForImportedConfigurationClass
- new AnnotatedGenericBeanDefinition(metadata) 构建 BeanDefinition 对象.
- 获取 BeanDefinition 中的 scopeMetadata, 经 scopeMetadataResolver.resolveScopeMetadata()处理 设置BeanDefinition的scope
- importBeanNameGenerator.generateBeanName() 生成BeanName.
- AnnotationConfigUtils.processCommonDefinitionAnnotations()
- 注册BeanDefinition.
- loadBeanDefinitionsForBeanMethod
- loadBeanDefinitionsFromImportedResources
- loadBeanDefinitionsFromRegistrars
- 对比parse前后的registry中的BeanDefinition数量,将未处理的BeanDefiniton继续处理.
- Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
以上就是对SpringFramework IOC部分的大致流程解析,其中有不少的知识点没有详细分析,后续会基于Spring启动流程中某一个知识点深入分析。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。