关于spring:spring源码导读别怕文章里没有贴代码

  1. 本文是一篇spring源码相干的文章。家喻户晓,读源码是一件令人恐怖的事件,看源码相干的博客、书和文章亦是如此。(笔者已经狂啃mybatis的设计与实现这本书,后果是看着超级苦楚,看完当前没留下啥印象)。鉴于此,本文的源码解析就不依照传统的去贴代码的形式去解说spring源码了,本文的源码解析以流程的形式来解说spring在每一步都干了什么,所以谓之曰spring源码导读。。。。
  2. 在正式开始spring源码导读之前,读者总得晓得spring里的各个标签是干啥的吧,因而文中前一部分列举了spring常见的注解用法。并搞了点SpringAOP和spring事务源码的解析作为前面正式开始的导读的开胃菜
  3. 介绍完了,让咱们开始吧!!!。

spring注解

  • @Configuration 用于标注配置类
  • @Bean 联合@Configuration(full mode)应用或联合@Component(light mode)应用。能够导入第三方组件,入办法有参数默认从IOC容器中获取,能够指定initMethod和destroyMethod 指定初始化和销毁办法,多实例对象不会调用销毁办法.
  • 包扫描@ComponentScan (@ComponentScans能够配置多个扫描,@TypeFilter:指定过滤规定,本人实现TypeFilter类)
    组件(@Service、@Controller、@Repository):包扫描+组件注解导入注解。
  • @Scope:设置组件作用域 1.prototype:多例的2.singleton:单例的(默认值)
  • @Lazy 懒加载
  • @Conditional({Condition}):依照肯定的条件进行判断,满足条件给容器中注册Bean,传入Condition数组,,应用时需本人创立类继承Condition而后重写match办法。
  • @Import[疾速给容器中导入一个组件]

    1. Import(类名),容器中就会主动注册这个组件,id默认是组件的全名
    2. ImportSelector:返回须要导入的组件的全类名的数组
    3. ImportBeanDefinitionRegistrar:手动注册bean
  • FactoryBean:工厂Bean,交给spring用来生产Bean到spring容器中.能够通过前缀&来获取工厂Bean自身.
  • @Value:给属性赋值,也能够应用SpEL和内部文件的值
  • @PropertySource:读取内部配置文件中的k/v保留到运行环境中,联合@value应用,或应用ConfigurableEnvironment获取
  • @Profile:联合@Bean应用,默认为default环境,能够通过命令行参数来切换环境
  • 自定义组件应用Spring容器底层的组件:须要让自定义组件实现xxxAware,(例如:ApplicationContextAware),spring在创建对象的时候,会帮咱们主动注入。spring通过BeanPostProcessor机制来实现XXXXAware的主动注入。
ApplicationContextProcessor.java

private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof Aware) {
            
            if (bean instanceof ResourceLoaderAware) {
                ((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);
            }

            if (bean instanceof ApplicationContextAware) {
                ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
            }
        }
    }
  • @Autowried 拆卸优先级如下:

    1. 应用依照类型去容器中找对应的组件
    2. 依照属性名称去作为组件id去找对应的组件
  • @Qualifier:指定默认的组件,联合@Autowried应用
    –标注在结构器:spring创建对象调用结构器创建对象
    –标注在办法上:
  • @Primary:spring主动拆卸的时候,默认首先bean,配合@Bean应用
  • @Resource(JSR250):jsr标准:依照组件名称进行拆卸
  • @Inject(JSR330):jsr标准和@Autowired性能统一,不反对require=false;

Bean生命周期:

初始化和销毁

  1. 通过@Bean 指定init-method和destroy-method
  2. 实现InitializingBean定义初始化逻辑,实现DisposableBean定义销毁办法
  3. 实现BeanPostProcessor接口的后置拦截器放入容器中,能够拦挡bean初始化,并能够在被拦挡的Bean的初始化前后进行一些解决工作。

