Spring |
您所在的位置:网站首页 › spring的启动 › Spring |
前言
最近在阅读spring源码,refresh这个方法的处理流程每次看都会有一点新的认识。本文章是自己对这一块源码功能的梳理记录。文章只对这一块代码的主要流程做一个梳理,需要对以下类有一定的认识。 PropertySources BeanFactory DefaultListableBeanFactory ConfigurableListableBeanFactory BeanDefinitionRegistry BeanDefinition BeanFactoryPostProcessor BeanPostProcessor 另外,本文是基于springboot工程启动时梳理的spring的加载过程,有些实现类是springboot提供的。下面放一张类关系图。其中AnnotationConfigServletWebServerApplicationContext和ServletWebServerApplicationContext由springboot提供。下面的代码是从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. obtainFreshBeanFactoryspringboot启动时,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的类关系图: |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |