共计 13388 个字符,预计需要花费 34 分钟才能阅读完成。
- 本文是一篇 spring 源码相干的文章。家喻户晓,读源码是一件令人恐怖的事件,看源码相干的博客、书和文章亦是如此。(笔者已经狂啃 mybatis 的设计与实现这本书,后果是看着超级苦楚,看完当前没留下啥印象)。鉴于此,本文的源码解析就不依照传统的去贴代码的形式去解说 spring 源码了,本文的源码解析以流程的形式来解说 spring 在每一步都干了什么,所以谓之曰 spring 源码导读。。。。
- 在正式开始 spring 源码导读之前,读者总得晓得 spring 里的各个标签是干啥的吧,因而文中前一部分列举了 spring 常见的注解用法。并搞了点 SpringAOP 和 spring 事务源码的解析作为前面正式开始的导读的开胃菜
- 介绍完了,让咱们开始吧!!!。
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[疾速给容器中导入一个组件]
- Import(类名), 容器中就会主动注册这个组件,id 默认是组件的全名
- ImportSelector:返回须要导入的组件的全类名的数组
- 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 拆卸优先级如下:
- 应用依照类型去容器中找对应的组件
- 依照属性名称去作为组件 id 去找对应的组件
- @Qualifier: 指定默认的组件, 联合 @Autowried 应用
– 标注在结构器:spring 创建对象调用结构器创建对象
– 标注在办法上: - @Primary:spring 主动拆卸的时候, 默认首先 bean, 配合 @Bean 应用
- @Resource(JSR250):jsr 标准: 依照组件名称进行拆卸
- @Inject(JSR330):jsr 标准和 @Autowired 性能统一, 不反对 require=false;
Bean 生命周期:
初始化和销毁
- 通过 @Bean 指定 init-method 和 destroy-method
- 实现 InitializingBean 定义初始化逻辑, 实现 DisposableBean 定义销毁办法
- 实现 BeanPostProcessor 接口的后置拦截器放入容器中,能够拦挡 bean 初始化,并能够在被拦挡的 Bean 的初始化前后进行一些解决工作。
spring 底层罕用的 BeanPostProcessor:
* BeanValidationPostProcessor 用来实现数据校验
* AutowireAnnotationBeanPostProcessor,@Autowire 实现
* ApplicationContextProcessor 实现 XXXAware 的主动注入。
执行机会
doCreateBean
-populateBean():给 bean 的各种属性赋值
-initializeBean():初始化 bean
- 解决 Aware 办法
-applyBeanPostProcessorsBeforeInitialization:后置处理器的实例化前拦挡
-invokeInitMethods: 执行 @Bean 指定的 initMethod
-applyBeanPostProcessorsAfterInitialization:后置处理器的实例化后拦挡
SpringAOP 实现原理
应用步骤
- @EnableAspectJAutoProxy 开启基于注解的 aop 模式
- @Aspect:定义切面类,切面类里定义告诉
- @PointCut 切入点,能够写切入点表达式,指定在哪个办法切入
-
告诉办法
- @Before(前置告诉)
- @After(后置告诉)
- @AfterReturning(返回告诉)
- @AfterTrowing(异样告诉)@Around(盘绕告诉)
- JoinPoint:连接点, 是一个类,配合告诉应用,用于获取切入的点的信息
SpringAop 原理
-
@EnableAspectJAutoProxy
- @EnableAspectJAutoProxy 通过 @Import(AspectJAutoProxyRegistrar.class)给 spring 容器中导入了一个 AnnotationAwareAspectJAutoProxyCreator。
- AnnotationAwareAspectJAutoProxyCreator 实现了 InstantiationAwareBeanPostProcessor,InstantiationAwareBeanPostProcessor 是一个 BeanPostProcessor。它能够拦挡 spring 的 Bean 初始化 (Initialization) 前后和实例化 (Initialization) 前后。
- AnnotationAwareAspectJAutoProxyCreator 的 postProcessBeforeInstantiation(bean 实例化前):会通过调用 isInfrastructureClass(beanClass)来判断 被拦挡的类是否是根底类型的 Advice、PointCut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect),若是则放入 adviseBean 汇合。这里次要是用来解决咱们的切面类。
-
AnnotationAwareAspectJAutoProxyCreator 的 BeanPostProcessorsAfterInitialization(bean 初始化后):
- 首先找到被拦挡的 Bean 的匹配的增强器(告诉办法),这里有切入点表达式匹配的逻辑
- 将增强器保留到 proxyFactory 中,
- 依据被拦挡的 Bean 是否实现了接口,spring 主动决定应用 JdkDynamicAopProxy 还是 ObjenesisCglibAopProxy
- 最初返回被拦挡的 Bean 的代理对象,注册到 spring 容器中
-
代理 Bean 的指标办法执行过程:CglibAopProxy.intercept();
- 保留所有的增强器,并解决转换为一个拦截器链
- 如果没有拦截器链,就间接执行指标办法
- 如果有拦截器链,就将指标办法,拦截器链等信息传入并创立 CglibMethodInvocation 对象,并调用 proceed()办法获取返回值。proceed 办法外部会顺次执行拦截器链。
spring 申明式事务
根本步骤
- 配置数据源:DataSource
- 配置事务管理器来管制事务:PlatformTransactionManager
- @EnableTransactionManagement 开启基于注解的事务管理性能
- 给办法下面标注 @Transactional 标识以后办法是一个事务办法
申明式事务实现原理
- @EnableTransactionManagement 利用 TransactionManagementConfigurationSelector 给 spring 容器中导入两个组件:AutoProxyRegistrar 和 ProxyTransactionManagementConfiguration
- AutoProxyRegistrar 给 spring 容器中注册一个 InfrastructureAdvisorAutoProxyCreator,InfrastructureAdvisorAutoProxyCreator 实现了 InstantiationAwareBeanPostProcessor,InstantiationAwareBeanPostProcessor 是一个 BeanPostProcessor。它能够拦挡 spring 的 Bean 初始化 (Initialization) 前后和实例化 (Initialization) 前后。利用后置处理器机制在被拦挡的 bean 创立当前包装该 bean 并返回一个代理对象代理对象执行办法利用拦截器链进行调用(同 springAop 的原理)
-
ProxyTransactionManagementConfiguration:是一个 spring 的配置类, 它为 spring 容器注册了一个 BeanFactoryTransactionAttributeSourceAdvisor, 是一个事务事务增强器。它有两个重要的字段:AnnotationTransactionAttributeSource 和 TransactionInterceptor。
- AnnotationTransactionAttributeSource:用于解析事务注解的相干信息
- TransactionInterceptor:事务拦截器,在事务办法执行时,都会调用 TransactionInterceptor 的 invoke->invokeWithinTransaction 办法,这外面通过配置的 PlatformTransactionManager 管制着事务的提交和回滚。
Spring 扩大(钩子)
- BeanFactoryPostProcessor:beanFactory 后置处理器,的拦挡机会:所有 Bean 的定义信息曾经加载到容器,但还没有被实例化。能够对 beanFactory 进行一些操作。
- BeanPostProcessor:bean 后置处理器,拦挡机会:bean 创建对象初始化前后进行拦挡工作。能够对每一个 Bean 进行一些操作。
- BeanDefinitionRegistryPostProcessor:是 BeanFactoryPostProcessor 的子接口,拦挡机会:所有 Bean 的定义信息曾经加载到容器,但还没有被实例化,能够对每一个 Bean 的 BeanDefinition 进行一些操作。
-
ApplicationListener, 自定义 ApplicationListener 实现类并退出到容器中, 能够监听 spring 容器中公布的事件。spring 在创立容器的时候(finishRefresh()办法)会公布 ContextRefreshedEvent 事件,敞开的时候(doClose())会公布 ContextClosedEvent 事件。也能够通过 spring 容器的 publishEvent 公布本人的事件。
-
事件公布流程:publishEvent 办法
- 获取事件的多播器,getApplicationEventMulticaster()。
- 调用 multicastEvent(applicationEvent, eventType)派发事件。获取到所有的 ApplicationListener, 即 getApplicationListeners(),而后同步或者异步的形式执行监听器的 onApplicationEvent。
- 事件的多播器的初始化中(initApplicationEventMulticaster()),如果容器中没有配置 applicationEventMulticaster,就应用 SimpleApplicationEventMulticaster。而后获取所有的监听器,并把它们注册到 SimpleApplicationEventMulticaster 中。
-
- @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 的过程:
- 先从主从核心取出所有的 BeanDefinition。顺次判断,若一个 BeanDefinition 是被 @Configuration 标注的,spring 将其标记为 FullMode,否则若一个 BeanDefinition 没有被 @Configuration 标注,但有被 @Bean 标注的办法,spring 将其标记为 LightMode。筛选出所有候选配置 BeanDefinition(FullMode 和 LightMode)
-
创立一个 ConfigurationClassParser,调用 parse 办法解析每一个配置类。
- 解析 @PropertySources, 将解析后果设置到 Environment
- 利用 ComponentScanAnnotationParser,将 @ComponentScans 标签解析成 BeanDefinitionHolder。再迭代解析 BeanDefinitionHolder
- 解析 @Import,@ImportResource
- 将 @Bean 解析为 MethodMetadata,将后果保留到 ConfigurationClass 中。最终 ConfigurationClass 会被保留到 ConfigurationClassParser 的 configurationClasses 中。
-
调用 ConfigurationClassParser 的 loadBeanDefinitions 办法,加载解析后果到注册中。
- 从利用 ComponentScanAnnotationParser 的 configurationClasses 获取所有的 ConfigurationClass,顺次调用 loadBeanDefinitionsForConfigurationClass 办法。
- loadBeanDefinitionsForConfigurationClass 会将每一个 BeanMethod 转为 ConfigurationClassBeanDefinition,最初将其增加到 spring 的注册核心。
beanFactory.getBean 办法执行的过程
- 首先将办法传入的 beanName 进行转换:先去除 FactoryBean 前缀(& 符)如果传递的 beanName 是别名,则通过别名找到 bean 的原始名称。
- 依据名称先从 singletonObjects(一个 Map 类型的容)获取 bean 实例。如果能获取到就先判断该 bean 实例是否实现了 FactoryBean,如果是 FactoryBean 类型的 bean 实例,就通过 FactoryBean 获取 Bean。而后间接返回该 bean 实例。getBean 办法完结。
-
如果从 singletonObjects 没有获取到 bean 实例就开始创立 Bean 的过程。
- 首先标记该 Bean 处于创立状态。
- 依据 Bean 的名称找到 BeanDefinition。查看该 Bean 是否有前置依赖的 Bean。若有则先创立该 Bean 前置依赖的 Bean。
- spring 调用 AbstractAutowireCapableBeanFactory 的 createBean 办法并传入 BeanDefinition 开始创建对象。先调用 resolveBeforeInstantiation 给 BeanPostProcessor 一个机会去返回一个代理对象去代替指标 Bean 的实例。
-
如果 BeanPostProcessor 没有返回 Bean 的代理就通过 doCreateBean 办法创建对象。
- 首先确定 Bean 的构造函数,如果有有参结构器,先主动拆卸有参结构器,默认应用无参数结构器。
- 抉择一个实例化策略去实例化 bean。默认应用 CglibSubclassingInstantiationStrategy。该策略模式中, 首先判断 bean 是否有办法被笼罩, 如果没有则间接通过反射的形式来创立, 如果有的话则通过 CGLIB 来实例化 bean 对象. 把创立好的 bean 对象包裹在 BeanWrapper 里。
- 调用 MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition
- 判断容器是否容许循环依赖,如果容许循环依赖,就创立一个 ObjectFactory 类并实现 ObjectFactory 接口的惟一的一个办法 getObject()用于返回 Bean。而后将该 ObjectFactory 增加到 singletonFactories 中。
- 调用 populateBean 为 bean 实例赋值。在赋值之前执行 InstantiationAwareBeanPostProcessor 的 postProcessAfterInstantiation 和 postProcessPropertyValues 办法。
- 调用 initializeBean 初始化 bean。如果 Bean 实现了 XXXAware,就先解决对应的 Aware 办法。而后调用 beanProcessor 的 postProcessBeforeInitialization 办法。再以反射的形式调用指定的 bean 指定的 init 办法。最初调用 beanProcessor 的 postProcessAfterInitialization 办法。
- 调用 registerDisposableBeanIfNecessary,将该 bean 保留在一个以 beanName 为 key,以包装了 bean 援用的 DisposableBeanAdapter,为 value 的 map 中,在 spring 容器敞开时,遍历这个 map 来获取须要调用 bean 来顺次调用 Bean 的 destroyMethod 指定的办法。
- 将新创建进去的 Bean 保留到 singletonObjects 中
spring 原理补充
spring 解决循环依赖
以类 A,B 相互依赖注入为例
- 依据类 A 的名称先从 singletonObjects 获取 Bean 实例,发现获取不到,就通过 doGetBean 办法开始创立 Bean 的流程。
- 依据 A 的名称找到对应的 BeanDefinition,通过 doCreateBean()办法创建对象,先确定类 A 的构造函数,而后抉择一个实例化策略去实例化类 A。
- 判断容器是否容许循环依赖,如果容许循环依赖,就创立一个 ObjectFactory 类并实现 ObjectFactory 接口的惟一的一个办法 getObject()用于返回类 A。而后将该 ObjectFactory 增加到 singletonFactories 中。
-
调用 populateBean()为类 A 进行属性赋值,发现须要依赖类 B,此时类 B 尚未创立,启动创立类 B 的流程。
- 依据类 B 的名称先从 singletonObjects 获取 Bean 实例,发现获取不到,就开始通过 doGetBean 办法开始创立 Bean 的流程
- 找到类 B 对应的 BeanDefinition,确认 B 的构造函数,而后实例化 B。
- 判断容器是否容许循环依赖,创立一个 ObjectFactory 并实现 getObject()办法,用于返回类 B,并增加到 singletonFactories 中。
- 调用 populateBean()为类 B 进行属性赋值,发现须要依赖类 A,调用 getSingleton 办法获取 A:A 当初已存在于 singletonFactories 中,getSingleton 将 A 从 singletonFactories 办法中移除并放入 earlySingletonObjects 中。
- 调用 getSingleton()办法获取 B:getSingleton 将 A 从 singletonFactories 办法中移除并放入 earlySingletonObjects 中。
- 调用 initializeBean 初始化 bean,最初将新创建进去的类 B 保留到 singletonObjects 中
- 调用 getSingleton()办法获取 A,这时 A 已在 earlySingletonObjects 中了,就间接返回 A
- 调用 initializeBean 初始化 bean,最初将新创建进去的类 B 保留到 singletonObjects 中。
@Autowire 实现原理
下面介绍 beanFactory.getBean 办法执行的过程 中提到:populateBean 为 bean 实例赋值。在赋值之前执行 InstantiationAwareBeanPostProcessor 的 postProcessAfterInstantiation 和 postProcessPropertyValues 办法。@Autowire 由 AutowiredAnnotationBeanPostProcessor 实现,它实现了 InstantiationAwareBeanPostProcessor。
AutowiredAnnotationBeanPostProcessor 执行过程:
- postProcessAfterInstantiation 办法执行,间接 return null。
- postProcessPropertyValues 办法执行,次要逻辑在此解决。待补充。。。。。