Spring源码启动流程源码全解
2021-09-24 17:55:25 0 举报
详解分享 有异议评论?
作者其他创作
大纲/内容
直接调用上层方法:
单例情况
BeanDefinitionRegistryPostProcessor:传入BeanDefinitionRegistry对象BeanFactoryPostProcessor:传入BeanFactory对象(对BeanDefinition进行操作)完成对这两个接口的调用实例化@Component修饰对象
3)反之,遍历所有的构造器集合candidates,获取参数类型、名称、值
AbstractApplicationContext
initializeBean();
6、返回NamespaceHandler对象;
DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId());
排除processedBeans集合内的进行处理
创建DefaultListableBeanFactory
PriorityOrdered 继承了 Ordered,并且 PriorityOrdered 的优先级要高于 Ordered
reader.loadBeanDefinitions(configLocations);
惰性地加载指定的NamespaceHandler映射。
否
sharedInstance != null && args == null
extends
把实现了BeanPostProcessor接口的类实例化,并且注册到BeanFactory中
initApplicationEventMulticaster();
getHandlerMappings()
作用:收集bean的属性和方法上是否有@Autowore,@Value注解,并封装到BeanDefinition中
2、获取需要依赖注入的属性值,这里必定会触发beanFactory.getBean(beanName)操作
2)拿到factory-bean属性,并判断进行factoryBean实例化
AutowiredAnnotationBeanPostProcessor
(2)传入beanFactroy、beanFactory后置处理器,进行bean实例化
1、如果BeanFactory不为空,则清除BeanFactory和里面的实例
6、afterSingletonCreation(beanName);
2
1)判断是否需要DI(依赖注入),不需要直接return
检查required类型是否与实际bean实例的类型匹配。最终,返回bean实例
倘若为beans标签,重新循环处理
init-method属性,和InitializingBean接口方法afterPropertiesSet调用。@PostConstruct注解方法调用。代理对象的生成入口
parseBeanDefinitions()
2、注册过程中DisposableBeanAdapter类中获取DestructionAwareBeanPostProcessor类型的接口,这个BeanPostProcessor接口专门用销毁对象的
return singletonObject
3、返回handlerMappings;
3、继续从缓存中取,为空则继续
parser()
实例化当前指定beanName,使用:factory-menthod、构造方法注入、简单实例化
1、先判断BeanDefinition是否已经注册BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
4、如果ctors不为空,就说明构造函数上有@Autowired注解,则寻找构造器入参实例,开始创建类实例
执行完则add进processedBeans集合
loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
(4)首先clear currentRegistryProcessors(ArrayList),继续循环剩余的集合, a)实例化BeanDefinitionRegistryPostProcessor,并且add到currentRegistryProcessors(ArrayList)集合中; b)发起postProcessor调用:invokeBeanDefinitionRegistryPostProcessors
1、调用xxxAware接口中的方法
parseBeanDefinitionElement()
如果是scope 是Prototype的,校验是否有出现循环依赖,如果有则直接报错
2、 0)创建BeanFactory; 1)设置是否可以循环依赖(allowCircularReferences) 2)是否允许使用相同名称重新注册不同的bean实现(allowBeanDefinitionOverriding)
2)具体实例化过程 preInstantiateSingletons()
1、注册过程中DisposableBeanAdapter类中获取BeanDefinition对象中的destroy-method属性
object != null
1)若实现PriorityOrdered,则实例化并且add进集合priorityOrderedPostProcessors中,同时,判断类型是否是MergedBeanDefinitionPostProcessor,span style=\"font-size: inherit;\
singletonFactory.getObject(); = doCreateBean()
1、postProcessMergedBeanDefinition根据该方法收集到的metaData数据,这个数据对象里面就封装了有@Autowired注解的方法或者属性,有这个注解就代表这个方法或者属性需要依赖注入
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
实例化A:需要B,则将A放入三级缓存中;B实例化:需要A,在第三级缓存找到了,然后缓存升级,将A放到二级缓存中,B放到一级缓存中,创建完成;回到A实例化过程,已经可以从一级缓存获取B,完成创建,然后将自己放到一级缓存,循环依赖操作完成。
invokeBeanFactoryPostProcessors()
设置类型转换器
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry);
object = getCachedObjectForFactoryBean(beanName);
doScan(String... basePackages)
bean标签解析
return object;
3、接下来就只剩下反射调用了,把值设置到属性或者方法中
1、创建xml的解析器;XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
如果缓存中有,则直接返回,没有则继续执行
判断是否实现了FactoryBean接口
否:自定义标签解析
4)拿出所有已经注册的postProcessor,倘若instance of InstantitationAwareBeanPostProcessor,则调用进行反射注入
findAutowiringMetadata()
4、调用当前beanFactory中所有postProcessor的postProcessorsAfterInitialization,并返回处理后的bean(实例化后的PostProcessor操作)
注册事件管理类
getSingleton()
初始化事件管理类
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);构造函数中初始化:this.autowiredAnnotationTypes.add(Autowired.class);this.autowiredAnnotationTypes.add(Value.class);
createBean()
populateBean()
createBeanInstance()
存在,则继续调用return parentBeanFactory.getBean进行实例化
最终通过cglib动态代理实例化BeanUtils.instantiateClass(constructorToUse);
return beanWrapper
如果我们不定义 id 和 name,那么:1. beanName 为:com.xxxx.xxx#0 2. beanClassName 为:com.xxx.xxxx同时将beanClassName增加到别名集合中
registerListeners();
3、如果都没有设置 id 和 name,那么此时的 beanName 就会为 null
2、如果beanDefinition有FactoryMethodName属性,可以不读(factory-method属性解析)
prepareBeanFactory(beanFactory);
1、循环basePackages数组,扫描jar包或者当前项目中的路径下.class文件,并将当前class的元数据封装到BeanDefinition中,最终返回一个BeanDefinition集合;
父子BeanDefinition合并
2、所有\"META-INF/spring.handlers\"文件里面的内容建立映射关系,并且缓存到xxxNamespaceHandlerResolver.handlerMappings中
是
把beanName添加到singletonsCurrentlyInCreation Set容器中,在这个集合里面的bean都是正在实例化的bean
1、获取ResourceLoaderResourceLoader resourceLoader = getResourceLoader();
7、倘若当前FactoryBeanRegistrySupport中的singletonObjects集合(Map)包含beanName,则把实例缓存到factoryBeanObjectCache map中,这个是单独缓存FactoryBean类型实例的map
1、获取Resource对象中的xml文件流对象InputStream inputStream = encodedResource.getResource().getInputStream();
false(如果singletonObjects缓存里面没有)
4
从缓存中获取实例 Object sharedInstance = getSingleton(beanName)
loadBeanDefinitions(location)
3
AbstractXmlApplicationContext
2、将实例注入到属性或者方法中(利用动态代理)
BeanWrapperImpl bw = new BeanWrapperImpl(); this.beanFactory.initBeanWrapper(bw);
Yes
else if
构造函数 => xxxAware接口 => @postConstruct => afterPropertiesSet => initMethod
registerBeanPostProcessors
registerBeanDefinition()=doRegisterBeanDefinitions(doc.getDocumentElement());
2)如果定义了无参构造函数,则直接实例化并return
为空,则构建自动注入Metadata对象
5
processAliasRegistration(ele);
2、对类中某些特殊方法的调用,比如@PostConstruct,Aware接口(调用实例化前的PostProcessors操作)
1、String beanName = definitionHolder.getBeanName();
IOC DI,依赖注入的核心方法
singletonFactory.getObject() = createBean()
1、创建BeanFactory对象2、xml解析 传统标签解析:bean、import等 自定义标签解析 如:<context:component-scan base-package=\"com.xiangxue.jack\"/> 自定义标签解析流程: a、根据当前解析标签的头信息找到对应的namespaceUri b、加载spring所以jar中的spring.handlers文件。并建立映射关系 c、根据namespaceUri从映射关系中找到对应的实现了NamespaceHandler接口的类 d、调用类的init方法,init方法是注册了各种自定义标签的解析类 e、根据namespaceUri找到对应的解析类,然后调用paser方法完成标签解析3、把解析出来的xml标签封装成BeanDefinition对象
resolve(namespaceUri)
else
BeanDefinitionReaderUtil
2、处理注解修饰的BeanDefinition(@Lazy、@DependOn、@Primary、@Role、@Description),将这些注解修饰状态set到BeanDefinition中;
2、加载BeanDefinitionloadBeanDefinitions(beanDefinitionReader);
没有,直接调用getBean实例化
No
AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition
1)调用findAutowiringMetadata构建InjectionMetadata
判断是否缓存里面能拿到实例
进行国际化,初始化MessageSource
这里调用自定义标签解析器实现类的parser()
doRegisterBeanDefinitions()
1、拿到当前自定义标签的namespaceuriString namespaceUri = getNamespaceURI(ele);
从给定的FactoryBean获取要公开的对象。
loadBeanDefinitions(EncodedResource encodedResource)
(0)声明几个集合: BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();然后开始for循环解析AbstractApplicationContext.beanFactoryPostProcessors: if (postProcessor instanceof BeanDefinitionRegistryPostProcessor): 扫描继承了@Component注解到注解修饰类 添加到registryProcessors中。 else: 添加到regularPostProcessors中。
refreshBeanFactory()
判断parentBeanFactory中是否存在BeanDefinition实例(parentBeanFactory.getBean)
getObjectForBeanInstance()
缓存由FactoryBean创建的单例对象:<FactoryBean名称,对象>。
doLoadBeanDefinition()
3、扫描package,并且将其包装成BeanDefinition对象;Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
DefaultListableBeanFactory
AbstractRefreshableApplicationContext
ComponentScanBeanDefinitionParser
7、把实例化好的bean缓存到一次性的集合中(单例对象)
import标签解析
bean创建完成后singletonsCurrentlyInCreation要删除该bean:
循环1)获取的 beanNames,然后继续处理
直接调用createBean进行实例化
7
loadBeanDefinitions(Resource resource)=loadBeanDefinitions(new EncodedResource(resource));
factoryBeanName != null :factoryBean = this.beanFactory.getBean(factoryBeanName);
invokeBeanFactoryPostProcessors();
2、解析自定义Handler文件,获取自定义标签数据NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
1)设置类型转换器
2、span style=\"font-size: inherit;\
return wrappedBean;
bean 实例化+ioc依赖注入完以后的调用
2)触发初始化所有非懒加载的单例实例
BeanDefinitionRegistryPostProcessor(interface)
return InjectionMetadata
finishRefresh()
其他情况
parseBeanDefiniionElement()
findAutowiringMetadata
autowireConstructor();
注册bean销毁时的类DisposableBeanAdapter
bean实例化大致流程:
6、用无参构造函数实例化当前beanName对象,并return
6、倘若允许提前暴漏(earlySigntonExposure = 单例 & 允许循环依赖 & 当前bean正在创建),则“三级缓存升级二级缓存”(getSingleton)
5、这里调用一个子类可实现的方法,可以继承实现(指定偏向的构造函数),然后进行实例化,return
1、解析document,封装成BeanDefinitionBeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
1)BeanWrapperImpl设置类型转换器,初始化构造器集合candidates
finishBeanFactoryInitialization(beanFactory);
for (BeanPostProcessor postProcessor : postProcessors) { beanFactory.addBeanPostProcessor(postProcessor); }
1)如果实例不是FactoryBean类型的,或者name是以&号开头的,则直接返回实例
把beanName添加到singletonsCurrentlyInCreation Set容器中,在这个集合里面的bean都是正在实例化的bean(标识作用):
流程:1、先从一级缓存获取;2、没有拿到,并且正在创建过程中(this.singletonsCurrentlyInCreation.contains(beanName);)3、然后从二级缓存中获取singletonObject = this.earlySingletonObjects.get(beanName);4、获取不到,则从三级缓存中获取ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);singletonFactory != null 则继续执行singletonObject = singletonFactory.getObject();5、升级到二级缓存,并且移除三级缓存中beanName;
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory);
4、调用处理类的init方法,在init方法中完成标签元素解析类的注册namespaceHandler.init();
registerBeanDefinitionParser()
AbstractBeanFactory
循环autowiredAnnotationTypes容器,实例化当前类时就已经存在@Autowired和@Value
生成BeanName:beanName =BeanDefinitionReaderUtils.generateBeanName();
多例情况
preInstantiateSingletons()
ConstructorResolver
bw = new BeanWrapperImpl(); this.beanFactory.initBeanWrapper(bw);
buildAutowiringMetadata
finally { xxx afterSingletonCreation(beanName);}
DefaultNameSpaceHandlerResolver
int loadBeanDefinitions(String... locations)
containingBean != null
4、返回扫描到的beanDefinition集合
2、根据bean标签属性、子元素装饰BeanDefinitionHolder,比如<bean class=\"xx\" p:username=\"jack\
postProcessMergedBeanDefinition
4、beforeSingletonCreation(beanName);
(1)传入beanFactroy、beanFactory后置处理器,进行bean实例化
2-1)首先按名称进行注入 autowireByName();2-2)然后按照类型注入 autowireByType();内部还会有实例化操作。
返回构建的BeanDefinitionHolder
倘若有注册(hasInstAwareBpps == true)
PostProcessorRegistrationDelegate
1、构造Metadata对象,并将所有符合条件的属性或方法put进injectionMetadataCache(ConcurrentHashMap)中
initMessageSource();
instantiateUsingFactoryMethod()
XmlBeanDefinitionReader
1、从缓存(factoryBeanObjectCache)中取factoryBean对象,为null则继续
AbstractBeanDefinitionReader
addSingletonFactory(xxx)
后处理XmlpostProcessXml(root);
判断当前root节点是否为默认标签(defaultNameSpace)
1)初始化BeanWrapperImpl
解析bean中标签属性:meta标签、lookup-method标签、replace-method标签、constructor-arg标签、property标签等。
1、通过反射判断当前class中是否有Method存在Lookup注解,将lookup内部对应值封装到LookupOverride中,然后将其封装到BeanDefinition中(mbd.getMethodOverrides().addOverride(override);)2、查找缓存中是否有当前beanClass的candidate构造函数对象(Constructor),没有则继续,找到构造函数上是否有注解(包括父类构造函数),然后获取到@Autowired里面的required方法的值,最终包装成一个LinkedHashMap(candidateConstructorsCache),将候选构造函数和beanClass对象put进缓存(遍历autowiredAnnotationTypes容器,该容器初始化存在@Autowired和@Value注解)
5)解析<property name=\"username\" value=\"Jack\"/>标签并注入
xml解析时,把所有beanName都缓存到beanDefinitionNames:List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
Object singletonObject = this.singletonObjects.get(beanName);
importBeanDefinitionResource(ele);
3、加载BeanDefinitionint count = loadBeanDefinitions(resources);
(1)初始化一个集合:List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
AnnotatedElementUtils#getMergedAnnotationAttributes(xxx):1、递归获取属性上的注解,包括注解的父注解;2、将注解名和参数名包装成map(AnnotationAttributes继承LinkedHashMap,map的key是attributeName,value是相关参数)
拿到工程里面所有实现了BeanPostProcessor接口的类,获取到BeanDefinition的名称
返回实例
3、获取所有的BeanPostProcessor接口类型的对象,然后判断是否是SmartInstantiationAwareBeanPostProcessor类型的,然后循环调用determineCandidateConstructors方法,该方法的作用是获取有@Autowired注解的构造函数
4)最后进行有参构造函数的实例化
refreshBeanFactory()
parseBeanDefinition()
把root节点传进去 doRegisterBeanDefinitions(doc.getDocumentElement());
if (beanFactory instanceof BeanDefinitionRegistry)
尝试从缓存中获取metadata:InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
obtainFreshBeanFactory()
继续判断子节点标签是否为默认的
ClassPathNeanDefinitionScanner
alias标签解析
beforeSingletonCreation(beanName);
4、将部分组件注册到beanFactory中
invokeBeanFactoryPostProcessors内部调用的是:BeanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
2、将inputStream转换为InputSource,inputSource是jdk中的sax xml文件解析对象;
2、创建注解的扫描器;
AbstractAutowireCapableBeanFactory
getObjectFromFactoryBean()
2)获取BeanDefinition的propertyValues(MutablePropertyValues对象内部包含PropertyValue集合),
如果不是抽象的 && 是单例的 && 是非懒加载的 则进行实例化
invokeBeanDefinitionRegistryPostProcessors内部调用的是:BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry(registry);
6
1、BeanDefinitionDocumentReader委托这个类进行document的解析BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
doGetBean()
3)实例化Bean
2)调用metadata.checkConfigMembers(beanDefinition);校验并将参数注册到RootDefinition.externallyManagedConfigMembers中
获取给定bean实例的对象,对于FactoryBean,可以是bean实例本身,也可以是它创建的对象。
buildAutowiringMetadata()
getBeanFactory();
1
1、加载\"META-INF/spring.handlers\
预处理XmlpreProcessXml(root);
1、获取spring中所有jar包里面的 \"META-INF/spring.handlers\
true
doRegisterBeanDefinitions(ele);
1、实例化单例;2、实例化多例;
2)从缓存里面拿FactoryBean类型的实例
parseBeanDefinitionElement(ele);
BeanFactoryPostProcessor(interface)
把父BeanDefinition里面的属性合并到当前的BeanDefinition中(深拷贝且合并BeanDefinition,缓存到mergedBeanDefinitions中)
返回实例对象
NamespaceHandlerSupport
1、获取base-package属性值,并且用逗号隔开获得一个数组basePackage[];
3)判断是否已经注册了任何InstantiationAwareBeanPostProcessor
DefaultSingletonBeanRegistry
a. 父子合并为RootBeanDefinition;b. 检查Bean是否抽象(是则抛异常)c. 获取依赖对象属性,依赖对象要先实例化<bean depend-on=\"xxx\"/> 或者@DependsOn(xxx)优先实例化(getBean)depend-on的对象
parseDefaultElement()
进行DI/IOC
3、InitializingBean接口,afterPropertiesSet,init-method属性调用
BeanDefinitionParserDelegate
singletonObject = singletonFactory.getObject();newSingleton = true;
1)初始化beanNames集合
2、根据namespaceUri(例如:http://www.springframework.org/schema/p),获取到这个命名空间的处理类或类名Object handlerOrClassName = handlerMappings.get(namespaceUri);
3、解析xml,并把xml中的标签封装成BeanDefinition对象,保存到BeanFactory中:loadBeanDefinitions(beanFactory);
将beanName移除singletonsCurrentlyInCreation集合
loadBeanDefinition(beanFactory)
3、建立别名和 id的映射,这样就可以根据别名获取到id
DefaultBeanDefinitionDocumentReader
doCreateBean()
1、bean实例化过程(初始化所有剩余单例实例) 2、ioc 3、注解支持 4、BeanPostProcessor的执行 5、Aop的入口
2、把字符串类型的xml文件路径,形如:classpath*:user/**/*-context.xml,转换成Resource对象类型,其实就是用流的方式加载配置文件,然后封装成Resource对象:Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
0 条评论
下一页