springBoot启动过程中容器刷新

springBoot容器刷新

上篇说了启动过程,现在说其中的刷新。上代码

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
      //刷新前准备
			prepareRefresh();

      //获取工厂
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      //工厂预处理(给工厂设置一些必要参数 类加载器 后置处理等)
			prepareBeanFactory(beanFactory);

			try {
        //工厂后置处理
				postProcessBeanFactory(beanFactory);

        //执行beanFactory后置处理器
				invokeBeanFactoryPostProcessors(beanFactory);

			//注册bean后置处理器
				registerBeanPostProcessors(beanFactory);

        //初始化信息(国际化等)
				initMessageSource();

				//初始化应用事件派发器
				initApplicationEventMulticaster();

				//子类实现(web容器就是在这里加载的)
				onRefresh();

				//注册监听器
				registerListeners();

				// 实例化剩下的bean(单例)
				finishBeanFactoryInitialization(beanFactory);

				// 后续操作(初始化生命周期等)
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

prepareRefresh

protected void prepareRefresh() {
  //记录时间,设置状态
   this.startupDate = System.currentTimeMillis();
   this.closed.set(false);
   this.active.set(true);

   if (logger.isInfoEnabled()) {
      logger.info("Refreshing " + this);
   }
   // 初始化属性源信息
   initPropertySources();
   //验证环境属性信息
   getEnvironment().validateRequiredProperties();
   this.earlyApplicationEvents = new LinkedHashSet<>();
}

invokeBeanFactoryPostProcessors

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  //获取所有实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的类然后执行 postProcessBeanFactory方法
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}

点进去invokeBeanFactoryPostProcessors

首先找到实现了BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的所有类,根据是否实现三种排序接口分类处理排序,放到一个集合中

然后执行方法,其中第二个实例是自定义实例

springBoot启动过程中容器刷新_第1张图片

自定义实例如下 :实现BeanDefinitionRegistryPostProcessor

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

        System.out.println("postProcessBeanDefinitionRegistry数量。。。"+registry.getBeanDefinitionCount());
//        System.out.println("postProcessBeanDefinitionRegistry数量。。。"+registry.getBeanDefinitionCount());
        RootBeanDefinition beanDefinition = new RootBeanDefinition(Row.class);
        registry.registerBeanDefinition("row",beanDefinition);

    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("postProcessBeanFactory数量"+beanFactory.getBeanDefinitionCount());

    }
}

此外其中一个重要的PostProcessor ConfigurationClassPostProcessor,它会对项目中的@Configuration注解修饰的类(@Component、@ComponentScan、@Import、@ImportResource修饰的类也会被处理)进行解析,解析完成之后把这些bean注册到BeanFactory中。需要注意的是这个时候注册进来的bean还没有实例化

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
      PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

registerBeanPostProcessors

和beanFactory的后置处理器一样,找到三种排序实现类进行注册实例化,这些BeanPostProcessor包括有AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)、RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)、CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。如果是自定义的BeanPostProcessor,已经被ConfigurationClassPostProcessor注册到容器内。这些BeanPostProcessor会在这个方法内被实例化(通过调用BeanFactory的getBean方法,如果没有找到实例化的类,就会去实例化)。

onRefresh

servlet容器就是在这里加载的,点进去找到子类ServletWebServerApplicationContext

@Override
protected void onRefresh() {
   super.onRefresh();
   try {
      createWebServer();
   }
   catch (Throwable ex) {
      throw new ApplicationContextException("Unable to start web server", ex);
   }
}

private void createWebServer() {
		WebServer webServer = this.webServer;
		ServletContext servletContext = getServletContext();
		if (webServer == null && servletContext == null) {
			ServletWebServerFactory factory = getWebServerFactory();
      //创建一个server 
			this.webServer = factory.getWebServer(getSelfInitializer());
		}
		else if (servletContext != null) {
			try {
				getSelfInitializer().onStartup(servletContext);
			}
			catch (ServletException ex) {
				throw new ApplicationContextException("Cannot initialize servlet context",
						ex);
			}
		}
		initPropertySources();
	}

创建server有三个子类,也是springBoot支持的三种servlet容器

springBoot启动过程中容器刷新_第2张图片

进到tomcat里,看到了tomcat熟悉的一些组件

public WebServer getWebServer(ServletContextInitializer... initializers) {
   Tomcat tomcat = new Tomcat();
   File baseDir = (this.baseDirectory != null) ? this.baseDirectory
         : createTempDir("tomcat");
   tomcat.setBaseDir(baseDir.getAbsolutePath());
  //连接器
   Connector connector = new Connector(this.protocol);
  //service
   tomcat.getService().addConnector(connector);
   customizeConnector(connector);
   tomcat.setConnector(connector);
  //host
   tomcat.getHost().setAutoDeploy(false);
   configureEngine(tomcat.getEngine());
   for (Connector additionalConnector : this.additionalTomcatConnectors) {
      tomcat.getService().addConnector(additionalConnector);
   }
   prepareContext(tomcat.getHost(), initializers);
   return getTomcatWebServer(tomcat);
}

finishBeanFactoryInitialization

开始实例化容器中的bean(后面详细说 bean的创建过程)

你可能感兴趣的:(SpringBoot)