spring boot的BeanDefinitionMap初始化

2019-01-17  本文已影响0人  全都是泡沫啦
1.执行在Initializer中congtext创建BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
2.获取BeanFactory中BeanDefinitionMap的(PriorityOrdered)BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
    处理ConfigurationClassPostProcessor
3.获取BeanFactory中BeanDefinitionMap的(Ordered)BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
4.获取BeanFactory中BeanDefinitionMap的BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
5.统一执行1-4步中的BeanDefinitionRegistryPostProcessor#postProcessBeanFactory
6.统一执行1-4步中的BeanFactoryPostProcessor#postProcessBeanFactory
7.步5和步6执行完可能继续生成剩余未处理的BeanFactoryPostProcessor此时统一按:PriorityOrdered=>Ordered=>普通调用#postProcessBeanFactory
    在PriorityOrdered中存在PropertySourcesPlaceholderConfigurer对于BeanDefinition中字符串${}进行替换
        visitParentName(beanDefinition);
        visitBeanClassName(beanDefinition);
        visitFactoryBeanName(beanDefinition);
        visitFactoryMethodName(beanDefinition);
        visitScope(beanDefinition);
        visitPropertyValues(beanDefinition.getPropertyValues());
        ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues();
        visitIndexedArgumentValues(cas.getIndexedArgumentValues());
        visitGenericArgumentValues(cas.getGenericArgumentValues());


ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry执行过程:
1.parse(Set<BeanDefinitionHolder> configCandidates):解析BeanDefinitionHolder
2.BeanDefinition包装为ConfigurationClass
3.processConfigurationClass(ConfigurationClass configClass):解析ConfigurationClass
4.doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
    1:processMemberClasses()解析内部类:存在Configuration则执行步骤3.processConfigurationClass(ConfigurationClass configClass)
    2:解析SourceClass可重复注解@PropertySource,获取value(为文件的位置),并添加ResourcePropertySource到Environment(instanceof ConfigurableEnvironment)
    3.解析SourceClass可重复注解@ComponentScan,通过ClassPathBeanDefinitionScanner扫描文件获取到ScannedGenericBeanDefinition并注册到Registry.BeanDefinitionMap,遍历scannedBeanDefinitions是否为Configuration候选者,是则包装为ConfigurationClass并执行则执行步骤3.processConfigurationClass(ConfigurationClass configClass)
    4.getImports(sourceClass)并解析:@Import中的value值(TODO:涉及到4种情况)
    5.解析注解@ImportResource然后configClass.addImportedResource(resolvedResource, readerClass);
    6.获取sourceClass中@bean方法并configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
    7.获取sourceClass所有接口中的默认@bean方法并configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
    8.获取sourceClass父类(除去java包下或者排除knownSuperclasses)如果存在则执行步骤4.doProcessConfigurationClass
5.处理延时processDeferredImportSelectors
    1.org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector这里面会对META-INF/spring.factories中的EnableAutoConfiguration.class进行配置
6.注册ConfigurationClasses到Registry.BeanDefinitionMap
    1.判断是否shouldSkip(注意Configuration有父子关系,也需要判断)
    2.ConfigurationClass如果是被父亲引入的需要将该注册到BeanDefinitionMap
    3.注册configClass.getBeanMethods(),注册到BeanDefinitionMap
    4.loadBeanDefinitionsFromImportedResources,这里会对资源文件进行判断读取".groovy":GroovyBeanDefinitionReader.class,其他的按XmlBeanDefinitionReader.class读取
    5.loadBeanDefinitionsFromRegistrars调用ImportBeanDefinitionRegistrar#registerBeanDefinitions
7.获取当前BeanDefinitionMap中未处理的Configuration进行执行步骤1parse(Set<BeanDefinitionHolder> configCandidates)

通过分析完bean definition如何加载到BeanFactory,我们提出几个问题:
1.@Conditional和@ConfigurationCondition的使用原理 以及两个周期(PARSE_CONFIGURATION,REGISTER_BEAN)
2.@Import的使用原理
Configuration ImportSelector ImportBeanDefinitionRegistrar (regular component)classes
3.如何进行自动配置,AutoConfigurationImportSelector原理
4.什么时候加载PropertySourcesPlaceholderConfigurer
5.@ComponentScan扫描
6.BeanDefinitionRegistryPostProcessor和BeanDefinitionPostProcessor区别

BeanDefinitionRegistryPostProcessor主要bean definition定义 包括BeanDefinitionPostProcessor的定义
BeanDefinitionPostProcessor        主要bean definition处理

7.ApplicationContextInitializer和ApplicationContext区别
8.SpringApplicationRunListeners的生命周期
9.AnnotationMetadata的实现类StandardAnnotationMetadata(基于AnnotatedElementUtils)和AnnotationMetadataReadingVisitor(基于asm实现) asm实现相对较弱只能识别当前类的字节码内容
10.PropertySourcesPropertyResolver的使用原理

        MutablePropertySources propertySources = new MutablePropertySources();
        Map<String,Object> map = new HashMap<>(16);
        map.put("application.name","Test");
        map.put("port","Test");
        map.put("application.port","${port:9080}");
        propertySources.addLast(new MapPropertySource("hello",map));
        PropertySourcesPropertyResolver propertySourcesPropertyResolver = new PropertySourcesPropertyResolver(propertySources);

        String s0 = propertySourcesPropertyResolver.getProperty("application.port");
        String s1 = propertySourcesPropertyResolver.resolvePlaceholders("${application.port}");
        String s2 = propertySourcesPropertyResolver.resolveRequiredPlaceholders("${application.port}");

spring对bean创建过程的扩展
org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessPropertyValues
    RequiredAnnotationBeanPostProcessor
    AutowiredAnnotationBeanPostProcessor
invokeAwareMethods(BeanNameAware,BeanClassLoaderAware,BeanFactoryAware)
org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
    ApplicationContextAwareProcessor#invokeAwareInterfaces(EnvironmentAware,ApplicationEventPublisherAware,ApplicationContextAware...)
    InitDestroyAnnotationBeanPostProcessor@PostConstruct
invokeInitMethods=((InitializingBean) bean).afterPropertiesSet();
invokeCustomInitMethod
org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization

对于bean实现SmartInitializingSingleton进行处理(如RestTemplate的LoadBalanced)
注意factorybean.getObject后会执行org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
DefaultListableBeanFactory#preInstantiateSingletons初始化单例bean后对SmartInitializingSingleton进行继续加工处理

容器关闭时候:
手动关闭org.springframework.context.support.AbstractApplicationContext#close
外部命令触发:org.springframework.context.ConfigurableApplicationContext#registerShutdownHook
扩展流程:
发布事件ContextClosedEvent
org.springframework.context.LifecycleProcessor#onClose
org.springframework.beans.factory.DisposableBean#destroy
org.springframework.context.support.AbstractApplicationContext#onClose

dependentBeanMap  key:beanName value:依赖beanName的bean
dependenciesForBeanMap key:beanName value:beanName依赖的bean
singletonObjects:
earlySingletonObjects:
singletonFactories:
registeredSingletons:
singletonsCurrentlyInCreation:
alreadyCreated:
mergedBeanDefinitions:
beanDefinitionMap:

org.springframework.beans.factory.support.AbstractBeanDefinition#autowireMode

AUTOWIRE_BY_NAME|AUTOWIRE_BY_TYPE会对bean中的PropertyDescriptor进行分析注入,而@autowire是通过后置处理postProcessPropertyValues进行处理添加到PropertyValues
上一篇下一篇

猜你喜欢

热点阅读