一直想研究下当下流行的开源框架的代码,最近年初终于得空了看了下Spring Framework的部分源代码。Spring最核心的功能是IOC容器,其他所有功能都是在此基础上做出的内部扩展,如aop、tx等。
首先先从web工程下经常使用的ContextLoaderListener开始阅读,可以知道Spring bean的创建过程是context-> beanFactory->bean。
- 初始化context
context的作用
- 实现统一资源读取接口用于获取spring容器配置文件的内容。
- 调用相关工具类读取spring配置文件解析成BeanDefinitionHolder并缓存起来。
- 实现几个beanFactory接口使得我们获取到context后即可得到目标bean,这样简化了bean获取方法(不必再去获取beanFactory)。
- 实现了应用事件发布器接口,用于在容器内发布相应的事件。
contex相关t类结构图如下:
web工程中加载spring容器时使用的容器上下文是XmlWebApplicationContext,还有其他非web工程经常使用的context实现类如ClassPathXmlApplicationContext、FileSystemXmlApplicationContext等都是通过xml文件来定义spring容器的。现在还可以完全通过注解的方式定义spring容器,其实现类为AnnotationConfigApplicationContext,定义spring容器的类需要使用@Configurable、@Bean注解来定义bean。在正式项目中通常还是使用xml+注解的方式,一般都会将aop、定时任务等的相关配置放在xml中,普通的spring bean则用@Service等注解进行定义,这样后续维护的人可以清楚的了解系统中有哪些隐秘执行的程序,不至于出现问题时毫无头绪。
纯xml定义或者纯注解的方式都容易理解,但spring如何解析xml和注解同时存在的情况?这就是spring设计的强大之处,spring内部通过实现自己提供的扩展点来实现解析的。当在xml文件中加入了<context:annotation-config>或者<context:component-scan base-package="com.jj" />时,spring会向容器中默认加入ConfigurationClassPostProcessor、CommonAnnotationBeanPostProcessor、AutowiredAnnotationBeanPostProcessor等bean实例。在下面创建beanFactory和实例化bean的伪代码中可以找到其被调用的地方,大家可以通过查看其源码来理解spring具体的实现方法。
context解析spring xml配置文件时需要使用BeanDefinationReader,其类图如下:为了更好的理解记忆context的创建过程,整理了如下伪代码用于描述ContextLoader初始化ApplicationContext的过程:
ContextLoaderListener.contextInitialized(ServletContextEvent event) { //listener继承自ContextLoader,因此下面这句其实是执行ContextLoaderListener父类的方法 ContextLoader.initWebApplicationContext(event.getServletContext()){ this.createWebApplicationContext(ServletContext sc, ApplicationContext parent){ /* determineContextClass方法是先从servlet上下文中获取初始化参数servletContext.getInitParameter("contextClass"), 如果该方法获取不到则从ContextLoader.properties获取,所以基本上我们在web中使用的都是XmlWebApplicationContext作为Spring容器上下文的实例。 如果我们不使用web容器,那么最常使用的是ClassPathXmlApplicationContext */ Class<?> contextClass = determineContextClass(sc); ConfigurableWebApplicationContext wac =(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); //下面这句开启了beanFactory的初始化 wac.refresh(); } } }
- 创建beanFactory
beanFactory是实现IOC的核心,其作用如下:
- 创建singleton类型的bean并缓存。
- 缓存prototype类型的beanFactory对象。
- 调用factory创建时拦截器BeanFactoryPostProcessor、bean创建时拦截器BeanPostProcessor,实现spring bean最核心的扩展点。
其类图如下:
如下伪代码描述了ApplicationContext创建BeanFactory的过程:
AbstractApplicationContext.refresh(){ ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(){ //AbstractRefreshableApplicationContext继承自AbstractApplicationContext AbstractRefreshableApplicationContext.refreshBeanFactory(){ //创建DefaultListableBeanFactory实例 ---1:创建beanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); //根据资源配置加载bean定义 ---2:加载beanDefinition并缓存起来 XmlWebApplicationContext.loadBeanDefinitions(beanFactory){ BeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); //如果是web工程则会通过web.xml中initParam参数查找configLocations配置 for (String configLocation : configLocations) { //将配置文件的解析工作委托给BeanDefinitionReader reader.loadBeanDefinitions(configLocation){ //调用实际执行解析的方法 reader.registerBeanDefinitions(Document doc, Resource resource){ //创建reader上下文,之所以创建context是为了触发bean解析后的相关注册事件 ReaderContext readerContext = new XmlReaderContext(reader); //创建实际执行Document解析工作的BeanDefinitionDocumentReader BeanDefinitionDocumentReader documentReader = new DefaultBeanDefinitionDocumentReader(); //调用其解析方法并将解析后的结果存储在registry(即beanFactory中,因为beanFactory实现了BeanDefinitionRegistry接口) documentReader.registerBeanDefinitions(doc, readerContext){ Element root = doc.getDocumentElement(); //创建真正执行解析的工具类BeanDefinitionParserDelegate BeanDefinitionParserDelegate delegate = = new BeanDefinitionParserDelegate(readerContext); documentReader.parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate){ for(Element ele : root.elements()){ //判断节点类型 if (delegate.isDefaultNamespace(ele)) { documentReader.parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate){ //根据ele节点类型来判断调用以下哪个方法 importBeanDefinitionResource(Element ele); processAliasRegistration(Element ele); //以bean节点的解析为例 processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate){ //解析出bdHolder对象,该对象包括beanName和beanDefinition BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); //将beanDefinition对象注册到registry bean定义缓存中 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); //获取reader上下文执行bean解析后的监听事件 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } } } else { delegate.parseCustomElement(ele){ /* *解析各种特殊的节点如context:component-scan等 *NamespaceHandlerResolver是由XmlBeanDefinitionReader.createReaderContext进行初始化,其中包含了各种自定义命名空间的处理类。 *如context命名空间的解析类为ContextNamespaceHandler */ //此处获取handler时会调用其init方法,向handler中注册各种节点的解析器 NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)){ //查找节点对应的解析器 //如component-scan对应的解析器为ComponentScanBeanDefinitionParser,此处会调用其parse方法时会调用ClassPathBeanDefinitionScanner.doScan方法扫描base-package指定的包中含有@Component注解的类并解析成beanDefinition注册到beanFactory handler.findParserForElement(element, parserContext).parse(element, parserContext) } } } } } } } } } } } } //可用来向beanFactory中添加自定义的拦截器, 如AbstractRefreshableWebApplicationContext中添加的ServletContextAwareProcessor postProcessBeanFactory(beanFactory); //从beanFactory中找到BeanFactoryPostProcessor的实现类并执行 invokeBeanFactoryPostProcessors(beanFactory){ //获取BeanDefinitionRegistryPostProcessor,该拦截器可由向beanDefineRegistry中添加bean定义 //spring内部有扩展该接口,如ConfigurationClassPostProcessor(当spring配置中加入了context:component-scan时,该bean会被注册到容器中)用于处理添加了@Configuration @Bean注解的bean,将其解析成beanDefine并添加到beanFactory中缓存起来 Map<String, BeanDefinitionRegistryPostProcessor> beanMap = beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false); if(beanbFactory instanceOf BeanDefinitionRegistry){ BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry((BeanDefinitionRegistry) beanFactory); } else { BeanDefinitionRegistryPostProcessor.postProcessBeanFactory(beanFactory); } } //从beanFactory中找到BeanPostProcessor的实现类实体bean定义,调用getBean方法实例化并注册到beanFactory中 registerBeanPostProcessors(beanFactory){ //BeanPostProcessor的注册顺序:首先是实现了PriorityOrdered接口的,然后是实现了Ordered 然后是没用排序接口的nonOrdered 最后是MergedBeanDefinitionPostProcessor的实现类 //当配置文件中加入了context:component-scan后spring会加入MergedBeanDefinitionPostProcessor的内部实现类PersistenceAnnotationBeanPostProcessor、 registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors); } //Initialize message source for this context. initMessageSource(); //初始化上下文中的应用事件广播器 initApplicationEventMulticaster(); //与registerBeanPostProcessors类似,从beanFactory中获取ApplicationListener的实现类 registerListeners(); //bean实例化(此时处理的基本只有用户自定义的普通bean,像BeanPostProcessor等扩展bean都已经提前实例化好了,所以在实例化普通bean时可以直接调用了) finishBeanFactoryInitialization(); }
- 实例化bean
如下伪代码用于描述spring内部的调用顺序:
BeanFactory实例化Bean的过程 AbstractApplicationContext.refresh(){ //完成bean的实例化 AbstractApplicationContext.finishBeanFactoryInitialization(){ DefaultListableBeanFactory.preInstantiateSingletons(){ List<String> beanNames = new ArrayList<String>(DefaultListableBeanFactory.beanDefinitionNames); //遍历bean定义集合,预先实例化singleton类型bean for (String beanName : beanNames) { AbstractBeanFactory.getBean(beanName){ AbstractBeanFactory.doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly){ if (RootBeanDefinition.isSingleton()) { //此处可以看出spring的bean都是从ObjectFactory生产出来的,如果是singleton等非自定义的工厂对象,那么最终工厂还是会去调用beanFactory里面的方法。 ObjectFactory singletonFactory = new ObjectFactory() { public Object getObject() throws BeansException { try { return AbstractBeanFactory.createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } } } //调用bean缓存器来获取bean,如果缓存中没有则需要继续调用beanFactory的createBean方法来创建bean。 DefaultSingletonBeanRegistry.getSingleton(String beanName, singletonFactory){ Object singletonObject = singletonFactory.getObject(){ AbstractAutowireCapableBeanFactory.createBean(String beanName, RootBeanDefinition mbd, Object[] args){ AbstractAutowireCapableBeanFactory.doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { //创建Bean对象包装器,该包装器提供setProperty等方法供后续填充bean属性及解决依赖使用 BeanWrapper instanceWrapper = AbstractAutowireCapableBeanFactory.createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args){ AbstractAutowireCapableBeanFactory.instantiateBean(final String beanName, final RootBeanDefinition mbd){ //实际的bean创建方式可以是直接实例化创建也可以是用cglib等代理创建的对象,此处默认用的是CglibSubclassingInstantiationStrategy //将真实的创建方式进行了策略抽象,这样就可以用不同的代理框架 可以自定义实现 SimpleInstantiationStrategy.instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner){ //CglibSubclassingInstantiationStrategy.instantiateWithMethodInjection(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner){ //} BeanUtils.instantiateClass(constructorToUse); } } } //执行AbstractApplicationContext.ApplicationListenerDetector处理器,作为后续添加到context applicationListener的先决条件 //调用MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition方法 /* *执行beanFactory创建时调用registerBeanPostProcessors方法所加入的MergedBeanDefinitionPostProcessor内部实现类,用于完善RootBeanDefinition定义 *PersistenceAnnotationBeanPostProcessor用来完善jpa相关注解的解析 *AutowiredAnnotationBeanPostProcessor *RequiredAnnotationBeanPostProcessor *CommonAnnotationBeanPostProcessor 解析字段和方法中的Resource webservice等注解,Resource注解字段信息会加入到externallyManagedConfigMembers中 * */ applyMergedBeanDefinitionPostProcessors(); DefaultSingletonBeanRegistry.addSingletonFactory(String beanName, ObjectFactory singletonFactory); //进行属性设置 依赖bean注入 AbstractAutowireCapableBeanFactory.populateBean(beanName, mbd, instanceWrapper){ //执行beanPostProcessors中InstantiationAwareBeanPostProcessor实现类的postProcessAfterInstantiation方法 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(instanceWrapper.getWrappedInstance(), beanName); /* *调用InstantiationAwareBeanPostProcessor.postProcessPropertyValues方法 *CommonAnnotationBeanPostProcessor中会向Resource注解的字段注入相应的bean */ InstantiationAwareBeanPostProcessor.postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName); } } } } //将创建的bean对象缓存起来 DefaultSingletonBeanRegistry.addSingleton(beanName, singletonObject);; } } } } } } } }
相关推荐
### Spring的IoC容器初始化源码解析 #### 一、Spring框架的核心——IoC容器 Spring框架是一个开源的轻量级Java开发框架,其核心功能是IoC(Inversion of Control,控制反转)容器和AOP(Aspect Oriented ...
Spring IoC容器还提供了许多其他功能,如初始化和销毁回调方法、AOP(面向切面编程)、事件发布、类型转换等。这些特性帮助开发者构建更加灵活和可扩展的应用程序。 在实际开发中,`maventest05`这个文件可能是...
在传统的编程中,对象通常自行创建和管理依赖对象,而在IoC中,这些职责被转移到了一个外部容器(如Spring的IoC容器)。容器根据配置信息创建对象,管理它们的生命周期,并负责建立对象间的依赖关系。 Spring的IoC...
首先,`finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)`方法是Spring IoC容器初始化过程中的一个关键环节。这个方法的主要任务包括设置转换服务、处理LoadTimeWeaverAware类型的...
在本篇中,我们将深入探讨Spring框架的核心组件——IoC(Inversion of Control)容器,这是Spring 2.5.6版本的一部分。IoC容器是Spring框架的心脏,它负责管理对象的生命周期和依赖关系,使得开发者能够实现松耦合和...
### Spring源码分析_Spring_IOC:深入理解Spring的IOC容器机制 #### 基本概念与核心作用 在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色...
【第四课:IOC容器设计理念与源码解读 (2)1】 本课程主要涵盖了IOC(Inversion of Control,控制反转)的核心理论以及实体Bean的创建方式,深入解析了Spring框架中的IOC设计原理。以下是对这些知识点的详细阐述: ...
2. Bean的实例化:当需要使用某个Bean时,IOC容器会根据Bean的定义创建实例。可以是单例模式,也可以是多例模式。 3. 依赖注入:在实例化Bean的过程中,容器会根据定义的依赖关系,将其他Bean注入到当前Bean中,...
Spring 框架系列(7)- Spring IOC 实现原理详解之 IOC 初始化流程 本文将详细解释 Spring 框架中的 IOC...IOC 容器的初始化流程是 Spring 框架中的关键部分,用于将资源配置文件中的信息加载到 IOC 容器中。
本项目"手写一个SpringIoc容器"旨在模仿Spring的IOC(Inversion of Control,控制反转)功能,帮助开发者深入理解Spring的工作原理,提升对依赖注入(Dependency Injection)模式的认识。 在实现自定义的Spring IOC...
文档可能将深入探讨Spring IoC容器初始化、Bean生命周期管理、依赖注入等关键概念,并以2021年的开源版本为背景进行分析。 从提供的部分文档内容来看,我们可以提炼出以下几个知识点: 1. **BeanFactory与...
一、Spring IoC容器的初始化 1. **实例化容器**:容器的起点通常是`AnnotationConfigApplicationContext`,它是基于注解配置的上下文。在创建`AnnotationConfigApplicationContext`时,我们通常会传入一个或多个...
3、源码分析-IOC容器的初始化 4、源码分析-IOC容器的依赖注入 5、源码分析-IOC容器的高级特性 三阶段 Spring AOP的涉及原理及具体实践 SpringJDBC的涉及原理及二次开发 SpringMVC框架设计原理及手写实现 四阶段 ...
Spring的IOC容器在初始化时会读取配置文件,解析Bean的定义,然后根据这些定义创建Bean实例。在Bean实例化的过程中,可以通过依赖注入(Dependency Injection,DI)来解决对象间的依赖关系。DI有两种主要形式:...
6. **扩展性**:一个好的IoC容器应该易于扩展,支持多种加载Bean元数据的方式,如XML、JSON、注解等。 7. **测试**:为了确保容器正常工作,需要编写单元测试,验证Bean的创建、依赖注入和生命周期管理等功能。 ...
BeanFactory提供了对Bean的创建、初始化、销毁等操作的支持,是Spring容器的基础。当我们通过XML、Java配置或者注解定义Bean时,Spring会将这些配置解析成BeanDefinition对象,BeanDefinition包含了Bean的所有元数据...
这个压缩包文件中的"spring源码 中英文注释"为开发者提供了一个深入理解Spring框架内部工作原理的机会。通过阅读源码和注释,我们可以更清晰地了解Spring如何管理依赖注入、AOP(面向切面编程)、事务管理、上下文...
此外,通过`lazy-init`属性可以设置延迟初始化,`init-method`和`destroy-method`指定初始化和销毁方法。 5. 依赖注入(DI): DI是IoC的具体实现,Spring通过setter方法或构造器注入依赖。此外,还有基于注解的...
Spring框架是Java开发中广泛应用的一个...这个编译好的Spring 4.3.0源码工程为开发者提供了一个学习和研究的平台,通过对源码的阅读,我们可以深入了解Spring的工作机制,从而更好地利用它来构建高质量的企业级应用。