解读 spring源码

整理一下spring源码,可能相当于一个大纲,细节的话还需要自己实际慢慢看慢慢磨,不一定全对,都是自己研究的。

//一、创建一个srping容器,并放置几个核心的 Processor CommonAnnotationProcessor AutowiredAnnotationProcessor
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
//二、将入口类告知spring,你不说我怎么知道哪个是入口,扫描包等都需要依赖注解类
annotationConfigApplicationContext.register(DemoApplication.class);
//三、核心类完成spring容器的初始化,一个bean的完整的生命周期都在这里
annotationConfigApplicationContext.refresh();

一、创建spring容器,重要方法解读  this.reader = new AnnotatedBeanDefinitionReader(this); 该方法会一直调用至如下方法:

这个方法其实就做了两件事:

① 拿到了 GenericApplicationContext内的DefaultListableBeanFactory,其实这个GenericApplicationContext 就是一个BeanDefinitionRegistry

② 注册了很多的Processor:说是注册其实就是放到Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(4)里面,其中这里初始化的Beandefinition都是RootBeandefinition

    1、org.springframework.context.annotation.internalConfigurationAnnotationProcessor(非常重要完成了类------>beanDefinition的转化)  对应:class org.springframework.context.annotation.ConfigurationClassPostProcessor

     2、org.springframework.context.annotation.internalAutowiredAnnotationProcessor

                 对应:class org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor

     3、org.springframework.context.annotation.internalRequiredAnnotationProcessor

                对应: class org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor

     4、org.springframework.context.annotation.internalCommonAnnotationProcessor

                对应:class org.springframework.context.annotation.CommonAnnotationBeanPostProcessor

     5、org.springframework.context.event.internalEventListenerProcessor

      6、org.springframework.context.event.internalEventListenerFactory

二、容器准备好了spring需要的BeanPostProcessor和BeanFactoryPostProcessor准备好了,下面需要把我们的入口类注册给spring。

三、核心方法refresh

1、this.obtainFreshBeanFactory() 就是获取 GenericApplicationContext中的 DefaultListableBeanFactory beanFactory。

2、prepareBeanFactory在beanFactory中添加一个需要的类,比如:ApplicationContextAware,ApplicationContext,还有两个BeanPostProcessor:ApplicationContextAwareProcessor(重要)、ApplicationListenerDetector

3、invokeBeanFactoryPostProcessors 在bean初始化之前执行(beanFactory即DefaultListableBeanFactory 就是一个BeanDefinitionRegistry),调用beanFactoryPostProcessor(自定义的beanFactoryPostProcessor,程序员可以通过调用annotationConfigApplicationContext.addBeanFactoryPostProcessor(),向其中注册beanFactoryPostProcessor)和BeanDefinitionRegistryPostProcessor 的postProcessBeanDefinitionRegistry。

spring通过自己定义的 ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry

(非常重要) 完成对注解的扫描,把类封装成了beanDefinition,其中遇到注解@Import 时,如果对应的类实现了ImportBeanDefinitionRegistrar,DeferredImportSelector或者ImportSelector 递归遍历所有的类。三者实现略有不同;简单阐述就是ImportBeanDefinitionRegistrar,DeferredImportSelector会被放到一个list集合中延迟执行对应的方法;而ImportSelector selectImports方法则是在 调用时被立即执行,则会立即执行具体可以参考如下链接:

AutoConfigurationImportSelector到底怎么初始化 - 简书;(在springboot的中也使用了DeferredImportSelector但是并不是调用selectImports而是调用AutoConfigurationImportSelector的getAutoConfigurationEntry实现的自动配置;很神奇参考如下链接springboot的自动启动 )

这里会把beanFactory传进来,操作beanFactory完成一系列操作register就是beanFactory,此时beanDefinition只有7个,其中DemoApplication,是我们自己注册进来的,如果beanDefinition被 @Configuration注解修饰,则是full的,后期会被生成一个代理类。

ClassPathBeanDefinitionScanner

这里的核心方法就是 ConfigurationClassParser.parse(Set<BeanDefinitionHolder> candidates), 转化所有被注解修饰的类,变为BeanDefinition,如果有@Import注解的话则循环扫描里面所有的类,并封装成beanDefinition。

4、registerBeanPostProcessors 注册所有的BeanPostProcessors到beanFactory中

 ① ConfigurationPropertiesBindingPostProcessor

 ② CommonAnnotationBeanPostProcessor

 ③ AutowiredAnnotationBeanPostProcessor

 ④ RequiredAnnotationBeanPostProcessor

5、经过上面得四步,所有得类都被封装成了BeanDefinition,环境准备工作完成,接下就是bean的实例化以及初始话过程。      finishBeanFactoryInitialization 最核心的方法,完成了对象的创建,属性填充,生命周期回调,aop。

 doGetBean内逻辑比较多 主要是:

① 调用 getSingleton,查看单例池中有没有,或者是不是正在创建,多次调用getSingleton方法解决了循环依赖;实现思路如下:

     1>第一次调用时判断,一级缓存中有没有或者是否正在创建,如果二级缓存中有则直接返回,没有则从三级缓存中取出来,三级工厂调用的getObject方法返回的是bean的实例。

  2> 第二次调用:重载了getSingleton方法,会把beanName放到一个Set集合中表示正在创建

this.beforeSingletonCreation(beanName),

private final Set singletonsCurrentlyInCreation = Collections.synchronizedSet(new HashSet());

同时暴漏一个工厂出来,如果该bean是单例的,并且开启了循环依赖,并且是正在创建的,这时再把创建bean的过程中会把工厂添加到三级缓存内。

