Spring源码解析
2019-12-24 12:25:03 164 举报
AI智能生成
Spring
作者其他创作
大纲/内容
1、Spring设计理念与整体架构
2、Spring核心:IOC容器实现
主要容器相关Class
BeanFactory
容器的顶级接口,定义了getBean方法
基本容器功能,提供存放\获取Object功能
ApplicationContext
应用上下文,除了容器的基本功能,还会对Object的生命周期进行管理
资源加载
依赖解析
动态代理
BeanDefinition
用于记录配置文件(注解)中对象的定义信息,包括依赖关系、需要进行哪些增强等,对象需要根据这些定义进行初始化、增强、依赖注入
Srping容器继承体系
BeanFactory
定义了getBean基本方法
HierarchicalBeanFactory
定义了getParentBean方法,可以获取双亲IOC容器
ConfigurableBeanFactory
增加了addBeanPostProcessor配置Bean后置处理器
定义了setParentBean方法,可以设置双亲IOC容器
DefaultListableBeanFactory
AbstractApplicationContext
完整容器功能基类
其他类别。。。
主要使用方法API
Spring容器Bean管理流程
Spring容器主要功能划分
1、Resource
用于定义不同Bean定义配置信息来源
XML配置文件
注解
2、BeanDefinitionReader
读取不同配置Resource,解析出BeanDefinition
XML配置文件
XmlBeanDefinitionReader
注解
...
解析方法
reader.loadBeanDefinitions
3、BeanDefinition
把用户定义好的Bean封装成IOC容器内部的数据结构,是对IOC容器中对象的描述,用于容器管理POJO对象
数据结构
主要阶段
Resource定位
BeanDefinition资源定位,使用统一的Resource接口对应不同类型的BeanDefinition
文件系统:FileSystemResource
类路径:ClassPathResource
Resource加载
通过ResourceLoader加载Resource,解析出BeanDefinition
AbstractBeanDefinitionReader.loadBeanDefinitions
DefaultResourceLoader.getResourceByPath
Resource解析注册Beandefinition
通过BeanDefinitionRegistry接口将解析出的BeanDefinition注入到IOC容器中的HashMap中进行管理
注意:这时候只是解析出Bean的定义信息,并没有将Bean实例化,只有调用getBean方法才会进行实例化
依赖注入(实例化)
在第一次调用getBean方法是将Bean实例化
(可以通过配置lazyinit属性控制容器初始化时预先完成)
容器初始化启动方法
AbstractApplicationContext.refresh()
1、获取环境参数,加载配置文件
AbstractApplicationContext.prepareRefresh
参数来源
1、"systemProperties":System.getProperties()
2、"systemEnvironment":System.getenv()
2、获取新BeanFactory
AbstractApplicationContext.obtainFreshBeanFactory
1、更新BeanFactory
AbstractRefreshableApplicationContext.refreshBeanFactory
1、销毁原BeanFactory及Bean
2、创建新BeanFactory
3、设置新BeanFactory参数
类加载校验器???
4、加载BeanDefinition
AbstractXmlApplicationContext.loadBeanDefinitions
1、将BeanDefinition按照Bean语义转换成IOC容器内部数据结构
先将xml配置文件解析成DOM对象,再按照SpringBean规则解析DOM,处理结果交由BeanDefinitionHolder持有
1、XmlBeanDefinitionReader.registerBeanDefinitions
2、BeanDefinitionDocumentReader.registerBeanDefinitions
3、解析出BeanDefinition,并注册到容器里面
DefaultBeanDefinitionDocumentReader.processBeanDefinition
1、生成BeanDefinition
BeanDefinitionParserDelegate.parseBeanDefinitionElement
1、获取id、name、aliaes属性,校验name属性是否重复
2、解析BeanDefinition
BeanDefinitionParserDelegate.parseBeanDefinitionElement
1、设置当前Bean处理状态正在解析
2、获取Class名称
3、初步生成BeanDefinition对象
GenericBeanDefinition
只含有ClassName和Class
4、解析当前Bean配置属性信息,设置描述信息
Scope
Singleton
Lazy_init
dependon
initMethod
destoryMethod
5、解析Bean的Meta属性信息
BeanDefinitionParserDelegate.parseMetaElements
6、动态改变方法返回的对象
look-method : parseLookupOverrideSubElements
replaced-method : parseReplacedMethodSubElements
7、解析构造参数设置
constructor-arg : parseConstructorArgElement
8、解析Bean的Property参数,遇到ref参数则嵌套处理其他BeanDefintion
property : parsePropertyElements
这里会对各种参数类型进行判断
ref
value
ref-value
9、常见异常处理
3、如果有包装BeanDefinition则作其他处理
2、装饰BeanDefinitionHolder
3、将BeanDefinitionHolder注册到容器中
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
2、返回新的BeanFactory
3、设置BeanFactory实例化Bean处理方式
AbstractApplicationContext.prepareBeanFactory
1、配置类加载解析方式
ClassLoader类加载器
ExpressionResolver表达式解析器
PropertyEditorRegistrar参数编辑注册器
AbstractBeanFactory#addPropertyEditorRegistrar
2、配置Bean初始化回调处理
添加Bean后置处理器:BeanPostProcessor
AbstractBeanFactory#addBeanPostProcessor
设置忽略依赖列表
依赖列表是什么???
4、设置BeanFactory的后置处理器
AbstractRefreshableApplicationContext.postProcessBeanFactory
1、设置Bean后置处理器
ServletContextAwareProcessor
2、设置忽略历来列表
3、设置当前BeanFactory为不同域环境(Request、Session等)IOC容器
5、对BeanFactory进行后置处理
AbstractRefreshableApplicationContext.invokeBeanFactoryPostProcessors
6、注册Bean的后置处理器(在Bean的创建过程调用)
AbstractApplicationContext.registerBeanPostProcessors
7、对上下文中的消息源进行初始化
AbstractApplicationContext.initMessageSource
8、初始化上下文中的事件机制
AbstractApplicationContext.initApplicationEventMulticaster
9、初始化其他的特殊Bean
AbstractRefreshableApplicationContext.onRefresh
10、检查监听Bean并且将这些监听Bean向容器注册
AbstractApplicationContext.registerListeners
11、实例化所有的(non-lazy-init)单件
AbstractApplicationContext.finishBeanFactoryInitialization
12、发布容器事件,结束refresh过程
AbstractApplicationContext.finishRefresh
13、异常处理
IOC容器依赖注入(第一次获取Bean实例)
getBean --> AbstractBeanFactory.doGetBean()
1、对name做标准化处理,别名替换成标准名
2、从缓存中获取已创建好的实例(单例模式)
1、判断BeanName是否是单例(BeanName是否在单例Map中)
2、如果没有创建过,判断是否有对应的FactroyBean进行创建,返回的可能是instance,也可能是Factroybean,如果是后者则获取创建家而过
AbstractBeanFactory#getObjectForBeanInstance ---> getObjectFromFactoryBean
3、创建实例
设置实例创建标志
1、判断当前BeanFactory是否有BeanDefinition,如果没有则到双亲BeanFactory中逐级向上查找
2、根据BeanName获取BeanDefinition
合并父类BeanDefinition
3、根据BeanDefinition获取依赖列表
嵌套调用getBean方法
注册依赖关系
bean --> depends
depends --> bean
4、根据BeanDefinition创建实例(单例 | 多例)
AbstractBeanFactory#getObjectForBeanInstance
1、创建前校验
2、创建实例(未做AOP代理,返回的可能是FactoryBean)
AbstractAutowireCapableBeanFactory.createBean()
1、判断BeanDefinition是否可以被实例化,这个类是否可以被类加载器加载
2、校验是否有Override方法
3、如果Bean配置了PostProcessor,则返回代理类
4、创建Bean实例
AbstractAutowireCapableBeanFactory.doCreateBean()
1、初步实例化Bean
1、判断是否指定FactoryBean,有则使用工厂方法获取实例
ConstructorResolver.instantiateUsingFactoryMethod
2、判断是否使用BeanPostProcessor处理过的构造函数进行实例化
3、使用默认构造函数进行实例化
AbstractAutowireCapableBeanFactory.instantiateBean()
1、使用默认的实例化策略对Bean进行实例化
1、获取实例化策略
AbstractAutowireCapableBeanFactory.getInstantiationStrategy()
CglibSubclassingInstantiationStrategy
对OverrideMethod、ReplaceMethod进行代理
2、进行实例化
SimpleInstantiationStrategy.instantiate()
1、判断是否有需要覆盖的方法,若没有则直接根据构造方法或者工厂方法进行数理化
beanDefinition.getMethodOverrides().isEmpty()
添加需要覆盖的方法(AOP代理,EL表达式匹配的方法等)MethodOverrides.addOverride()
2、使用Cglib进行实例化(硬编码)
什么地方可以设置其他实例化策略
2、对实例进行包装,注册PropertyEditor
AbstractBeanFactory.registerCustomEditors()
2、其他处理
3、对Bean进行依赖注入
AbstractAutowireCapableBeanFactory.populateBean()
1、获取BeanDefinition中定义的property列表
2、参数其他处理
3、开始进行依赖注入
1、处理autowire注入
1、嵌套获取bean
2、注册依赖关系
2、依赖校验
AbstractAutowireCapableBeanFactory#checkDependencies
3、对属性进行注入
AbstractAutowireCapableBeanFactory.applyPropertyValues()
1、使用BeanDefinitionValueResolver对Property的类型进行解析,解析出PropertyDefinition
BeanDefinitionValueResolver.resolveValueIfNecessary()
A、RuntimeBeanReference
嵌套调用getBean
B、Map
C、List
D、Set
E、String
F、Properties
(Book-P81 解析)
2、为解析值创建副本
3、判断属性是否需要编辑
根据不同property类型进行编辑
4、将解析的值(PropertyDefinition)注入到Bean中
AbstractPropertyAccessor.setPropertyValues()
4、完成对Bean的依赖注入后对Bean进行初始化(调用Bean的initMethods、回调后置处理器)
AbstractAutowireCapableBeanFactory#initializeBean()
1、调用BeanPostProcessor对Bean进行前置处理
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
如果Bean实现了Aware相关结构,则注入对应的IOC容器
ApplicationContextAwareProcessor
2、调用Bean的initMethod方法
AbstractAutowireCapableBeanFactory#invokeInitMethods
3、调用BeanPostProcessor对Bean进行后置处理
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
3、对获取的Bean进行APO代理
判断是不是FacotryBean,对需要代理的Bean进行AOP代理
AbstractBeanFactory#getObjectForBeanInstance ---> getObjectFromFactoryBean ---> doGetObjectFromFactoryBean
4、创建后类型校验
5、判断实例结果是instance还是factroyBean
4、对bean(已包含依赖)的类型进行校验
IOC容器关闭
AbstractApplicationContext#doClose ---> destroyBeans ---> DefaultSingletonBeanRegistry#destroySingletons(遍历需要销毁的Bean) ---> destroySingleton ---> destroyBean(递归销毁依赖Bean) ---> DisposableBeanAdapter#destroy
发出容器关闭信号,然后逐个关闭(销毁)Bean,最后关闭容器自身
IOC容器中的Bean的生命周期
1、Bean实例创建
2、为Bean实例设置属性
3、调用Bean的初始化方法
AbstractAutowireCapableBeanFactory#initializeBean() ---> invokeInitMethods
4、应用通过IOC容器使用Bean
5、当容器关闭时,调用Bean的销毁方法
DisposableBeanAdapter#destroy ---> invokeCustomDestroyMethod
3、Spring AOP代理实现
AOP联盟
AOP技术
AspectJ
AspectWerkz
JBoss-AOP
BCEL
javassist
AOP体系结构
Advice通知
BeforeAdvice
AfterAdvice
AroundAdvice
ThrowsAdvice
AfterReturningAdvice
Pointcut切点
Pointcut
JdkRegexpMethodPointcut
返回MethodMatcher作为切点匹配器
MethodMatcher
StaticMethodMatcher#matches
NameMethodMatcher#matches
完成方法的匹配判断
Advisor通知器
将Advice和Pointcut结合
DefaultPointcutAdvisor
Pointcut.TRUE ---> TruePointcut --- > MethodMatcher.TRUE --> TrueMethodMatcher
Spring AOP
JVM动态代理特性
InvocationHandler
代理生成类ProxyFactoryBean
编程式使用
ProxyFactory
(一个实例对应一个ProxyFactory)
声明式配置
配置Advisor
配置ProxyFactoryBean
配置target属性(TargetBean)
配置interceptorNames(Advisor)
获取代理对象
ProxyFactoryBean#getObject ---> AopProxyFactory(DefalutAopProxyFactory)#getProxy
1、初始化AdvisorChain(通知链)
1、根据标志位(advisorChainInitialized)判断初始化是否完成
2、遍历所有通知器名称(interceptorNames)
3、通过通知器名称获取通知器实例(容器调用getBean)
4、将获取到的通知器添加到通知链中
ProxyFactoryBean#addAdvisorOnChainCreation
2、根据单例、多例分别进行代理
1、获取ProxyFactory
ProxyCreatorSupport#getAopProxyFactory ---> DefaultAopProxyFactory#createAopProxy
根据target是否有接口判断代理方式
Cglib2AopProxy
JdkDynamicAopProxy
2、设置被代理对象相关接口
如果是多例,需要复制ProxyFacotry
3、使用ProxyFactory获取代理对象
ProxyFactoryBean#getProxy
CglibAopProxy
1、获取代理增强Advice\Advisor
CglibAopProxy#getCallbacks
增加逻辑
增强部件
aopInterceptor
targetInterceptor
targetDispatcher
CglibAopProxy.DynamicAdvisedInterceptor#intercept
1、获取拦截链,并执行拦截链代码
JdkDynamicAopProxy
增强处理
JdkDynamicAopProxy#invoke
1、不相关方法特殊处理
equals
hashCode
isAssignableFrom
2、获取拦截链,并执行拦截链代码
Spring Aop拦截器设计原理
不同代理方式拦截方法位置
CglibAopProxy.DynamicAdvisedInterceptor#intercept
JdkDynamicAopProxy#invoke
拦截链执行流程
2、根据Advisor获取拦截链
AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice --> DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
对应Xml配置ProxyFactoryBean的interceptNames属性配置
通过AdvisorAdapterRegistry对配置的拦截器进行适配
1、判断是否有符合要求的Advisor
1、遍历Advisors
2、判断是否支持目标Class
IntroductionAdvisor#getClassFilter
1、获取PointCutAdvisor中的pointcut,在获取对应的MethodMatcher
2、对拦截的对象进行匹配
3、判断是否有拦截链,若有则执行拦截链
ReflectiveMethodInvocation#proceed
1、从索引为-1的拦截器开始调用,判断是否迭代完毕,是则调用目标对象方法
2、判断是Advice还是Interceptor
1、是Advice
判断目标方法是否匹配Pointcut,匹配则交由对应的Advice执行,否则交由下一个拦截器
2、是Interceptor
直接执行拦截器的对应方法
4、返回值校验处理
(finally代码块中做资源释放处理)
Advice通知的实现
(Book P143)
DefaultAdvisorAdapterRegistry
各种类型Advice实现
BeforeAdvice
AfterAdvice
AroundAdvice
ThrowsAdvice
AfterReturningAdvice
4、Spring事务的实现
数据库操作组件实现
5、SpringMVC处理流程
6、安全框架ACEGI的设计与实现
7、Spring远程调用实现
8、SpringDM模块的设计与实现
9、Spring Flex的设计与实现
0 条评论
下一页