spring底层罕用的BeanPostProcessor:

* BeanValidationPostProcessor用来实现数据校验
* AutowireAnnotationBeanPostProcessor,@Autowire实现
* ApplicationContextProcessor实现XXXAware的主动注入。

执行机会

doCreateBean
-populateBean():给bean的各种属性赋值
-initializeBean():初始化bean
-解决Aware办法
-applyBeanPostProcessorsBeforeInitialization:后置处理器的实例化前拦挡
-invokeInitMethods:执行@Bean指定的initMethod
-applyBeanPostProcessorsAfterInitialization:后置处理器的实例化后拦挡

SpringAOP实现原理

应用步骤

  1. @EnableAspectJAutoProxy 开启基于注解的aop模式
  2. @Aspect:定义切面类,切面类里定义告诉
  3. @PointCut 切入点,能够写切入点表达式,指定在哪个办法切入
  4. 告诉办法

    • @Before(前置告诉)
    • @After(后置告诉)
    • @AfterReturning(返回告诉)
    • @AfterTrowing(异样告诉)@Around(盘绕告诉)
  5. JoinPoint:连接点,是一个类,配合告诉应用,用于获取切入的点的信息

SpringAop原理

  1. @EnableAspectJAutoProxy

    • @EnableAspectJAutoProxy 通过@Import(AspectJAutoProxyRegistrar.class)给spring容器中导入了一个AnnotationAwareAspectJAutoProxyCreator。
    • AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor,InstantiationAwareBeanPostProcessor是一个BeanPostProcessor。它能够拦挡spring的Bean初始化(Initialization)前后和实例化(Initialization)前后。
  2. AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation(bean实例化前):会通过调用isInfrastructureClass(beanClass)来判断 被拦挡的类是否是根底类型的Advice、PointCut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect),若是则放入adviseBean汇合。这里次要是用来解决咱们的切面类。
  3. AnnotationAwareAspectJAutoProxyCreator的BeanPostProcessorsAfterInitialization(bean初始化后):

    1. 首先找到被拦挡的Bean的匹配的增强器(告诉办法),这里有切入点表达式匹配的逻辑
    2. 将增强器保留到proxyFactory中,
    3. 依据被拦挡的Bean是否实现了接口,spring主动决定应用JdkDynamicAopProxy还是ObjenesisCglibAopProxy
    4. 最初返回被拦挡的Bean的代理对象,注册到spring容器中
  4. 代理Bean的指标办法执行过程:CglibAopProxy.intercept();

    1. 保留所有的增强器,并解决转换为一个拦截器链
    2. 如果没有拦截器链,就间接执行指标办法
    3. 如果有拦截器链,就将指标办法,拦截器链等信息传入并创立CglibMethodInvocation对象,并调用proceed()办法获取返回值。proceed办法外部会顺次执行拦截器链。

spring 申明式事务

根本步骤

  1. 配置数据源:DataSource
  2. 配置事务管理器来管制事务:PlatformTransactionManager
  3. @EnableTransactionManagement开启基于注解的事务管理性能
  4. 给办法下面标注@Transactional标识以后办法是一个事务办法

申明式事务实现原理

  1. @EnableTransactionManagement利用TransactionManagementConfigurationSelector给spring容器中导入两个组件:AutoProxyRegistrar和ProxyTransactionManagementConfiguration
  2. AutoProxyRegistrar给spring容器中注册一个InfrastructureAdvisorAutoProxyCreator,InfrastructureAdvisorAutoProxyCreator实现了InstantiationAwareBeanPostProcessor,InstantiationAwareBeanPostProcessor是一个BeanPostProcessor。它能够拦挡spring的Bean初始化(Initialization)前后和实例化(Initialization)前后。利用后置处理器机制在被拦挡的bean创立当前包装该bean并返回一个代理对象代理对象执行办法利用拦截器链进行调用(同springAop的原理)
  3. ProxyTransactionManagementConfiguration:是一个spring的配置类,它为spring容器注册了一个BeanFactoryTransactionAttributeSourceAdvisor,是一个事务事务增强器。它有两个重要的字段:AnnotationTransactionAttributeSource和TransactionInterceptor。

    1. AnnotationTransactionAttributeSource:用于解析事务注解的相干信息
    2. TransactionInterceptor:事务拦截器,在事务办法执行时,都会调用TransactionInterceptor的invoke->invokeWithinTransaction办法,这外面通过配置的PlatformTransactionManager管制着事务的提交和回滚。

