spring源码脑图
2021-07-04 16:47:56 38 举报
AI智能生成
登录查看完整内容
源码脑图
作者其他创作
大纲/内容
spring源码脑图
refresh()
//1、初始化前的预处理\t\t\tprepareRefresh();
//2、获取BeanFactory,加载所有xml配置文件中的bean定义信息(未实例化)\t\t\tConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//刷新BeanFactory(包含配置文件的加载和解析)\t\trefreshBeanFactory();\t\tConfigurableListableBeanFactory beanFactory = getBeanFactory();
//加载配置文件\t\t\tloadBeanDefinitions(beanFactory);
//XML配置文件由XmlBeanDefinitionReader解析\t\tXmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//使用xml解析器,解析xml配置文件\t\tloadBeanDefinitions(beanDefinitionReader);
//加载配置文件资源路径的xml配置文件\t\t\treader.loadBeanDefinitions(configLocations);
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
doRegisterBeanDefinitions(root);
//取<bean>上的profile属性,并根据Environment中配置好的profile决定是否继续解析(profile过滤)\t\t\tString profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
//解析xml元素为BeanDefinition\t\t//bdHolder内部组合了BeanDefinition\t\tBeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
//3、BeanFactory的预处理配置\t\t\tprepareBeanFactory(beanFactory);
//4、准备BeanFactory完成后进行的后置处理\t\t\t\tpostProcessBeanFactory(beanFactory);
//5、执行BeanFactory创建后的后置处理器\t\t\t\tinvokeBeanFactoryPostProcessors(beanFactory);
1、将BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor分离开
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//解析配置类(解析配置类中的定义的bean,并封装为BeanDefinition)\t\tprocessConfigBeanDefinitions(registry);
//筛选出所有的配置类
//配置类的排序
//构造默认的BeanNameGenerator bean的名称生成器
//真正解析配置类的组件:ConfigurationClassParser\t\tConfigurationClassParser parser
//解析配置类\t\t\tparser.parse(candidates);
//如果配置类已经@Import过了,则跳过
//处理@PropertySource注解processPropertySource(propertySource);
//解析@PropertySource注解的属性
//处理路径,加载资源文件,并添加进environment中
//处理@ComponentScan注解
//如果有@ComponentScans,则要取出里面所有的@ComponentScan依次扫描
//1、构造ClassPathBeanDefinitionScanner,并封装@componentScan注解中的属性
//2、整理要进行包扫描的basePackages,以及include和exclude的过滤器
//3、执行包扫描动作return scanner.doScan(StringUtils.toStringArray(basePackages));
//【真正的包扫描动作在这里】\t\t\tSet<BeanDefinition> candidates = findCandidateComponents(basePackage);
return scanCandidateComponents(basePackage);
//加载.class文件
//如果符合匹配规则,则封装为ScannedGenericBeanDefinition
迭代candidates
//处理scope(默认情况下是singleton)
//生成bean的名称
//处理bean中的@Lazy,@Primary等注解
//设置AOP相关的属性(如果支持的话)
//防止循环@Import导入
//处理ImportSelector
//DeferredImportSelector的执行时机后延
//执行ImportSelector的selectImports方法,并注册导入的类
//处理ImportBeanDefinitionRegistrar
//导入普通类、配置类
//处理@ImportResource注解(保存进configClass)
//处理@Bean注解(也只是保存进configClass)Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
//获取被@Bean标注的方法
//spring使用ASM读取字节码,为了保证加载配置类中的@Bean方法的从上到下的顺序与源文件.java中一致
//寻找接口中标注了@Bean的方法
/父类的返回(配置类存在父类,父类也应该一起加载,迭代处理)
子主题
//编程式注入配置类
//其他情况
//回调特殊的ImportSelectors,DeferredImportSelectors它的执行时机比ImportSelectors更晚,\t\t// 它会在注解配置类的所有解析工作完成后才执行\t\tprocessDeferredImportSelectors();
//加载配置类的内容\t\t\tthis.reader.loadBeanDefinitions(configClasses);
//与条件配置有关
//如果当前配置类是被@Import的,要把自己注册进BeanFactoryregisterBeanDefinitionForImportedConfigurationClass(configClass);
//构造AnnotatedGenericBeanDefinition
//包装BeanDefinitionHolder
//注册进BeanDefinitionRegistry
//注册@Bean注解方法(在解析阶段,只是对@Bean加入的处理)loadBeanDefinitionsForBeanMethod(beanMethod);
//如果条件装配将其跳过,则该@Bean标注的方法,对应的BeanDefinition不会注册进BeanDefinitionRegistry
//检查方法上真的有@Bean注解吗
//如果bean指定了多个name,则第一个作为为唯一标识,其余都是alias别名
//注解中配置了@Bean,与xml中的bean撞车了,会抛出异常
//构造ConfigurationClassBeanDefinition
//【复杂】解析@Bean所在方法的修饰符
//处理@Bean的属性(name,initMethod等),额外的注解(@Lazy,@DependsOn等)
//注册来自xml配置文件的bean(使用XmlBeanDefinitionReader搞的)\t\tloadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
//注册来自ImportBeanDefinitionRegistrars的bean\t\tloadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
//一些额外处理动作
1、执行 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法 (1)执行实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor (2)执行实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessor (3)执行普通的 BeanDefinitionRegistryPostProcessor2、执行 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory 方法 同上3、执行BeanFactoryPostProcessor 的 postProcessBeanFactory 方法 同上
//6、注册bean的后置处理器\t\t\t\tregisterBeanPostProcessors(beanFactory);
//获取ioc容器中已经有的BeanPostProcessor的name
//1.1此处会先注册一个BeanPostProcessorChecker
//根据排序规则,给所有的后置处理器分类
//1.2注意此处,PriorityOrdered类型的后置处理器被提前初始化了(防止优先级低的后置处理器干预了优先级高的后置处理器,从而引发程序的运行情况异常)
//MergedBeanDefinitionPostProcessor要额外筛选出来
//首先,注册所有实现了PriorityOrdered接口的后置处理器
//其次,注册所有实现了Ordered接口的后置处理器
//最后注册所有普通的后置处理器
//1.3注意此处,所有的MergedBeanDefinitionPostProcessor又被注册了一次
//最后又注册了一个ApplicationListenerDetector
//7、初始化MessageSource\t\t\t\tinitMessageSource();
//8、初始化事件派发器\t\t\t\tinitApplicationEventMulticaster();
//9、子类的多态onRefresh\t\t\t\tonRefresh();
//10、注册监听器\t\t\t\tregisterListeners();
//到此为止BeanFactory已创建完成\t\t\t\t// Instantiate all remaining (non-lazy-init) singletons.\t\t\t\t//11、初始化所有剩下的单例bean\t\t\t\tfinishBeanFactoryInitialization(beanFactory);
//处理单实例bean的初始化\t\tbeanFactory.preInstantiateSingletons();
//此处循环初始化剩余的非延迟加载的单实例bean
//先合并BeanDefinition\t\t\tRootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//不是抽象的、不是延迟加载的单实例bean要初始化
//普通的初始化,就是getBean方法\t\t\t\t\tgetBean(beanName);
//处理bean的alias
//循环依赖的探测
//如果原型bean之间互相依赖,则一定会引发无限循环,此处会抛出循环依赖的异常
//如果本地不存在当前bean的定义信息,则尝试让父容器实例化bean\t\t\t//此举可以保证每个BeanFactory持有它应该有的bean,而不是所有的bean都集中在某一个BeanFactory中
//标记当前bean已经开始创建了
//此处会合并BeanDefinition,并检查是否为抽象类(abstract则会抛出无法实例化的异常)\t\t\t\tfinal RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//此处会处理当前bean依赖的bean的初始化
//单实例bean的初始化,如果缓存中没有,最终调用createBean
getSingleton
//加锁后,再查一次单实例bean的缓存
/【createBean】如果单实例bean的缓存中真的没有,那就创建对象(即外面的lamda表达式中的createBean方法)
进入到这个方法,那就相当于要真实的中规中矩的创建 bean 对象了!这个方法中共有三个大步骤:1、实例化 bean 对象(此时 bean 中所有属性均为空)2、属性赋值 & 依赖注入3、bean 对象的初始化(执行完该步骤后 bean 已经完整)
//处理FactoryBean的小细节问题
//factoryBeanInstanceCache的作用:获取到FactoryBean中生成的bean的类型。
//bean无法被访问,则抛出异常
//【工厂方法创建】
//这一步是为原型bean的一个小优化(由于原型bean的创建过程中,每次的执行流程都是一样的,所以执行一次后,把这个过程中\t\t// 一些需要的东西缓存起来,以备后续再创建该bean是可以直接拿这些信息,去创建bean对象)
//得到真实的bean对象引用
InitDestroyAnnotationBeanPostProcessor实现类
//用到缓存机制,把bean的初始化和销毁注解信息都保存到lifecycleMetadataCache里return buildLifecycleMetadata(clazz);
//反射所有的public方法
//寻找所有被初始化注解(@PostConstruct)标注的方法
//寻找所有被销毁注解(@PreDestroy)标注的方法
CommonAnnotationBeanPostProcessor实现类
//额外收集了@Resource注解的信息metadata = buildResourceMetadata(clazz);
AutowiredAnnotationBeanPostProcessor实现类
//已经指定好默认支持@Autowire注解、@Value注解、如果 classpath 下有来自 JSR 330 的 @Inject 注解,也会一并支持
//早期bean对象引用的获取与缓存(bean被实例化出来以后还没有进行属性赋值和组件的依赖注入,但此时的bean对象已经实实在在的存在了\t\t// 。如果在此期间,有另外的bean又需要创建它时,就不应该再创建同样的一个bean对象,而是直接拿到该引用)
//检查BeanWrapper是否存在
//回调InstantiationAwareBeanPostProcessors(postProcessAfterInstantiation方法也是干预bean的属性等东西。\t\t// 而且postProcessAfterInstantiation方法返回的boolean类型,当postProcessAfterInstantiation返回false时,\t\t// 会直接return出去,不再执行下面的属性赋值+组件依赖注入的逻辑。\t\t// 这个回调的位置,就是让咱在bean已经初始化好,但还没有开始属性赋值和依赖注入时切入自定义逻辑)
//解析出当前bean支持的自动注入模式
//它将这个过程中需要组件依赖注入的信息也封装进了PropertyValues中了,所以此时pvs就应该有一开始封装的信息,\t\t\t//以及通过自动注入封装好的依赖信息\t\t\tpvs = newPvs;
//收集所有需要注入的信息\t\tCollection<InjectedElement> elementsToIterate =\t\t\t\t(checkedElements != null ? checkedElements : this.injectedElements);
//预检查和准备
//重复解析的提前返回
//类型转换(不是重点)
//把pvs中的属性值全部应用到bean对象中。\t\t\tbw.setPropertyValues(new MutablePropertyValues(deepCopy));
//如果bean实现了BeanNameAware,则强转后调用setBeanName方法注入bean的名称
//如果bean实现了BeanClassLoaderAware,则强转后调用setBeanClassLoader方法注入当前的classLoader
//如果bean实现了BeanFactoryAware,则强转后调用setBeanFactory方法注入BeanFactory
ApplicationContextAwareProcessor实现类
由此我们可以先得出一个结论:BeanFactory 的注入时机比 ApplicationContext 早。
//回调InitializingBean的afterPropertiesSet方法\t\t\t\t((InitializingBean) bean).afterPropertiesSet();
AbstractAutoProxyCreator实现类
ApplicationListenerDetector实现类
这个 ApplicationListenerDetector它用来关联所有的监听器引用。同样的,监听器在创建的时候,也需要 ApplicationListenerDetector 把这些监听器挂进 ApplicationContext 中,这样这些监听器才可以被事件广播器使用。
//不是原型bean,且有定义销毁类型的方法
//处理特殊的scope
//原型bean的初始化,直接调用createBean
//处理自定义的scope
//类型强转前的检查
//初始化的最后阶段
//12、完成容器的创建工作\t\t\t\tfinishRefresh();
//清楚上下文级别的资源缓存\t\tclearResourceCaches();
//为当前ApplicationContext初始化一个生命周期处理器\t\tinitLifecycleProcessor();
无论 BeanFactory 中有没有 LifecycleProcessor ,它都会保证最终容器中会有,注意它的实现类是 DefaultLifecycleProcessor
//将refresh的动作传播到生命周期处理器\t\tgetLifecycleProcessor().onRefresh();
startBeans(true);\t\tthis.running = true;
//广播事件\t\tpublishEvent(new ContextRefreshedEvent(this));
start()
close()
doClose();
//广播 ContextClosedEvent 事件\t\t\t\tpublishEvent(new ContextClosedEvent(this));
//销毁bean\t\t\tdestroyBeans();
//获取到 ApplicationContext 内部的 BeanFactory ,让它去销毁所有的单实例 bean 。\t\tgetBeanFactory().destroySingletons();
DefaultListableBeanFactory实现类
super.destroySingletons();\t\t//清空单实例bean的名称\t\tthis.manualSingletonNames.clear();\t\t// 清空“类型到 name ” 的映射。(\t\t// allBeanNamesByType 中保存了 bean 的类型包含的所有 bean ,如 Person 类型的 bean 在 IOC 容器中包含 master 和 admin )\t\tclearByTypeCache();
DefaultSingletonBeanRegistry实现类
//销毁所有单实例bean\t\tfor (int i = disposableBeanNames.length - 1; i >= 0; i--) {\t\t\t//重载的 destroySingleton(beanName)\t\t\tdestroySingleton(disposableBeanNames[i]);\t\t}
//此处会处理掉BeanFactory中设计的用于处理bean循环依赖的三级缓存\t\tremoveSingleton(beanName);
//在销毁一个 bean 时,如果它有依赖其它的 bean ,则首要目标不是销毁自己,而是先销毁那些依赖的 bean ,递归销毁
//自定义bean销毁方法的回调bean.destroy();
//回调DestructionAwareBeanPostProcessor\t\t//此处会有执行@PreDestoty注解标注的方法
//回调DisposableBean接口的destroy方法\t\t\t\t\t((DisposableBean) bean).destroy();
//回调自定义的destroy-method方法
//处理bean中的bean
//销毁依赖的bean
/清空一切缓存
//关闭 BeanFactory ,实际上更接近于 “销毁” ,因为原来的 BeanFactory 无论如何都无法继续用了。\t\t\tcloseBeanFactory();
AbstractRefreshableApplicationContext实现类
//它会获取到原有的 BeanFactory ,移除序列化 ID ,并直接丢弃原来的 BeanFactory 。
GenericApplicationContext
//它只会给内部组合的 BeanFactory 移除序列化 ID 而已。
收藏
0 条评论
回复 删除
下一页