Spring

您所在的位置:网站首页 spring的启动 Spring

Spring

#Spring | 来源: 网络整理| 查看: 265

前言

最近在阅读spring源码,refresh这个方法的处理流程每次看都会有一点新的认识。本文章是自己对这一块源码功能的梳理记录。文章只对这一块代码的主要流程做一个梳理,需要对以下类有一定的认识。

PropertySources BeanFactory DefaultListableBeanFactory ConfigurableListableBeanFactory BeanDefinitionRegistry BeanDefinition BeanFactoryPostProcessor BeanPostProcessor 另外,本文是基于springboot工程启动时梳理的spring的加载过程,有些实现类是springboot提供的。下面放一张类关系图。其中AnnotationConfigServletWebServerApplicationContext和ServletWebServerApplicationContext由springboot提供。

annotation.png

refresh整体结构

下面的代码是从AbstractApplicationContext类中摘下来的,只保留了关键处理流程。Spring启动时会执行这个方法,主要流程就是try代码块中的几个方法。里面的功能包含:

Ioc容器初始化 对扫描到的class进行封装 bean的实例化、属性填充、初始化、扩展点方法的调用 AOP包装 public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh"); prepareRefresh(); ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); prepareBeanFactory(beanFactory); try { postProcessBeanFactory(beanFactory); StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process"); invokeBeanFactoryPostProcessors(beanFactory); registerBeanPostProcessors(beanFactory); beanPostProcess.end(); initMessageSource(); initApplicationEventMulticaster(); onRefresh(); registerListeners(); finishBeanFactoryInitialization(beanFactory); finishRefresh(); } catch (BeansException ex) { destroyBeans(); cancelRefresh(ex); throw ex; } finally { resetCommonCaches(); contextRefresh.end(); } } } 流程梳理 1. prepareRefresh

清理scanner的缓存,初始化PropertySources,校验环境中的一些关键属性。

2. obtainFreshBeanFactory

springboot启动时,beanFactory是在refresh执行之前创建的,这里直接返回。

3. prepareBeanFactory(beanFactory)

设置一些ioc容器加载时必须使用的 BeanPostProcessor 和 register。

4. postProcessBeanFactory(beanFactory)

根据我的上下文,是进入AnnotationConfigReactiveWebServerApplicationContext中,啥也没做。

5.invokeBeanFactoryPostProcessors(beanFactory) 主要流程 调用 BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,扫描class,封装成BeanDefinition。分三次调用,第一次时实现PriorityOrdered接口的,第二次是实现 Ordered 接口的,第三次是其他的所有注册器,例如mybatis的注册器。 调用 BeanFactoryPostProcessor的postProcessBeanFactory方法,在bean创建之前,修改bean的定义属性。分三次调用,第一次时实现PriorityOrdered接口的,第二次是实现 Ordered 接口的,第三次是其他的。 关键类功能 ConfigurationClassPostProcessor:从启动类开作为入口,解析 @Configuration 标记的类。扫描出来的class后边会遍历进行处理。 ClassPathBeanDefinitionScanner:doScan方法干活,把能读取到的class文件中使用了@Component注解的类都封装成BeanDefinition。@Bean注解标记的class,判断scope是否需要创建代理对象。 ConfigurationClassParser:doProcessConfigurationClass方法解析当前类,把@PropertySource、@ComponentScan、@Import、@ImportResource、@Bean、接口方法、super类方法都进行处理。需要注册的bean统统管理在beanFactory中。 扩展点 @Import、@ImportResource注解。在执行到这两个注解的处理时可以把自定义的对象导入到spring容器中。 BeanDefinitionRegistryPostProcessor接口。实现类放到spring中之后,spring会调用对应的postProcessBeanDefinitionRegistry,实现自定义对象的注册。 6. registerBeanPostProcessors(beanFactory) 主要流程 通过前面的扫描和注册,spring能管理的bean都已经被读取出来了。这里找出实现了BeanPostProcessor接口的类,按优先级排序后注册起来。优先级从高到低依次是实现PriorityOrdered接口的,实现 Ordered 接口的,没优先级和order顺序的,internal的。 7. initMessageSource

国际化处理

8. initApplicationEventMulticaster

初始化一个事件广播器,注册到beanFactory中。

9. onRefresh 功能 我们这里分析的是web应用,这里会使用内置的tomcat创建一个webserver。 10. registerListeners

注册listener

11. finishBeanFactoryInitialization(beanFactory) 主要流程 实例化非延迟加载的bean实例 遍历所有的beanName,通过getBean去创建需要加载的bean。涉及实例化、填充、初始化三个阶段。 再遍历所有的beanName,找到SmartInitializingSingleton类型的bean,调用它的afterSingletonsInstantiated方法。 getBean()处理过程 Object sharedInstance = getSingleton(beanName); 先获取一次 markBeanAsCreated(beanName); 放到已经创建的列表,做标记用 getSingleton(String beanName, ObjectFactory singletonFactory); 再获取一次,没有的话调用singletonFactory.getObject()创建 createBean(beanName, mbd, args); // 这就是上面的创建具体实现 doCreateBean(beanName, mbdToUse, args);//真正的创建方法 populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw); // 这里会触发InstantiationAwareBeanPostProcessor中postProcessPropertyValues的调用 initializeBean(beanName, exposedObject, mbd);// 1、触发BeanPostProcessor的postProcessBeforeInitialization 2、触发InitializingBean的afterPropertiesSet 3、触发BeanPostProcessor的postProcessAfterInitialization的调用 循环依赖解决 protected Object getSingleton(String beanName, boolean allowEarlyReference) { // Quick check for existing instance without full singleton lock Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { synchronized (this.singletonObjects) { // Consistent creation of early reference within full singleton lock singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { ObjectFactory singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); // 把自己暴露在二级缓存中 this.earlySingletonObjects.put(beanName, singletonObject); // 从一级缓存中删除 this.singletonFactories.remove(beanName); } } } } } } return singletonObject; } protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } // 走到这里,bean已经创建完成 protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); // 删除 this.earlySingletonObjects.remove(beanName); // 删除 this.registeredSingletons.add(beanName); } } 关键类的功能 AutowiredAnnotationBeanPostProcessor:对@Autowired注解标记的对象进行注入 DefaultSingletonBeanRegistry 注册bean,解决循环依赖 扩展点 BeanPostProcessor InitializingBean InstantiationAwareBeanPostProcessor 12. finishRefresh

发布ContextRefreshedEvent事件

关于AOP

@EnableAspectJAutoProxy开启Aop,里面导入AspectJAutoProxyRegistrar类,这个类会注入一个AnnotationAwareAspectJAutoProxyCreator类,这个类是BeanPostProcesser接口的一个实现类,在initializeBean执行前后会执行接口总的实现方法,实现代理的效果。

AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

下面放一个AOP的类关系图:

aop.png

总结 Spring先对beanFactory进行初始化工作 以启动类作为入口,扫描出所有可以读取到的class 对扫描出来的class进行解析,继续扫描出所有需要管理的class,全部封装为beanDefinition 找出所有的BeanPostProcessor并注册 遍历所有的beanName,实例化需要提前加载的bean。这里包括实例化、自动注入、初始化三个阶段。同时处理了循环依赖问题。每个阶段还包括对扩展点的调用。


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3