Spring 扩大(钩子)

  1. BeanFactoryPostProcessor:beanFactory后置处理器,的拦挡机会:所有Bean的定义信息曾经加载到容器,但还没有被实例化。能够对beanFactory进行一些操作。
  2. BeanPostProcessor:bean后置处理器,拦挡机会:bean创建对象初始化前后进行拦挡工作。能够对每一个Bean进行一些操作。
  3. BeanDefinitionRegistryPostProcessor:是BeanFactoryPostProcessor的子接口,拦挡机会:所有Bean的定义信息曾经加载到容器,但还没有被实例化,能够对每一个Bean的BeanDefinition进行一些操作。
  4. ApplicationListener,自定义ApplicationListener实现类并退出到容器中,能够监听spring容器中公布的事件。spring在创立容器的时候(finishRefresh()办法)会公布ContextRefreshedEvent事件,敞开的时候(doClose())会公布ContextClosedEvent事件。也能够通过spring容器的publishEvent公布本人的事件。

    1. 事件公布流程:publishEvent办法

      1. 获取事件的多播器,getApplicationEventMulticaster()。
      2. 调用multicastEvent(applicationEvent, eventType)派发事件。获取到所有的ApplicationListener,即getApplicationListeners(),而后同步或者异步的形式执行监听器的onApplicationEvent。
    2. 事件的多播器的初始化中(initApplicationEventMulticaster()),如果容器中没有配置applicationEventMulticaster,就应用SimpleApplicationEventMulticaster。而后获取所有的监听器,并把它们注册到SimpleApplicationEventMulticaster中。
  5. @EventListener(class={}):在一般的业务逻辑的办法上监听事件特定的事件。原理:EventListenerMethodProcessor是一个SmartInitializingSingleton,当所有的单例bean都初始化完当前, 容器会回调该接口的办法afterSingletonsInstantiated(),该办法里会遍历容器中所有的bean,并判断每一个bean里是否带有@EventListener注解的Method,而后创立ApplicationListenerMethodAdapter存储并包装该Method,最初将ApplicationListenerMethodAdapter增加到spring容器中。

Spring源代码剖析

spring外围逻辑AbstractApplicationContext的refresh()办法如下

public void refresh() {
    synchronized (this.startupShutdownMonitor) {
        // 刷新前的预筹备工作
        prepareRefresh();
        // 提取bean的配置信息并封装成BeanDefinition实例,而后将其增加到注册核心。注册核心是一个ConcurrentHashMap<String,BeanDefinition>类型,key为Bean的名字,value为BeanDefinition实例。
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
       //对beanFactory进行一些配置,注册一些BeanPostProcessor和一些非凡的Bean。
        prepareBeanFactory(beanFactory);
        
            //留给子类在BeanFactory筹备工作实现后处理一些工作。
            postProcessBeanFactory(beanFactory);
           //调用 BeanFactory的后置处理器。
           invokeBeanFactoryPostProcessors(beanFactory);
           //注册Bean的后置处理器。
            registerBeanPostProcessors(beanFactory);
            //国际化相干性能
            initMessageSource();
            //初始化事件派发器;
            initApplicationEventMulticaster();
            // 提供给子容器类,供子容器去实例化其余的非凡的Bean
            onRefresh();
            // 解决容器中已有的ApplicationListener
            registerListeners();
            //初始化容器中残余的单实例bean
            finishBeanFactoryInitialization(beanFactory);
            //最初一步
            finishRefresh();
        
        }
    }

