01.浅谈浏览器存储 | cookie,local
916 2023-04-03 02:39:03
本文的目的是记录自己在学习Spring容器启动过程中的一些笔记,以供后面复习,也希望可以给有需要的朋友提供一点帮助。本次分析所用的Spring版本为 5.1.4.RELEASE。首先我们从容器创建为入口,逐渐深入容器的启动过程。
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
上面这行代码大家应该都很熟悉,通过这行代码就可以完成IOC容器的初始化,让Spring帮我们管理一切。下面我们就从AnnotationConfigApplicationContext这个类开始,一层一层解开Spring的神秘面纱。
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { /** 此处只是初始化了Bean Definition的reader和scanner this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);*/this();// 此处只是将传进来的配置类(AppConfig.class注册到BeanDefinitionMap中去)register(annotatedClasses);// 重点在refresh方法里面refresh();}
在前两个方法中只是做了简单的初始化ioc容器所需的对象,此时ioc容器是空的,通过refresh方法会一次来解析beandefinition并产生对象装入容器中,下面来分析refresh方法。
// Prepare this context for refreshing. // 这个方法只是记录了容器启动时间,设置容器为active状态,并无实际操作,不重要。 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // 此处只是给Bean Factory设置了一个SerializationId ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // 初始化了IOC容器的一些工具,比如Class Loader、EL表达式解析器和属性解析器 prepareBeanFactory(beanFactory); // Allows post-processing of the bean factory in context subclasses. // 空方法 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. // 执行所有的BeanFactoryPostProcessor // 在ConfigurationClassPostProcessor#processConfigBeanDefinitions()方法会对所有的配置类进行处理,通过ConfigurationClassParser对象来解析,最终通过parser.parse(candidates);来调用解析方法。 // 其中会处理所有@Configuration注解的类,解析其配置的@Bean和@ComponentScan注解,将相关的Bean扫描并加入到BeanDefinitionMaps中,之后会使用动态代理(CGLIB)增强Configuration类,增强是直接修改Bean Definition中BeanClass属性,直接替换为代理后的class invokeBeanFactoryPostProcessors(beanFactory); // 注册了两个BeanPostProcessor,一个CommonBeanPostProcessor,另一个AutoWiredBeanPostProcessor,注意,这个后置处理器很重要,他是完成自动装配的关键! // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // 像BeanFactory注册了messageSource initMessageSource(); // Initialize event multicaster for this context. // 向BeanFactory注册了applicationEventMulticaster initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 空方法,api注释中写的是允许子类添加一些特定的逻辑在实例化单例Bean之前。 before instantiation of singletons. onRefresh(); // Check for listener beans and register them. // 将实现了ApplicationListener的类注册到applicationEventMulticaster中 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // 实例化Bean DefinitionMap中所有的非懒加载的单例Bean // 前面做大堆准备工作,最终会冻结配置,防止配置发生变化(freezeConfiguration),结束后调用preInstantiateSingletons()方法来实例化,由于实例化较为重要,下面单独分析preInstantiateSingletons方法 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // 结束启动过程,会清空在初始化过程中创建的一些缓存,同时调用LifecycleProcessor#onRefresh方法。最后会发布ContextRefreshedEvent事件。 finishRefresh();
以上就是Spring启动的全过程,后面我们会深入分析容器的初始化过程,容器如何解析配置类,如何根据配置类来实例化单例对象等。由于本人水平有限,难免遇到表述不清或错误的情况,如果存在任何问题,请大家及时提醒,我会在第一时间进行修正。