本文已参与「新人创作礼」活动,一起开启掘金创作之路。
spring-ioc-xml源码学习
刷新上下文AbstractApplicationContext.refresh
==文章按照XML上下文梳理==
- 设置开始时间,closed置为false,active置为true
- initPropertySources子类未重写
- 校验环境必须参数(standardEnvironment)
- 初始化earlyApplicationEvents
- ==refreshBeanFactory刷新工厂,XML上下文由AbstractRefreshableApplicationContext,注解上下文由GenericApplicationContext实现==
- createBeanFactory创建工厂
- customizeBeanFactory自定义工厂配置,设置是否允许重写bean定义,是否允许循环依赖
* {@link DefaultListableBeanFactory}'s settings.
* @param beanFactory the newly created bean factory for this context
* @see DefaultListableBeanFactory#setAllowBeanDefinitionOverriding
* @see DefaultListableBeanFactory#setAllowCircularReferences
* @see DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping
* @see DefaultListableBeanFactory#setAllowEagerClassLoading
*/
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
- loadBeanDefinitions加载bean定义
- XmlBeanDefinitionReader创建xmlbean定义解析对象(reader中的registry与beanFactory绑定)
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
- 设置环境对象,resourceLoader对象(上下文本身),Entity解析对象
/**
* Loads the bean definitions via an XmlBeanDefinitionReader.
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
* @see #initBeanDefinitionReader
* @see #loadBeanDefinitions
*/
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
- initBeanDefinitionReader初始化:设置validating为true
- loadBeanDefinitions加载bean定义
graph LR
ApplicationContext-->BeanFactory
BeanFactory
BeanDefinitionReader.registry-->BeanFactory
BeanDefinitionReader.resourceLoader-->applicationContext
BeanDefinitionReader.entityResolver.resourceLoader-->applicationContext
- BeanDefinitionReader创建BeanDefinitionDocumentReader
- BeanDefinitionDocReader.registerBeanDefinitions注册bean至reader上下文(创建)
graph LR
XmlReaderContext-->DefaultNamespaceHandlerResolver
DefaultNamespaceHandlerResolver-->ApplicationContext.ClassLoader
XmlReaderContext-->XmlBeanDefinitionReader
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
return new DefaultNamespaceHandlerResolver(getResourceLoader().getClassLoader());
}
- DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions执行注册
- 注册beandefinition至registry
graph LR
getReaderContext.getRegistry-->reader.getRegistry
reader.getRegistry-->BeanFactory
public final BeanDefinitionRegistry getRegistry() {
return this.reader.getRegistry();
}
/**
* Process the given bean element, parsing the bean definition
* and registering it with the registry.
*/
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
- 刷新完成
- 返回工厂(DefaultListableBeanFactory)
- 调用入参的(spring系统自身配置)BeanDefinitionRegistryPostProcessor接口的实现bean的postProcessBeanDefinitionRegistry方法
- 调用getBean发现定义的BeanDefinitionRegistryPostProcessor接口的实现bean的postProcessBeanDefinitionRegistry方法,如果存在顺序,则按照顺序调用
- 根据类型获取调用getBean发现定义的BeanDefinitionRegistryPostProcessor接口的实现bean的postProcessBeanDefinitionRegistry方法
- 调用入参的(spring系统自身配置)BeanFactoryPostProcessor接口的实现bean的postProcessBeanFactory方法
- ---else---入参不是BeanDefinitionRegistryPostProcessor实现,直接调用spring入参的(spring系统自身配置)BeanFactoryPostProcessor接口的实现bean的postProcessBeanFactory方法
- 按照相同的方式(不包含按照类型获取),如果存在顺序,则按照顺序调用getBean发现定义的BeanFactoryPostProcessor接口的实现bean的postProcessBeanFactory方法
- 按照BeanPostProcessor类型获取所有实现bean名称,然后按照bean名称获取bean,如果有顺序,则按照顺序,否则正常,注册至beanFactory中
-
Initialize message source for this context.Initialize event multicaster for this context.Initialize other special beans in specific context subclasses.Check for listener beans and register them.
-
finishBeanFactoryInitialization完成beanFactory初始化
上下文中获取Bean
- bean工厂pre初始化
- getBean初始化
- 是否是合成的类(返回这个bean定义是否是“合成的”,也就是说,不是由应用程序本身定义的),是则判断,如果存在InstantiationAwareBeanPostProcessors注册,则获取对象class类并调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation方法,该方法如果返回对象,则遍历调用BeanPostProcessor.postProcessAfterInitialization方法,如果返回对象直接返回实例,否则继续
- 否则创建对象AbstractAutowireCapableBeanFactory.doCreateBean
- AbstractAutowireCapableBeanFactory.createBeanInstance创建实例
- 如果指定工厂方法创建,则调用工厂方法创建wrapperbean对象
- 如果指定autowired构造器,使用autowireConstructor方法创建wrapperbean对象
- 否则使用Cglib(CglibSubclassingInstantiationStrategy)创建动态代理wrapperbean对象,否则直接调用构造器构造wrapperbean对象(如果构造器不可访问,强制置为可访问)
- 是否存在MergedBeanDefinitionPostProcessor注册,存在则调用MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition回调
- 提前曝光对象
- 从early缓存中获取earlyBean,如果bean不是合成的,并且存在hasInstantiationAwareBeanPostProcessors注册,并且存在SmartInstantiationAwareBeanPostProcessor注册则调用SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference回调方法通知
- 继续初始化bean,组装bean注入populateBean,CommonAnnotationBeanPostProcessor处理Resource注解、EJB、WebServiceRef属性注入;AutowiredAnnotationBeanPostProcessor处理Autowired、Value注解属性注入,注入对象resolveDependency选择时会调用QualifierAnnotationAutowireCandidateResolver等实现选择一个建议的bean getSuggestedValue,如果没有则会判断isAutowireCandidate是否自动注入类型查找候选bean列表最终选择匹配的bean,如果是懒惰加载类型则调用getLazyResolutionProxyIfNecessary获取代理对象;RequiredAnnotationBeanPostProcessor处理Required注解属性注入
- 如果存在InstantiationAwareBeanPostProcessor注册,则调用InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation回调方法,如果任何一个返回false失败则终止后续的回调
- 根据名称、类型注入对象
- 如果存在InstantiationAwareBeanPostProcessor注册,调用InstantiationAwareBeanPostProcessor.postProcessPropertyValues方法回调通知。可以在populateBean注入属性前拦截到待注入的属性进行一些特殊处理
- populateBean注入属性后初始化bean,initializeBean
- 如果bean是Aware类型,按照相应的类型通知beanName,beanClassloader,beanFactory
- 调用BeanPostProcessor类型的postProcessBeforeInitialization方法,初始化前置动作
- 调用afterPropertiesSet再调用用户自定义的init方法
- 调用BeanPostProcessor类型的postProcessAfterInitialization方法,初始化后置动作
- getBean初始化完成
- getBean初始化完成后如果对象是SmartInitializingSingleton的实现,则回调afterSingletonsInstantiated
总结
autowired注解流程
- 实现类:org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
- 解析出需要注入的bean对象:org.springframework.beans.factory.config.AutowireCapableBeanFactory#resolveDependency(org.springframework.beans.factory.config.DependencyDescriptor, java.lang.String, java.util.Set<java.lang.String>, org.springframework.beans.TypeConverter)
- 通过下面两个类查找可注入的候选bean:org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate org.springframework.beans.factory.support.GenericTypeAwareAutowireCandidateResolver#isAutowireCandidate
注意autowired注入的属性类型涉及泛型,会检查泛型,例如:要注入的bean类型为KafkaTemplate<Object, Object>,上下文中存在KafkaTemplate类型的bean有两个,一个name=kafkaTemplate,type=KafkaTemplate,一个name=otherKafkaTemplate,type=KafkaTemplate<Object, Object>。最终注入的一定是otherKafkaTemplate
检查bean类型是否可注入可以参考下方代码:org.springframework.beans.factory.support.GenericTypeAwareAutowireCandidateResolver#checkGenericTypeMatch return dependencyType.isAssignableFrom(targetType); 按照上面的案例,此处的dependencyType=KafkaTemplate<Object, Object>,targetType=KafkaTemplate