prepareRefresh()

1. 记录启动工夫,设置容器的active和close状态。 
2. initPropertySources():提供给子容器类,子容器类可笼罩该办法进行一些自定义的属性设置。
3. getEnvironment().validateRequiredProperties():测验属性的合法性
4. this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>() :保留容器中的一些晚期的事件,待事件多播器创立后执行。

obtainFreshBeanFactory()

提取bean的配置信息并封装成BeanDefinition实例,而后将其增加到注册核心。注册核心是一个ConcurrentHashMap<String,BeanDefinition>类型,key为Bean的名字,value为BeanDefinition实例。

1. refreshBeanFactory:如果以后容器曾经有了BeanFactory就销毁原来的BeanFactory。而后创立一个DefaultListableBeanFactory();
    * 对BeanFactory并进行配置,次要配置是否容许BeanDefinition笼罩,是否容许Bean间的循环援用。
    * 加载BeanDefinition,解析XML文件和配置文件,将其转换为BeanDefinition,而后保留到DefaultListableBeanFactory的beanDefinitionMap字段中。
2. getBeanFactory() 简略的返回beanFactory,即DefaultListableBeanFactory。

prepareBeanFactory()

1. 设置BeanFactory的类加载器、设置反对SPEL表达式的解析器。
2. 增加ApplicationContextAwareProcessor用于解决XXXAware接口的回调。 
3. 设置疏忽一些接口。并注册一些类,这些类能够在bean里间接进行主动拆卸。
4. 增加ApplicationListenerDetector用于辨认并保留ApplicationListener的子类。

postProcessBeanFactory():

提供给子容器类,子容器类能够笼罩该办法在BeanFactory筹备工作实现后处理一些工作。

invokeBeanFactoryPostProcessors()

执行BeanFactoryPostProcessor类型的监听办法。

* BeanFactoryPostProcessor是beanFactory后置处理器,在整个BeanFactory规范初始化实现后进行拦挡调用, 
* BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,在beanFactory解析完所有的BeanDefinition后拦挡调用。
* BeanFactoryPostProcessor起源
    * 通过ApplicationContent的addBeanFactoryPostProcessor()办法手动增加本人的拦截器
    * 零碎默认了一些BeanFactoryPostProcessor。例如:ConfigurationClassPostProcessor用来解决@Configuration标注的Spring配置类。
* 调用程序 
    1. 先调用BeanDefinitionRegistryPostProcessor类型的拦截器,
    2. 而后再顺次调用实现了PriorityOrdered,Ordered接口的BeanFactoryPostProcessor
    3. 最初调用一般的BeanFactoryPostProcessor

registerBeanPostProcessors()

注册Bean的后置处理器。


1. 从beanFactory里获取所有BeanPostProcessor类型的Bean的名称。
2. 调用beanFactory的getBean办法并传入每一个BeanPostProcesso类型的Bean名称,从容器中获取该Bean的实例。
3. 
    1. 第一步向beanFactory注册实现了PriorityOrdered的BeanPostProcessor类型的Bean实例。
    2. 第二步向beanFactory注册实现了Ordered的BeanPostProcessor类型的Bean实例。
    3. 第三步向beanFactory注册一般的BeanPostProcessor类型的Bean实例。
    4. 最初一步向beanFactory从新注册实现了MergedBeanDefinitionPostProcessor的BeanPostProcessor类型的Bean实例

4. 向beanFactory注册BeanPostProcessor的过程就是简略的将实例保留到beanFactory的beanPostProcessors属性中。

initMessageSource()

国际化相干性能