AbstractAutowireCapableBeanFactory 

 ②这里有个小插曲,描述如下:  

   在spring createBean之前会调用 this.resolveBeforeInstantiation(beanName, mbdToUse) ,调用 如果bean 实现了InstantiationAwareBeanPostProcessor 并且 直接返回bean则spring不再创建,可能调用后置处理器:

 ③最重要的代码:bean的实例化和初始化

  ** 第三步:getEarlyBeanReference 方法,在解决循环依赖的时候会调用singletonFactory.getObject(),也就是从三级缓存中去拿bean数据,会调用所有实现SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法,这里的 AbstractAutoProxyCreator类中 就实现了这个接口的这个方法,而getEarlyBeanReference会调用wrapIfNecessary()方法完成aop**。

 1、创建bean对象,推断构造方法 + 反射

 推断构造方法:第 1  次后置处理器调用 ,会对所有的构造方法排序,public和方法参数多的在前,找到合适的构造方法,不过一般使用默认的,调用如下:

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor的determineCandidateConstructors

反射:其实最后就是这一句话,使用构造方法创建对象

ReflectionUtils.makeAccessible(ctor);
return ctor.newInstance(args);

2、第 2 次后置处理器调用: 调用applyMergedBeanDefinitionPostProcessors (mbd, beanType, beanName)方法进行bd的merge,合并会调用beanPostProcess的 MergedBeanDefinitionPostProcessor进行bd的合并。

3、第 3 次后置处理器调用:调用 AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean) 调用AbstractAutoProxyCreator 的 getEarlyBeanReference 提早完成 aop。

4、属性填充: 

       ① 第4 次后置处理器调用: 如果某一个BeanDefinition 实现了 InstantiationAwareBeanPostProcessor 的 postProcessAfterInstantiation并且返回fasle,则可以自己完成属性填充,后续spring不再填充属性

        ② 会判断注入模型 ,默认是0不自动注入。

       ③  第 5 次后置处理器调用: 最后调用所有的InstantiationAwareBeanPostProcessor类型的 beanPostProcess的 postProcessPropertyValues方法完成属性注入,主要使用的是CommonAnnotationBeanPostProcesser和AutowiredAnnotationBeanPostProcesser两个,这就是@Resource和@Autowired的区别,最后利用反射填充属性;

 @Resource和@Autowired 区别

@Resource: CommonAnnotationBeanPostProcesser 的 postProcessPropertyValues方法内部调用的是findResourceMetadata方法获取元信息,

@Autowired: AutowiredAnnotationBeanPostProcesser 的postProcessPropertyValues方法内部调用的是findAutowiringMedadata方法获取元信息,

 

 最后调用

5、initializeBean 初始化bean ,完成 生命周期回调,aop。

① 如果对应的类实现了Aware:BeanNameAware, BeanClassLoaderAware,BeanFactoryAware 则会提前执行这些方法。

②  第6次后置处理器调用: 执行所有的BeanPostProcess的 postProcessBeforeInitialization,如果使用 @PostConstruct 注解的方式声明回调,则调用CommonAnnotationBeanPostProcess的 postProcessBeforeInitialization执行回调。

③  如果是实现了接口的 InitializingBean的afterPropertiesSet 方法,或者 是xml中配置的  init-method 则在 invokeInitMethods的时候通过方法反射完成回调。

第7 次后置处理器调用: 执行 BeanPostProcessor 的postProcessBeforeInitialization 。

⑤ 第8次后置处理器调用: 执行 所有的BeanPostProcessor 的applyBeanPostProcessorsAfterInitialization方法。

    spring 的aop就是在调用 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator 或者

AbstractAutoProxyCreator 的postProcessAfterInitialization 完成对象代理的,根据是否实现接口区分使用JdkDynamicAopProxy 动态代理还是Cglib代理。

如果循环依赖的话会提前完成aop,所以叫wrapIfNecessary。 查找对应的类是否有对应的切点,有的话才会生成代理:

Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);

调用代理DefaultAopProxyFactory的代理工厂,根据是否有接口选择, 有接口则使用jdk动态代理,否则使用cglib代理

四、spring中使用的设计模式

  1、责任链模式:spring在bean实例化之前,需要对beanFactory进行一系列操作比如: 1、beanFactory的初始化 2、把bean解析成beanDefinition对象,3、执行beanFactoryPostProcessor把 实现ImportBeanDefinitionRegistrar接口的类生成的 BeanDefinition 加入到beanFactory的 Map<String, BeanDefinition> beanDefinitionMap中。4、把BeanPostProcess放入到beanFactory中,这一系列的操作中入参都只有beanFactory。

2、简单工厂:application.getBean("a"),通过beanName生成对应的Bean。

3、工厂模式: factoryBean.getObject();返回的是一个bean,当然也可以是一个工厂类,这里使用的就是工厂模式

4、单例模式,默认情况下bean都是单例的,因为都放置到beanDefinitionMap 单例池中,初始化过的不会再初始化。

5、适配器模式:在springmvc中,controller的实现方式有两种:1、使用注解@Controller 2、实现Controller接口 ,解析请求根据实现的方式对应不同的HandlerMapping,找到对应的 HandlerExecutionChain,再根据不同的HandlerExecutionChain生成不同的adapter,最后执行不同handler的方法,@controller是转化成HandlerMethod执行 实现接口转化成controller执行

6、代理模式: spring aop会生成一个代理对象执行对应的方法。

五、接口类图整理

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值