spring启动过程
2021-10-28 19:27:17 1 举报
spring简单启动过程
作者其他创作
大纲/内容
EventListenerMethodProcessor.postProcessBeanFactory
createBeanInstance(实例化)
invokeInitMethods
用户可以得到早期的bean
利用三级缓存解决循环依赖的问题1.singletonObjects 完整生命周期的bean对象。2.earlySingletonObjects Bean的生命周期还没走完就把这个Bean放入了earlySingletonObjects。3.singletonFactories用来创建早期bean对象的工厂。如果存在循环依赖,则会调用singletonFactories获取早期bean放入earlySingletonObjects(过度bean)
applyMergedBeanDefinitionPostProcessors
SmartInitializingSingleton
用户可以得到早期的bean,修改属性值
getBean
用户的bean实现InitializingBean接口或者自定义init方法,在这一步执行。
invokeAwareMethods
字段注入1. 遍历所有的AutowiredFieldElement对象。2. 将对应的字段封装为DependencyDescriptor对象。3. 调用BeanFactory的resolveDependency()方法,传入DependencyDescriptor对象,进行依赖查找,找到当前字段所匹配的Bean对象。4. 将DependencyDescriptor对象和所找到的结果对象beanName封装成一个ShortcutDependencyDescriptor对象作为缓存,比如如果当前Bean是原型Bean,那么下次再来创建该Bean时,就可以直接拿缓存的结果对象beanName去BeanFactory中去那bean对象了,不用再次进行查找了5. 利用反射将结果对象赋值给字段。Set方法注入1. 遍历所有的AutowiredMethodElement对象2. 遍历将对应的方法的参数,将每个参数封装成MethodParameter对象3. 将MethodParameter对象封装为DependencyDescriptor对象4. 调用BeanFactory的resolveDependency()方法,传入DependencyDescriptor对象,进行依赖查找,找到当前方法参数所匹配的Bean对象。5. 将DependencyDescriptor对象和所找到的结果对象beanName封装成一个ShortcutDependencyDescriptor对象作为缓存,比如如果当前Bean是原型Bean,那么下次再来创建该Bean时,就可以直接拿缓存的结果对象beanName去BeanFactory中去那bean对象了,不用再次进行查找了6. 利用反射将找到的所有结果对象传给当前方法,并执行。
用户实现InstantiationAwareBeanPostProcessor接口,实例化前,AOP就是在这里实现的
它能解析的注解是:@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description
postProcessAfterInitialization
放置AutowiredAnnotationProcessor/CommonAnnotationProcessor/ApplicationContextAwareProcessor/ApplicationListenerDetector/ImportAwareBeanPostProcessor
ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry
ConfigurationClassPostProcessor.postProcessBeanFactory
开始制造单例bean
用户实现SmartInstantiationAwareBeanPostProcessor,实现参考(初始化前选择构造方法)AutowiredAnnotationBeanPostProcessor
自定义类,实现BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry
自定义类,实现BeanFactoryPostProcessor.postProcessBeanFactory
DisposableBean或者自定义destroyMethod
执行这些Aware接口BeanNameAware/BeanClassLoaderAware/BeanFactoryAware
postProcessAfterInstantiation
preInstantiateSingletons
推断构造方法:1. 如果一个类只存在一个构造方法,不管该构造方法是无参构造方法,还是有参构造方法,Spring都会用这个构造方法2. 如果一个类存在多个构造方法 a. 这些构造方法中,存在一个无参的构造方法,那么Spring就会用这个无参的构造方法 b. 这些构造方法中,不存在一个无参的构造方法,那么Spring就会报错3. 不过如果某个构造方法上加了@Autowired注解,那就表示程序员告诉Spring就用这个加了注解的方法,那Spring就会用这个加了@Autowired注解构造方法了 。
自定义类,实现BeanDefinitionRegistryPostProcessor.postProcessBeanFactory
registerDisposableBeanIfNecessary
用户实现MergedBeanDefinitionPostProcessor接口,实现参考CommonAnnotationBeanPostProcessor/AutowiredAnnotationBeanPostProcessor,找出属性填充的地方Autowired/Value/Inject/WebServiceRef/EJB/Resource
总结BeanPostProcessor1. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()2. 实例化3. MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()4. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()5. 自动注入6. InstantiationAwareBeanPostProcessor.postProcessProperties()7. Aware对象8. BeanPostProcessor.postProcessBeforeInitialization()9. 初始化10. BeanPostProcessor.postProcessAfterInitialization()
初始化前ImportAwareBeanPostProcessor实现ImportAwareApplicationContextAwareProcessor实现各种XXXAwareInitDestroyAnnotationBeanPostProcessor执行@PostConstruct
instantiateBean(实例化)
determineCandidateConstructors
postProcessProperties、postProcessPropertyValues
实例化ClassPathBeanDefinitionScanner
1. HierarchicalBeanFactory:拥有获取父BeanFactory的功能2. ListableBeanFactory:拥有获取beanNames的功能3. ResourcePatternResolver:资源加载器,可以一次性获取多个资源(文件资源等等)4. EnvironmentCapable:可以获取运行时环境(没有设置运行时环境功能)5. ApplicationEventPublisher:拥有广播事件的功能(没有添加事件监听器的功能)6. MessageSource:拥有国际化功能
populateBean(属性填充)
实例化AnnotatedBeanDefinitionReader
1. 遍历当前类的所有的属性字段Field2. 查看字段上是否存在@Autowired、@Value、@Inject中的其中任意一个,存在则认为该字段是一个注入点3. 如果字段是static的,则不进行注入4. 获取@Autowired中的required属性的值5. 将字段信息构造成一个AutowiredFieldElement对象,作为一个注入点对象添加到currElements集合中。6. 遍历当前类的所有方法Method7. 判断当前Method是否是桥接方法,如果是找到原方法8. 查看方法上是否存在@Autowired、@Value、@Inject中的其中任意一个,存在则认为该方法是一个注入点9. 如果方法是static的,则不进行注入10. 获取@Autowired中的required属性的值11. 将方法信息构造成一个AutowiredMethodElement对象,作为一个注入点对象添加到currElements集合中。12. 遍历完当前类的字段和方法后,将遍历父类的,直到没有父类。13. 最后将currElements集合封装成一个InjectionMetadata对象,作为当前Bean对于的注入点集合对象,并缓存。
registerBeanPostProcessors
finishBeanFactoryInitialization
ScheduledAnnotationBeanPostProcessor定时任务Aop的代理类生成
实例化DefaultListableBeanFactory
invokeBeanFactoryPostProcessors
执行afterSingletonsInstantiated
postProcessBeforeInitialization
applyBeanPostProcessorsBeforeInstantiation
AOP大致流程1. 找出所有的切面Bean2. 遍历切面中的每个方法,看是否写了@Before、@After等注解3. 如果写了,则判断所对应的Pointcut是否和当前Bean对象的类是否匹配4. 如果匹配则表示当前Bean对象有匹配的的Pointcut,表示需要进行AOP
收藏
0 条评论
下一页