1. 看容器中是否有id为messageSource的,类型是MessageSource的Bean实例。如果有赋值给messageSource,如果没有本人创立一个DelegatingMessageSource。
2. 把创立好的MessageSource注册在容器中,当前获取国际化配置文件的值的时候,能够主动注入MessageSource。

initApplicationEventMulticaster()

初始化事件派发器;

1. 看容中是否有名称为applicationEventMulticaster的,类型是ApplicationEventMulticaster的Bean实例。如果没有就创立一个SimpleApplicationEventMulticaster。
2. 把创立好的ApplicationEventMulticaster增加到BeanFactory中。

onRefresh():

提供给子容器类,供子容器去实例化其余的非凡的Bean。

registerListeners():

解决容器中已有的ApplicationListener。

1. 从容器中取得所有的ApplicationListener
2. 将每个监听器增加到事件派发器(ApplicationEventMulticaster)中;
3. 解决之前步骤产生的事件;

finishBeanFactoryInitialization():

初始化容器中残余的单实例bean:拿到残余的所有的BeanDefinition,顺次调用getBean办法(详看beanFactory.getBean的执行流程)

finishRefresh():

最初一步。

1. 初始化和生命周期无关的后置处理器;LifecycleProcessor,如果容器中没有指定解决就创立一个DefaultLifecycleProcessor退出到容器。
2. 获取容器中所有的LifecycleProcessor回调onRefresh()办法。
3. 公布容器刷新实现事件ContextRefreshedEvent。

ConfigurationClassPostProcessor解决@Configuration的过程:

  1. 先从主从核心取出所有的BeanDefinition。顺次判断,若一个BeanDefinition是被@Configuration标注的,spring将其标记为FullMode,否则若一个BeanDefinition没有被@Configuration标注,但有被@Bean标注的办法,spring将其标记为LightMode。筛选出所有候选配置BeanDefinition(FullMode和LightMode)
  2. 创立一个ConfigurationClassParser,调用parse办法解析每一个配置类。

    1. 解析@PropertySources,将解析后果设置到Environment
    2. 利用ComponentScanAnnotationParser,将@ComponentScans标签解析成BeanDefinitionHolder。再迭代解析BeanDefinitionHolder
    3. 解析@Import,@ImportResource
    4. 将@Bean解析为MethodMetadata,将后果保留到ConfigurationClass中。最终ConfigurationClass会被保留到ConfigurationClassParser的configurationClasses中。
  3. 调用ConfigurationClassParser的loadBeanDefinitions办法,加载解析后果到注册中。

    1. 从利用ComponentScanAnnotationParser的configurationClasses获取所有的ConfigurationClass,顺次调用loadBeanDefinitionsForConfigurationClass办法。
    2. loadBeanDefinitionsForConfigurationClass会将每一个BeanMethod转为ConfigurationClassBeanDefinition,最初将其增加到spring的注册核心。

