spring源码笔记

Spring源码

spring运行流程 ,最大的特点就是可扩展性

在这里插入图片描述

创建BeanDefinition对象

在这里插入图片描述

BeanDefinition接口:把配置文件定义的属性,分装成BeanDefinition对象并且填充占位符,不会自动去填充properties的值,放入到Container容器中。(利用loadBeanDefinitions(beanFactory),方法填充beandefinitionMap,和beandefinitionNames)。

@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工厂(DefltListableBeanFactory)。
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      //准备bean工厂一系列set,get方法。
       prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         //Spring做了一些空方法,boot做了一些扩展和实现
          postProcessBeanFactory(beanFactory);

         StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
         // Invoke factory processors registered as beans in the context.
         //执行BeanFactoryPostProcessor放入BeanFactory中。boot自动装配的一些细节
          invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         //注册BeanPostProcessor并实例化
          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.
         //boot的tomcat实现
          onRefresh();

         // Check for listener beans and register them.
         //注册监听器
          registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         //实例化所有非懒加载的实例对象,反射代码ctor.newinstance(); Bean的周期,实例化的操作都在这里实现。核心代码。
          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();
      }
   }
}

具体细节:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

循环依赖——三级缓存

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V55I37FD-1648712250398)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220224153130123.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bZSW2oeJ-1648712250399)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220225164309236.png)]

三级缓存中分别保存的是什么对象
1:成品对象
2:半成品对象
3:lambda表达式
2、如果只使用1级缓存行不行?
不行,因为成品和半成品对象会放到一起,在进行对象获取的时候有可能获取到半成品对象,这样的对象是没法使用的
3、如果只有二级缓存行不行?
getSingleton
doCreateBean
只有二级缓存的时候也可以解决循环依赖的问题,
添加aop的实现之后,报错,This means that said other beans do not use the final version of the bean.没有使用最终版本的bean对象
4、三级缓存存在到底做了什么事?
如果一个对象需要被代理,生成代理对象,那么这个对象需要预先生成非代理对象吗?需要
三级缓存到底做了什么?
lambda:getEarlyBeanReference(),只要搞清楚这个方法的具体执行逻辑即可
在当前方法中,有可能会用代理对象替换非代理对象,如果没有三级缓存的话,那么就无法得到代理对象,换句话说在整个容器中,包含了同名对象的代理对象和非代理对象,你觉得可以吗?
容器中,对象都是单例的,意味着根据名称只能获取一个对象的值,此时同时存在两个对象的话,使用的时候应该取哪一个?无法判断
谁也无法确认什么时候会调用当前对象,是在其他对缘的执行过程中来进行调用的,而不是人为指定的,所以必须要保证容器中任何时候都只有个对象供外部调用,所以在三级缓存中,完整了一件代理对象替换非代理对象的工作,确定返回的是唯一的对象。

三级缓存是为了解决在aop代理过程中产生的循环依赖问题,如果没有aop的话,二级缓存足矣解决循环依赖问题。
其实相当于是一个回调机制,当我都需要使用当前对象的时候,会判断此对象是否需要被代理实现,如果直接替换,不需要直接返回非代理对象即可。
5、spring是一个框架,跟业务完全无关,框架如何知道你什么时候用aop,什么时候不用aop呢?
但是在调用时候的时候,如果出现此问题怎么办呢?最重要的一件事,走总体的流程,如果有,就处理,没有就直接返回,不会有额外的任何影响。

第二步:填充占位符

在实例化对象的过程中使用 :PlaceholderConfigurerSupport实现BeanFactoryPostProcessor接口对BeanDefinition(转换成Bean对象时不会自动的填充属性值)的属性进行占位符填充,实现替换工作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K5wnzON1-1648712250401)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220223120644352.png)]

第二步:自动装配(@注解)

spring中存在ConfigurationClassPostProcessorjava方法,底层分别去解析了所有的注解并进行处理,底层本质走的XML方式。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QUeLgui7-1648712250403)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220223124133379.png)]

通过反射的方式进行对象的实例化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VTUV3o6t-1648712250407)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220223124559299.png)]

<1>创建对象
在这里插入图片描述

实例化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GHu2Sxlv-1648712250410)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220223125345801.png)]

总结:容器和对象的创建流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4zUsiPor-1648712250410)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220224113850988.png)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值