本篇文章是针对上篇文章启动原理的补充,主要介绍Spring IOC容器初始化中刷新应用上下文操作。
查看源码发现refreshContext(context) --> refresh(context) --> ApplicationContext.refresh()
所以我们这里详细说一下这个refresh()方法。
代码如下:
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //第一步:容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等 prepareRefresh(); //第二步:获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等,注意此处是获取新的,销毁旧的,这就是刷新的意义(Spring容器里通过BeanDefinition对象来表示Bean,BeanDefinition描述了Bean的配置信息。) ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //第三步:配置标准的beanFactory,设置ClassLoader,设置SpEL表达式解析器等 prepareBeanFactory(beanFactory); try { //第四步:在所有的beanDenifition加载完成之后,bean实例化之前执行。比如在beanfactory加载完成所有的bean后,想修改其中某个bean的定义,或者对beanFactory做一些其他的配置,就可以在子类中对beanFactory进行后置处理。 postProcessBeanFactory(beanFactory); //第五步:实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor的bean) invokeBeanFactoryPostProcessors(beanFactory); //第六步:实例化和注册beanFactory中扩展了BeanPostProcessor的bean。 //例如: AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入) //RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法) //CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。 registerBeanPostProcessors(beanFactory); //第七步:初始化国际化工具类MessageSource initMessageSource(); //第八步:初始化应用事件广播器。这是观察者模式的典型应用。我们知道观察者模式由主题Subject和Observer组成。广播器相当于主题Subject,其包含多个监听器。当主题发生变化时会通知所有的监听器。初始化应用消息广播器,并放入"ApplicationEventMulticaster" Bean中 initApplicationEventMulticaster(); //第九步:这个方法在AnnotationApplicationContex上下文中没有实现,留给子类来初始化其他的Bean,是个模板方法,在容器刷新的时候可以自定义逻辑(子类自己去实现逻辑),不同的Spring容器做不同的事情 onRefresh(); //第十步:注册监听器,并且广播early application events,也就是早期的事件 registerListeners(); //第十一步:初始化剩下的单例(非懒加载的单例类)(并invoke BeanPostProcessors) //实例化所有剩余的(非懒加载)单例Bean。(也就是我们自己定义的那些Bean) //比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化,扫描的@Bean之类的, //实例化的过程各种BeanPostProcessor开始起作用 finishBeanFactoryInitialization(beanFactory); //第十二步:完成刷新过程,通知生命周期处理器lifecycleProcessor完成刷新过程,同时发出ContextRefreshEvent通知别人 //refresh做完之后需要做的其他事情 //清除上下文资源缓存(如扫描中的ASM元数据) //初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。 //发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } //如果刷新失败那么就会将已经创建好的单例Bean销毁掉 destroyBeans(); //重置context的活动状态 告知是失败的 cancelRefresh(ex); //抛出异常 throw ex; } finally { // 失败与否,都会重置Spring内核的缓存。因为可能不再需要metadata给单例Bean了。 resetCommonCaches(); } } }
protected void prepareRefresh() { //记录容器启动时间,然后设立对应的标志位 this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); // 打印info日志:开始刷新当前容器了 if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // 这是扩展方法,由子类去实现,可以在验证之前为系统属性设置一些值可以在子类中实现此方法 // 因为我们这边是AnnotationConfigApplicationContext,可以看到不管父类还是自己,都什么都没做,所以此处先忽略 initPropertySources(); //属性文件验证,确保需要的文件都已经放入环境中 getEnvironment().validateRequiredProperties(); //初始化容器,用于装载早期的一些事件 this.earlyApplicationEvents = new LinkedHashSet<>(); }
obtainFreshBeanFactory()方法会解析所有Spring配置文件(通常我们会放在 resources 目录下),将所有 Spring 配置文件中的 bean 定义封装成 BeanDefinition,加载到 BeanFactory中。常见的,如果解析到<context:component-scan base-package="" /> 注解时,会扫描 base-package 指定的目录,将该目录下使用指定注解(@Controller、@Service、@Component、@Repository)的 bean 定义也同样封装成 BeanDefinition,加载到 BeanFactory 中。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { //初始化BeanFactory refreshBeanFactory(); //返回初始化之后的BeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
protected final void refreshBeanFactory() throws BeansException { //判断是否已经存在BeanFactory,存在则销毁所有Beans,并且关闭BeanFactory if (hasBeanFactory()) { //销毁所有的bean destroyBeans(); //关闭并销毁BeanFactory closeBeanFactory(); } try { //创建具体的beanFactory,这里创建的是DefaultListableBeanFactory,最重要的beanFactory spring注册及加载bean就靠它 DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); //定制BeanFactory,包括是否允许覆盖同名称的不同定义的对象以及循环依赖 customizeBeanFactory(beanFactory); //这个就是最重要的了,加载所有的Bean配置信息(属于模版方法,由子类去实现加载的方式) loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { //allowBeanDefinitionOverriding属性是指是否允对一个名字相同但definition不同进行重新注册,默认是true。 if (this.allowBeanDefinitionOverriding != null) { beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } //allowCircularReferences属性是指是否允许Bean之间循环引用,默认是true. if (this.allowCircularReferences != null) { beanFactory.setAllowCircularReferences(this.allowCircularReferences); } }
实现loadBeanDefinitions()的子类有多种,如AbstractXmlApplicationContext类提供了基于XML的加载实现,AnnotationConfigWebApplicationContext类提供了在webapp的场景下基于注解配置的加载实现,XmlWebApplicationContext类提供了在webapp场景下基于xml配置的加载实现,XmlPortletApplicationContext提供了在portalet下基于xml配置的加载实现,GroovyWebApplicationContext类提供了基于groovy脚本配置的加载实现。
下面以AnnotationConfigWebApplicationContext#loadBeanDefinitions()方法为例看下代码。
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) { //初始化这个脚手架 其实就是直接new出实例 AnnotatedBeanDefinitionReader reader = getAnnotatedBeanDefinitionReader(beanFactory); ClassPathBeanDefinitionScanner scanner = getClassPathBeanDefinitionScanner(beanFactory); // 生成Bean的名称的生成器,如果自己没有setBeanNameGenerator(可以自定义),这里目前为null BeanNameGenerator beanNameGenerator = getBeanNameGenerator(); if (beanNameGenerator != null) { reader.setBeanNameGenerator(beanNameGenerator); scanner.setBeanNameGenerator(beanNameGenerator); //若我们注册了beanName生成器,那么就会注册进容器里面 beanFactory.registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator); } //这是给reader和scanner注册scope的解析器 此处为null ScopeMetadataResolver scopeMetadataResolver = getScopeMetadataResolver(); if (scopeMetadataResolver != null) { reader.setScopeMetadataResolver(scopeMetadataResolver); scanner.setScopeMetadataResolver(scopeMetadataResolver); } //我们可以自己指定annotatedClasses 配置文件,同时也可以交给下面扫描 if (!this.annotatedClasses.isEmpty()) { // 这里会把所有的配置文件输出=======info日志 请注意观察控制台 if (logger.isDebugEnabled()) { logger.debug("Registering annotated classes: [" + StringUtils.collectionToCommaDelimitedString(this.annotatedClasses) + "]"); } // 若是指明的Bean,就交给reader去处理 reader.register(ClassUtils.toClassArray(this.annotatedClasses)); } // 也可以是包扫描的方式,扫描配置文件的Bean if (!this.basePackages.isEmpty()) { if (logger.isDebugEnabled()) { logger.debug("Scanning base packages: [" + StringUtils.collectionToCommaDelimitedString(this.basePackages) + "]"); } scanner.scan(StringUtils.toStringArray(this.basePackages)); } // 此处的意思是,也可以以全类名的形式注册。比如可以调用setConfigLocations设置(这在xml配置中使用较多) 可以是全类名,也可以是包路径 String[] configLocations = getConfigLocations(); if (configLocations != null) { for (String configLocation : configLocations) { try { Class<?> clazz = ClassUtils.forName(configLocation, getClassLoader()); if (logger.isTraceEnabled()) { logger.trace("Registering [" + configLocation + "]"); } reader.register(clazz); } catch (ClassNotFoundException ex) { if (logger.isTraceEnabled()) { logger.trace("Could not load class for config location [" + configLocation + "] - trying package scan. " + ex); } int count = scanner.scan(configLocation); // 发现不是全类名,那就当作包扫描 if (count == 0 && logger.isDebugEnabled()) { logger.debug("No annotated classes found for specified class/package [" + configLocation + "]"); } } } } }
该方法主要是解析我们项目配置的 application.xml、xxx.xml 定义的import、bean、resource、profile、、、、、。或扫描注解 将其属性封装到BeanDefinition 对象中。
上面提到的 “加载到 BeanFactory 中” 的内容主要指的是添加到以下3个缓存:
beanDefinitionNames缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 集合。
beanDefinitionMap缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和 BeanDefinition 映射( Map<String, BeanDefinition>,beanName--key和beanDefinition--value)。
aliasMap缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和别名映射。
现在BeanFactory已经创建完成了,并且Config配置文件的Bean定义已经注册完成了(备注:其它单例Bean是还没有解析的),下面的步骤大都把BeanFactory传进去了,都是基于此Bean工厂的操作。
至此,spring已经完成了对配置的解析,开始ApplicationContext功能上的扩展。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { //设置beanFactory的classLoader为当前context的classLoader beanFactory.setBeanClassLoader(getClassLoader()); //设置EL表达式解析器(Bean初始化完成后填充属性时会用到) beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //设置属性注册解析器PropertyEditor 这个主要是对bean的属性等设置管理的一个工具 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // 将当前的ApplicationContext对象交给ApplicationContextAwareProcessor类来处理,从而在Aware接口实现类中的注入applicationContext等等 // 添加了一个处理aware相关接口的beanPostProcessor扩展,主要是使用beanPostProcessor的postProcessBeforeInitialization()前置处理方法实现aware相关接口的功能 // 类似的还有下面的ResourceLoaderAware、ServletContextAware等等等等 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); //设置几个忽略自动装配的接口( 默认只有BeanFactoryAware被忽略,所以其它的需要自行设置) beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // 设置几个"自动装配"规则======如下: // 如果是BeanFactory的类,就注册beanFactory // 如果是ResourceLoader、ApplicationEventPublisher、ApplicationContext等等就注入当前对象this(applicationContext对象) // 此处registerResolvableDependency()方法注意:它会把他们加入到DefaultListableBeanFactory的resolvableDependencies字段里面缓存这,供后面处理依赖注入的时候使用 DefaultListableBeanFactory#resolveDependency处理依赖关系 // 这也是为什么我们可以通过依赖注入的方式,直接注入这几个对象比如ApplicationContext可以直接依赖注入 // 但是需要注意的是:这些Bean,Spring的IOC容器里其实是没有的。beanFactory.getBeanDefinitionNames()和beanFactory.getSingletonNames()都是找不到他们的,所以特别需要理解这一点 // 至于容器中没有,但是我们还是可以@Autowired直接注入的有哪些,请看下图 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // 注册这个Bean的后置处理器:在Bean初始化后检查是否实现了ApplicationListener接口 // 是则加入当前的applicationContext的applicationListeners列表 这样后面广播事件也就方便了 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // 检查容器中是否包含名称为loadTimeWeaver的bean,实际上是增加Aspectj的支持 // AspectJ采用编译期织入、类加载期织入两种方式进行切面的织入 // 类加载期织入简称为LTW(Load Time Weaving),通过特殊的类加载器来代理JVM默认的类加 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { // 添加BEAN后置处理器:LoadTimeWeaverAwareProcessor // 在BEAN初始化之前检查BEAN是否实现了LoadTimeWeaverAware接口, // 如果是,则进行加载时织入,即静态代理。 beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // 注入一些系统环境的bean,比如environment、systemProperties、SystemEnvironment等 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
附:IOC容器中没有Bean,但是我们还是可以依赖注入的Bean如下(resolvableDependencies):
主要扩展: 1. 增加对SPEL语言的支持; 2. 增加对属性编辑器的支持,这些PropertyEditors在这里只是注册,使用的时候是将bean包装成BeanWrapper,包装后的BeanWrapper的就包含了所有的这些PropertyEditors,以便后期给bean设置属性的时候使用; 3. 增加对一些内置类(实际上就是前置处理器),比如Aware接口的信息注入; 4. 设置依赖功能可忽略的接口; 5. 注册一些固定的bean,这些都是特殊的依赖解析,比如当注册了BeanFactory.class的依赖解析之后,当bean的属性注入的时候,一旦检测到属性为BeanFactory类型便会将beanFactory的实例注入进去; 6. 增加对AspectJ的支持; 7. 将相关环境变量及属性以单例模式注册。
到这里beanFactory都准备好了,子类可以自己去实现自己的逻辑。所以postProcessBeanFactory这个模版方法用于子类对beanFactory进行后置处理。比如一些web的ApplicationContext,就实现了自己的逻辑,做一些自己的web相关的事情。此处我们看下AbstractRefreshableWebApplicationContext#postProcessBeanFactory方法:
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { //注册ServletContextAwareProcessor 这样任意Bean都可以很方便的获取到ServletContext了 同时忽略另外两个,因为ServletContextAwareProcessor 都把事情都做了 beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig)); beanFactory.ignoreDependencyInterface(ServletContextAware.class); beanFactory.ignoreDependencyInterface(ServletConfigAware.class); //注册web环境,包括request、session、golableSession、application WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext); //注册servletContext、contextParamters、contextAttributes 、servletConfig单例bean WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig); }
invokeBeanFactoryPostProcessors执行BeanFactory后置处理器,前提是你已经在容器中注册过此处理器了。这个接口跟BeanPostProcessor类似,可以对bean的定义(配置元数据)进行处理,作用范围是容器级的,只对自己的容器的bean进行处理。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 1.getBeanFactoryPostProcessors(): 拿到当前应用上下文beanFactoryPostProcessors变量中的值 // 2.invokeBeanFactoryPostProcessors: 实例化并调用所有已注册的BeanFactoryPostProcessor PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // 这里就是定制:如果loadTimeWeaver这个Bean存在,那么就会配置上运行时织入的处理器LoadTimeWeaverAwareProcessor if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
拿到当前应用上下文 beanFactoryPostProcessors 变量中的值.
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() { return this.beanFactoryPostProcessors; }
它不是返回Spring容器里面的Processors,而是你自己的注册的(你自己手动set的),也就是说我们自己手动调用set方法添加进去,就能够执行。并不需要自己配置@Bean或者在xml里配置,那么重点就在于PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors:
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // 这个doc说明很清楚:不管怎么样,先执行BeanDefinitionRegistryPostProcessors // 需要注意的是BeanDefinitionRegistryPostProcessors 为 BeanFactoryPostProcessor 的子接口 它新增了方法:void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) // BeanFactoryPostProcessor 的方法为;void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; // 所以BeanDefinitionRegistryPostProcessors,我们介入并改变Bean的一些定义信息 Set<String> processedBeans = new HashSet<>(); // 1.判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory, // 而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此这边为true //1.只有此beanFactory是BeanDefinitionRegistry 才能执行BeanDefinitionRegistryPostProcessor,才能修改Bean的定义 (beanFactory为DefaultListableBeanFactory,而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此这边为true) if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // 用于存放普通的BeanFactoryPostProcessor List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>(); // 用于存放BeanDefinitionRegistryPostProcessor List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>(); 都是LinkedList,所以执行顺序和set进去的顺序是保持一样的 // 2.首先处理入参中的beanFactoryPostProcessors // 遍历所有的beanFactoryPostProcessors, 将BeanDefinitionRegistryPostProcessor和普通BeanFactoryPostProcessor区分开 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { // 2.1 如果是BeanDefinitionRegistryPostProcessor BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; // 2.1.1 直接执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法 registryProcessor.postProcessBeanDefinitionRegistry(registry); // 2.1.2 添加到registryProcessors(用于最后执行postProcessBeanFactory方法) registryProcessors.add(registryProcessor); } else { // 2.2 否则,只是普通的BeanFactoryPostProcessor // 2.2.1 添加到regularPostProcessors(用于最后执行postProcessBeanFactory方法)regularPostProcessors.add(postProcessor); } } // 用于保存本次要执行的BeanDefinitionRegistryPostProcessor List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // 3.调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类 // 3.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // 3.2 遍历postProcessorNames for (String ppName : postProcessorNames) { // 3.3 校验是否实现了PriorityOrdered接口 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 3.4 获取ppName对应的bean实例, 添加到currentRegistryProcessors中, // beanFactory.getBean: 这边getBean方法会触发创建ppName对应的bean对象, 目前暂不深入解析currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); // 3.5 将要被执行的加入processedBeans,避免后续重复执行 processedBeans.add(ppName); } } // 3.6 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序) sortPostProcessors(currentRegistryProcessors, beanFactory); // 3.7 添加到registryProcessors(用于最后执行postProcessBeanFactory方法) registryProcessors.addAll(currentRegistryProcessors); // 3.8 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 3.9 执行完毕后, 清空currentRegistryProcessors currentRegistryProcessors.clear(); // 4.调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类(过程跟上面的步骤3基本一样) // 4.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的类, 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor, // 可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 校验是否实现了Ordered接口,并且还未执行过 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); // 4.2 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // 5.最后, 调用所有剩下的BeanDefinitionRegistryPostProcessors boolean reiterate = true; while (reiterate) { reiterate = false; // 5.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的类 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 5.2 跳过已经执行过的 if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); // 5.3 如果有BeanDefinitionRegistryPostProcessor被执行, 则有可能会产生新的BeanDefinitionRegistryPostProcessor, // 因此这边将reiterate赋值为true, 代表需要再循环查找一次 reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); // 5.4 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // 6.调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法(BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor) invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); // 7.最后, 调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // 到这里 , 入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕, // 下面开始处理容器中的所有BeanFactoryPostProcessor // 8.找出所有实现BeanFactoryPostProcessor接口的类 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); // 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName List<String> orderedPostProcessorNames = new ArrayList<>(); // 用于存放普通BeanFactoryPostProcessor的beanName List<String> nonOrderedPostProcessorNames = new ArrayList<>(); // 8.1 遍历postProcessorNames, 将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开 for (String ppName : postProcessorNames) { // 8.2 跳过已经执行过的 if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 8.3 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { // 8.4 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName orderedPostProcessorNames.add(ppName); } else { // 8.5 添加剩下的普通BeanFactoryPostProcessor的beanName nonOrderedPostProcessorNames.add(ppName); } } // 9.调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor // 9.1 对priorityOrderedPostProcessors排序 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); // 9.2 遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法 invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 10.调用所有实现Ordered接口的BeanFactoryPostProcessor List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String postProcessorName : orderedPostProcessorNames) { // 10.1 获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行 orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } // 10.2 对orderedPostProcessors排序 sortPostProcessors(orderedPostProcessors, beanFactory); // 10.3 遍历orderedPostProcessors, 执行postProcessBeanFactory方法 invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // 11.调用所有剩下的BeanFactoryPostProcessor List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String postProcessorName : nonOrderedPostProcessorNames) { // 11.1 获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行 nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } // 11.2 遍历nonOrderedPostProcessors, 执行postProcessBeanFactory方法 invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); / 12.清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType), // 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符... beanFactory.clearMetadataCache(); }
invokeBeanFactoryPostProcessors(beanFactory)这一步主要做了:
到这里Bean工厂完全准备好了,并且也注册好了所有的Bean的定义信息(此时Bean还并没有创建)。也完成了对配置文件的解析,可以说Spring IOC容器的大部分准备工作已经完成了,接下来就是对Bean的一些初始化、操作
略。。。
略。。。
略。。。
略。。。
在所有注册的Bean中查找Listenter bean,注册到消息广播器中。
protected void registerListeners() { // 首先注册静态注册的监听器(代码注册的) for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // 获取容器中所有配置的listener并注册 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // 对earlyApplicationEvents这些事件进行广播,实际上就是遍历所有的listener,找到可以处理event的listener处理 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
初始化剩下的非惰性单例,如果某个单例依赖了惰性的单例,那么这个惰性的单例也会被初始化,这个很好理解吧。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // 初始化ConversionService,跟PropertyEditor类似 if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } //则注册默认的嵌入值解析器 //例如PropertyPlaceholderConfigurer bean)之前注册过: //主要用于注解属性值的解析。 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } //单例bean初始化之前首先初始化LoadTimeWeaverAware,以支持aop,AspectJ String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); //冻结bean定义(BeanDefinition),表示所有的bean定义进不被修改或进行进一步处理 beanFactory.freezeConfiguration(); //初始化非惰性单例,实际上就是遍历所有的beanName,然后一一调用getBean() beanFactory.preInstantiateSingletons(); }
protected void finishRefresh() { //清除上下文级别(context-level)的资源缓存,比如由scanning产生的ASM元数据 clearResourceCaches(); //初始化LifecycleProcessor initLifecycleProcessor(); //使用LifecycleProcessor来启动Lifecycle子类 getLifecycleProcessor().onRefresh(); //上下文刷新完成,发布事件 publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); }
初始化LifecycleProcessor的时候,跟初始化MessageResource一样,没有自定义的就是用默认的DefaultLifecycleProcessor。
getLifecycleProcessor().onRefresh()会使用我们注册的LyfecycleProcessor来启动我们注册的SmartLifeCycle的子类。看一下代码吧。
//默认的DefaultLifecycleProcessor.java public void onRefresh() { startBeans(true); this.running = true; }
private void startBeans(boolean autoStartupOnly) { //获取所有的LifeCycle类型的bean Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans(); Map<Integer, LifecycleGroup> phases = new HashMap<>(); lifecycleBeans.forEach((beanName, bean) -> { //默认的DefaultLifecycleProcessor只会启动SmartLifecycle的,或者非自动启动的类型 //SmartLifecycle继承了Phases接口 if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) { int phase = getPhase(bean); LifecycleGroup group = phases.get(phase); if (group == null) { group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly); //添加到需要启动的集合中 phases.put(phase, group); } group.add(beanName, bean); } }); //启动需要启动的这些LifeCycle if (!phases.isEmpty()) { List<Integer> keys = new ArrayList<>(phases.keySet()); Collections.sort(keys); for (Integer key : keys) { phases.get(key).start(); } } }
这一步主要完成以下操作:
Spring刷新应用上下文操作简要划分为12步操作流程:
1.准备刷新--->2.获取刷新bean工厂--->3.准备bean工厂--->4.前处理bean工厂--->
5.调用bean工厂前处理器--->6.注册bean前处理器--->7.初始化消息源--->8.初始化应用事件发布器--->
9.刷新--->10.注册监听器--->11.完成bean工厂初始化--->12.完成刷新.