beanFactory.getBean办法执行的过程

  1. 首先将办法传入的beanName进行转换:先去除FactoryBean前缀(&符)如果传递的beanName是别名,则通过别名找到bean的原始名称。
  2. 依据名称先从singletonObjects(一个Map类型的容)获取bean实例。如果能获取到就先判断该bean实例是否实现了FactoryBean,如果是FactoryBean类型的bean实例,就通过FactoryBean获取Bean。而后间接返回该bean实例。getBean办法完结。
  3. 如果从singletonObjects没有获取到bean实例就开始创立Bean的过程。

    1. 首先标记该Bean处于创立状态。
    2. 依据Bean的名称找到BeanDefinition。查看该Bean是否有前置依赖的Bean。若有则先创立该Bean前置依赖的Bean。
    3. spring调用AbstractAutowireCapableBeanFactory的createBean办法并传入BeanDefinition开始创建对象。先调用resolveBeforeInstantiation给BeanPostProcessor一个机会去返回一个代理对象去代替指标Bean的实例。
    4. 如果BeanPostProcessor没有返回Bean的代理就通过doCreateBean办法创建对象。

      1. 首先确定Bean的构造函数,如果有有参结构器,先主动拆卸有参结构器,默认应用无参数结构器。
      2. 抉择一个实例化策略去实例化bean。默认应用CglibSubclassingInstantiationStrategy。该策略模式中,首先判断bean是否有办法被笼罩,如果没有则间接通过反射的形式来创立,如果有的话则通过CGLIB来实例化bean对象. 把创立好的bean对象包裹在BeanWrapper里。
      3. 调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition
      4. 判断容器是否容许循环依赖,如果容许循环依赖,就创立一个ObjectFactory类并实现ObjectFactory接口的惟一的一个办法getObject()用于返回Bean。而后将该ObjectFactory增加到singletonFactories中。
      5. 调用populateBean为bean实例赋值。在赋值之前执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation和postProcessPropertyValues办法。
      6. 调用initializeBean初始化bean。如果Bean实现了XXXAware,就先解决对应的Aware办法。而后调用beanProcessor的postProcessBeforeInitialization办法。再以反射的形式调用指定的bean指定的init办法。最初调用beanProcessor的postProcessAfterInitialization办法。
      7. 调用registerDisposableBeanIfNecessary,将该bean保留在一个以beanName为key,以包装了bean援用的DisposableBeanAdapter,为value的map中,在spring容器敞开时,遍历这个map来获取须要调用bean来顺次调用Bean的destroyMethod指定的办法。
    5. 将新创建进去的Bean保留到singletonObjects中

spring原理补充

spring解决循环依赖

以类A,B相互依赖注入为例

  1. 依据类A的名称先从singletonObjects获取Bean实例,发现获取不到,就通过doGetBean办法开始创立Bean的流程。
  2. 依据A的名称找到对应的BeanDefinition,通过doCreateBean()办法创建对象,先确定类A的构造函数,而后抉择一个实例化策略去实例化类A。
  3. 判断容器是否容许循环依赖,如果容许循环依赖,就创立一个ObjectFactory类并实现ObjectFactory接口的惟一的一个办法getObject()用于返回类A。而后将该ObjectFactory增加到singletonFactories中。
  4. 调用populateBean()为类A进行属性赋值,发现须要依赖类B,此时类B尚未创立,启动创立类B的流程。

    1. 依据类B的名称先从singletonObjects获取Bean实例,发现获取不到,就开始通过doGetBean办法开始创立Bean的流程
    2. 找到类B对应的BeanDefinition,确认B的构造函数,而后实例化B。
    3. 判断容器是否容许循环依赖,创立一个ObjectFactory并实现getObject()办法,用于返回类B,并增加到singletonFactories中。
    4. 调用populateBean()为类B进行属性赋值,发现须要依赖类A,调用getSingleton办法获取A:A当初已存在于singletonFactories中,getSingleton将A从singletonFactories办法中移除并放入earlySingletonObjects中。
    5. 调用getSingleton()办法获取B:getSingleton将A从singletonFactories办法中移除并放入earlySingletonObjects中。
    6. 调用initializeBean初始化bean,最初将新创建进去的类B保留到singletonObjects中
  5. 调用getSingleton()办法获取A,这时A已在earlySingletonObjects中了,就间接返回A
  6. 调用initializeBean初始化bean,最初将新创建进去的类B保留到singletonObjects中。

@Autowire 实现原理

下面介绍beanFactory.getBean办法执行的过程中提到:populateBean为bean实例赋值。在赋值之前执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation和postProcessPropertyValues办法。@Autowire由AutowiredAnnotationBeanPostProcessor实现,它实现了InstantiationAwareBeanPostProcessor。
AutowiredAnnotationBeanPostProcessor执行过程:

  1. postProcessAfterInstantiation办法执行,间接return null。
  2. postProcessPropertyValues办法执行,次要逻辑在此解决。待补充。。。。。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理