1.1 Springboot启动:

  1. @SpringBootApplication
  2. public class ServerApplication {
  3. public static void main(String[] args) {
  4. SpringApplication.run(ServerApplication.class,args);
  5. }
  6. }

从上面代码看,调用了SpringApplication的静态方法run。这个run方法会构造一个SpringApplication的实例,然后再调用这里实例的run方法就表示启动SpringBoot。具体对象处理流程看下边时序图:

概述:

构造SpringApplication的实例(时序图步骤1-2)
调用SpringApplication.run()方法(时序图步骤3)
构造SpringApplicationRunListeners 实例(时序图步骤3.1.1)
发布ApplicationStartedEvent事件(时序图步骤3.1.2)
SpringApplicationRunListeners 实例准备环境信息(时序图步骤3.1.3)
创建ApplicationContext对象(时序图步骤3.1.4)
ApplicationContext实例准备环境信息(时序图步骤3.1.5)
刷新的上下文(时序图步骤3.1.6)
注:文章按照该顺序讲解【1.2 启动加载过程分析】

时序图:

1.2 启动加载过程分析

1.2.1 构造SpringApplication的实例(时序图步骤1-2)

代码

  1. public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
  2. // 步骤1
  3. return new SpringApplication(sources).run(args);
  4. }
  5. public SpringApplication(Object... sources) {
  6. // 步骤1.1
  7. initialize(sources);
  8. }
  9. @SuppressWarnings({ "unchecked", "rawtypes" })
  10. private void initialize(Object[] sources) {
  11. if (sources != null && sources.length > 0) {
  12. this.sources.addAll(Arrays.asList(sources));
  13. }
  14. this.webEnvironment = deduceWebEnvironment();
  15. //加载META-INF/spring.factories路径ApplicationContextInitializer.class
  16. getSpringFactoriesInstances(
  17. ApplicationContextInitializer.class));
  18. setListeners((Collection)
  19. //加载META-INF/spring.factories路径ApplicationListener.class
  20. getSpringFactoriesInstances(ApplicationListener.class));
  21. this.mainApplicationClass = deduceMainApplicationClass();
  22. }
1.2.2 步骤3.1.1:

代码

  1. private SpringApplicationRunListeners getRunListeners(String[] args) {
  2. Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
  3. // (1)
  4. return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
  5. SpringApplicationRunListener.class, types, this, args));
  6. }

分析
(1). 通过ClassLoader.getResources加载META-INF/spring.factories路径下的
文件信息,从中找key为SpringApplicationRunListener对应类,并实例化。

1.2.3 步骤3.1.2:

代码

  1. public void starting() {
  2. for (SpringApplicationRunListener listener : this.listeners) {
  3. listener.starting();
  4. }
  5. }
  6. @Override
  7. @SuppressWarnings("deprecation")
  8. public void starting() {
  9. this.initialMulticaster.multicastEvent(new ApplicationStartedEvent(this.application, this.args));
  10. }

分析
发布ApplicationStartedEvent事件。

1.2.4 步骤3.1.3:

代码

  1. private ConfigurableEnvironment prepareEnvironment(
  2. SpringApplicationRunListeners listeners,
  3. ApplicationArguments applicationArguments) {
  4. // Create and configure the environment
  5. // ⑴. 得到环境对象ConfigurableEnvironment,没有则创建一个StandardServletEnvironment
  6. ConfigurableEnvironment environment = getOrCreateEnvironment();
  7. // ⑵. 配置环境信息(激活环境,通过从系统环境变量里取)
  8. configureEnvironment(environment, applicationArguments.getSourceArgs());
  9. // ⑶. 发布ApplicationEnvironmentPreparedEvent事件,加载配置文件,具体请看(ConfigFileApplicationListener)。
  10. listeners.environmentPrepared(environment);
  11. if (isWebEnvironment(environment) && !this.webEnvironment) {
  12. environment = convertToStandardEnvironment(environment);
  13. }
  14. return environment;
  15. }
  16.  
  17. protected void configureEnvironment(ConfigurableEnvironment environment,String[] args) {
  18. configurePropertySources(environment, args);
  19. // 配置ConfigurableEnvironment中的激活属性
  20. configureProfiles(environment, args);
  21. }
  22. protected void configureProfiles(ConfigurableEnvironment environment, String[] args) {
  23. environment.getActiveProfiles(); // ensure they are initialized
  24. // additionalProfiles是项目启动时在main中SpringApplication.setAdditionalProfiles("")配置的
  25. Set<String> profiles = new LinkedHashSet<>(this.additionalProfiles);
  26. // 获取环境变量中设置的spring.profiles.active属性
  27. profiles.addAll(Arrays.asList(environment.getActiveProfiles()));
  28. // 赋值 activeProfiles
  29. environment.setActiveProfiles(StringUtils.toStringArray(profiles));
  30. }

分析
⑴. 得到环境对象ConfigurableEnvironment,没有则创建一个StandardServletEnvironment
⑵. 配置激活环境信息,通过从系统环境变量里取或启动时通过SpringApplication.setAdditionalProfiles("")添加进来的
⑶. 发布ApplicationEnvironmentPreparedEvent事件,加载Spring配置文件信息,例如application.properties等。具体请看Spring Boot 属性文件(三)

步骤3.1.4:
分析
创建ApplicationContext对象 ,本文启动的是SERVLET所以会创建AnnotationConfigServletWebServerApplicationContext对象

  1. protected ConfigurableApplicationContext createApplicationContext() {
  2. Class<?> contextClass = this.applicationContextClass;
  3. if (contextClass == null) {
  4. try {
  5. switch (this.webApplicationType) {
  6. case SERVLET:
  7. contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
  8. break;
  9. case REACTIVE:
  10. contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
  11. break;
  12. default:
  13. contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
  14. }
  15. }
  16. catch (ClassNotFoundException ex) {
  17. throw new IllegalStateException(
  18. "Unable create a default ApplicationContext, "
  19. + "please specify an ApplicationContextClass",ex);
  20. }
  21. }
  22. return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
  23. }
  24.  
  25. public AnnotationConfigServletWebServerApplicationContext() {
  26. this.reader = new AnnotatedBeanDefinitionReader(this);
  27. this.scanner = new ClassPathBeanDefinitionScanner(this);
  28. }

会创建AnnotatedBeanDefinitionReader对象检测是否需要将一下对象放到Spring上下文中

  1. // 用户配置Configuration注解,实现了BeanDefinitionRegistryPostProcessor接口,在容器刷新时,处理后置工厂处理器用来扫描Spring,注册Bean
  2. ConfigurationClassPostProcessor
  3. // 用于配置Autowired注解,实现了MergedBeanDefinitionPostProcessor接口
  4. AutowiredAnnotationBeanPostProcessor
  5. // 用于配置Required注解,实现了MergedBeanDefinitionPostProcessor接口
  6. RequiredAnnotationBeanPostProcessor
  7. // 用于配置JSR-250注解,实现了InstantiationAwareBeanPostProcessor接口
  8. CommonAnnotationBeanPostProcessor
  9. // 用于配置JPA注解
  10. PersistenceAnnotationBeanPostProcessor
  11. // 用于配置EventListener注解,实现了SmartInitializingSingleton接口
  12. EventListenerMethodProcessor
  13. // EventListener工厂
  14. DefaultEventListenerFactory
步骤3.1.5:

代码

  1. private void prepareContext(ConfigurableApplicationContext context,
  2. ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
  3. ApplicationArguments applicationArguments, Banner printedBanner) {
  4. // ⑴.对ApplicationContext设置环境变量;
  5. context.setEnvironment(environment);
  6. // ⑵.配置属性ResourceLoader和ClassLoader属性;
  7. postProcessApplicationContext(context);
  8. // ⑶.循环初始化继承ApplicationContextInitializer接口的类
  9. applyInitializers(context);
  10. listeners.contextPrepared(context);
  11. if (this.logStartupInfo) {
  12. logStartupInfo(context.getParent() == null);
  13. logStartupProfileInfo(context);
  14. }
  15.  
  16. // Add boot specific singleton beans
  17. context.getBeanFactory().registerSingleton("springApplicationArguments",
  18. applicationArguments);
  19. if (printedBanner != null) {
  20. context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
  21. }
  22.  
  23. // Load the sources
  24. Set<Object> sources = getSources();
  25. Assert.notEmpty(sources, "Sources must not be empty");
  26. load(context, sources.toArray(new Object[sources.size()]));
  27. listeners.contextLoaded(context);
  28. }
  29.  
  30. @Override
  31. public void setEnvironment(ConfigurableEnvironment environment) {
  32. super.setEnvironment(environment);
  33. this.reader.setEnvironment(environment);
  34. this.scanner.setEnvironment(environment);
  35. }

分析:
⑴.对ApplicationContext设置环境变量;
⑵.配置属性ResourceLoader和ClassLoader属性;
⑶.调用步骤1查询出来ApplicationContextInitializer子类,循环调用initialize()方法。

  1. @SuppressWarnings({ "rawtypes", "unchecked" })
  2. protected void applyInitializers(ConfigurableApplicationContext context) {
  3. for (ApplicationContextInitializer initializer : getInitializers()) {
  4. Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(
  5. initializer.getClass(), ApplicationContextInitializer.class);
  6. Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
  7. initializer.initialize(context);
  8. }
  9. }

⑷.发布ApplicationPreparedEvent事件。

步骤3.1.6

代码:

  1. @Override
  2. public void refresh() throws BeansException, IllegalStateException {
  3. synchronized (this.startupShutdownMonitor) {
  4. // ⑴.准备刷新的上下文环境
  5. prepareRefresh();
  6.  
  7. // ⑵.初始化BeanFactory
  8. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
  9.  
  10. // ⑶.对BeanFactory进行各种功能填充
  11. prepareBeanFactory(beanFactory);
  12.  
  13. try {
  14. // ⑷.子类覆盖方法做额外的处理
  15. postProcessBeanFactory(beanFactory);
  16.  
  17. // ⑸.激活各种BeanFactory处理器
  18. invokeBeanFactoryPostProcessors(beanFactory);
  19.  
  20. // ⑹.注册拦截Bean创建的Bean处理,这里只是注册,真正调用是再拿去Bean的时候
  21. registerBeanPostProcessors(beanFactory);
  22.  
  23. // ⑺.为上下文初始化Message源,即不同语言的消息体,国际化处理
  24. initMessageSource();
  25.  
  26. // ⑻.初始化应用消息广播器,并放到applicationEventMulticaster bean中
  27. initApplicationEventMulticaster();
  28.  
  29. // ⑼.留给子类来初始化其他bean
  30. onRefresh();
  31.  
  32. // ⑽.在所有注册的bean中查找Listener bean,注册到消息广播中
  33. registerListeners();
  34.  
  35. // ⑾.初始化剩下的单实例(非惰性)
  36. finishBeanFactoryInitialization(beanFactory);
  37.  
  38. // ⑿.完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
  39. finishRefresh();
  40. }
  41.  
  42. catch (BeansException ex) {
  43. if (logger.isWarnEnabled()) {
  44. logger.warn("Exception encountered during context initialization - " +
  45. "cancelling refresh attempt: " + ex);
  46. }
  47.  
  48. // Destroy already created singletons to avoid dangling resources.
  49. destroyBeans();
  50.  
  51. // Reset 'active' flag.
  52. cancelRefresh(ex);
  53.  
  54. // Propagate exception to caller.
  55. throw ex;
  56. }
  57.  
  58. finally {
  59. // Reset common introspection caches in Spring's core, since we
  60. // might not ever need metadata for singleton beans anymore...
  61. resetCommonCaches();
  62. }
  63. }
  64. }

分析:

⑴.准备刷新的上下文环境
⑵.初始化BeanFactory
⑶.对BeanFactory进行各种功能填充
⑷.子类覆盖方法做额外的处理,这里会调用子类AnnotationConfigServletWebServerApplicationContext注入
⑸.激活各种BeanFactory处理器
⑹.注册拦截Bean创建的Bean处理,这里只是注册,真正调用是再拿去Bean的时候
⑺.为上下文初始化Message源,即不同语言的消息体,国际化处理
⑻.初始化事件派发器,并放到applicationEventMulticaster bean中
⑼.留给子类来初始化其他bean
⑽.在所有注册的bean中查找Listener bean,注册到事件派发器中
⑾.初始化剩下的单实例(非惰性)
⑿.完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人

⑷.子类覆盖方法做额外的处理

  1. @Override
  2. protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  3. super.postProcessBeanFactory(beanFactory);
  4. if (this.basePackages != null && this.basePackages.length > 0) {
  5. this.scanner.scan(this.basePackages);
  6. }
  7. if (!this.annotatedClasses.isEmpty()) {
  8. this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
  9. }
  10. }
  11.  
  12. @Override
  13. protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  14. // 添加后置处理器,在创建Tomcat时会利用这个后置处理器来初始化Tomcat Server类
  15. beanFactory.addBeanPostProcessor(
  16. new WebApplicationContextServletContextAwareProcessor(this));
  17. beanFactory.ignoreDependencyInterface(ServletContextAware.class);
  18. registerWebApplicationScopes();
  19. }

添加后置处理器,在创建Tomcat时会利用这个后置处理器来初始化Tomcat Server类

⑸.激活各种BeanFactory处理器
主要利用**步骤3.1.4:**创建AnnotatedBeanDefinitionReader对象往Spring容器中注入的ConfigurationClassPostProcessor来处理组件的注入

具体请看容器刷新,

⑺.为上下文初始化Message源,即不同语言的消息体,国际化处理

  1. protected void initMessageSource() {
  2. ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  3. if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
  4. this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
  5. // Make MessageSource aware of parent MessageSource.
  6. if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
  7. HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
  8. if (hms.getParentMessageSource() == null) {
  9. // Only set parent context as parent MessageSource if no parent MessageSource
  10. // registered already.
  11. hms.setParentMessageSource(getInternalParentMessageSource());
  12. }
  13. }
  14. if (logger.isDebugEnabled()) {
  15. logger.debug("Using MessageSource [" + this.messageSource + "]");
  16. }
  17. }
  18. else {
  19. //
  20. // Use empty MessageSource to be able to accept getMessage calls.
  21. DelegatingMessageSource dms = new DelegatingMessageSource();
  22. dms.setParentMessageSource(getInternalParentMessageSource());
  23. this.messageSource = dms;
  24. beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
  25. if (logger.isDebugEnabled()) {
  26. logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
  27. "': using default [" + this.messageSource + "]");
  28. }
  29. }
  30. }

如果容器中没有则创建一个DelegatingMessageSource国际化,并将它注册到Spring容器中

⑻.初始化事件派发器,并放到applicationEventMulticaster bean中
  1. protected void initApplicationEventMulticaster() {
  2. ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  3. if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
  4. this.applicationEventMulticaster =
  5. beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
  6. if (logger.isDebugEnabled()) {
  7. logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
  8. }
  9. }
  10. else {
  11. this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
  12. beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
  13. if (logger.isDebugEnabled()) {
  14. logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
  15. APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
  16. "': using default [" + this.applicationEventMulticaster + "]");
  17. }
  18. }
  19. }

如果容器中没有则创建一个SimpleApplicationEventMulticaster事件派发器,并将它注册到Spring容器中

⑼.留给子类来初始化其他bean
主要目的是初始化Tomcat等内置服务器

SpingBoot启动过程二

⑽.在所有注册的bean中查找Listener bean,注册到事件派发器中

  1. protected void registerListeners() {
  2. // Register statically specified listeners first.
  3. for (ApplicationListener<?> listener : getApplicationListeners()) {
  4. getApplicationEventMulticaster().addApplicationListener(listener);
  5. }
  6.  
  7. // Do not initialize FactoryBeans here: We need to leave all regular beans
  8. // uninitialized to let post-processors apply to them!
  9. // 从容器中获取所有的事件监听器,添加到事件派发器
  10. String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
  11. for (String listenerBeanName : listenerBeanNames) {
  12. getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
  13. }
  14.  
  15. // Publish early application events now that we finally have a multicaster...
  16. // 如果早期有些事件,则在此将其派发出去
  17. Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
  18. this.earlyApplicationEvents = null;
  19. if (earlyEventsToProcess != null) {
  20. for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
  21. getApplicationEventMulticaster().multicastEvent(earlyEvent);
  22. }
  23. }
  24. }

⑾.初始化剩下的单实例(非惰性)

  1. protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
  2. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
  3. beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
  4. beanFactory.setConversionService(
  5. beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
  6. }
  7. if (!beanFactory.hasEmbeddedValueResolver()) {
  8. beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
  9. }
  10. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
  11. for (String weaverAwareName : weaverAwareNames) {
  12. getBean(weaverAwareName);
  13. }
  14. beanFactory.setTempClassLoader(null);
  15. beanFactory.freezeConfiguration();
  16.  
  17. // 实例化单实例bean
  18. beanFactory.preInstantiateSingletons();
  19. }
  20.  
  21. @Override
  22. public void preInstantiateSingletons() throws BeansException {
  23. if (logger.isDebugEnabled()) {
  24. logger.debug("Pre-instantiating singletons in " + this);
  25. }
  26.  
  27. // 获取容器中所有的Bean,实例化
  28. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
  29. for (String beanName : beanNames) {
  30. RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
  31. // 如果不是抽象,是单实例,并且不是懒加载
  32. if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
  33. // 没有实现FactoryBean接口的Bean
  34. if (isFactoryBean(beanName)) {
  35. Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
  36. if (bean instanceof FactoryBean) {
  37. final FactoryBean<?> factory = (FactoryBean<?>) bean;
  38. boolean isEagerInit;
  39. if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
  40. isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
  41. ((SmartFactoryBean<?>) factory)::isEagerInit,
  42. getAccessControlContext());
  43. }
  44. else {
  45. isEagerInit = (factory instanceof SmartFactoryBean &&
  46. ((SmartFactoryBean<?>) factory).isEagerInit());
  47. }
  48. if (isEagerInit) {
  49. getBean(beanName);
  50. }
  51. }
  52. }
  53. else {
  54. getBean(beanName);
  55. }
  56. }
  57. }
  58.  
  59. // Trigger post-initialization callback for all applicable beans...
  60. for (String beanName : beanNames) {
  61. Object singletonInstance = getSingleton(beanName);
  62. if (singletonInstance instanceof SmartInitializingSingleton) {
  63. final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
  64. if (System.getSecurityManager() != null) {
  65. AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
  66. smartSingleton.afterSingletonsInstantiated();
  67. return null;
  68. }, getAccessControlContext());
  69. }
  70. else {
  71. smartSingleton.afterSingletonsInstantiated();
  72. }
  73. }
  74. }
  75. }

首先判断Bean不是抽象,是单实例,不是懒加载,再判断Bean没有实现FactoryBean,则调用getBean()方法创建Bean

1 getBean方法创建Bean

  1. @Override
  2. public Object getBean(String name) throws BeansException {
  3. return doGetBean(name, null, null, false);
  4. }
  5.  
  6. @SuppressWarnings("unchecked")
  7. protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
  8. @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
  9.  
  10. final String beanName = transformedBeanName(name);
  11. Object bean;
  12.  
  13. // Eagerly check singleton cache for manually registered singletons.
  14. Object sharedInstance = getSingleton(beanName);
  15. if (sharedInstance != null && args == null) {
  16. if (logger.isDebugEnabled()) {
  17. if (isSingletonCurrentlyInCreation(beanName)) {
  18. logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
  19. "' that is not fully initialized yet - a consequence of a circular reference");
  20. }
  21. else {
  22. logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
  23. }
  24. }
  25. bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
  26. } else {
  27. ........省略
  28. // 如果实现了dependsOn则现将dependsOn创建出来
  29. String[] dependsOn = mbd.getDependsOn();
  30. if (dependsOn != null) {
  31. for (String dep : dependsOn) {
  32. if (isDependent(beanName, dep)) {
  33. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  34. "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
  35. }
  36. registerDependentBean(dep, beanName);
  37. try {
  38. getBean(dep);
  39. }
  40. catch (NoSuchBeanDefinitionException ex) {
  41. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  42. "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
  43. }
  44. }
  45. }
  46. // 单实例Bean创建
  47. if (mbd.isSingleton()) {
  48. sharedInstance = getSingleton(beanName, () -> {
  49. try {
  50. return createBean(beanName, mbd, args);
  51. }
  52. catch (BeansException ex) {
  53. destroySingleton(beanName);
  54. throw ex;
  55. }
  56. });
  57. bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
  58. }
  59. }
  60. }

1.1 createBean

  1. @Override
  2. protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  3. throws BeanCreationException {
  4. ....省略
  5.  
  6. try {
  7. // 处理InstantiationAwareBeanPostProcessor类型的后置处理器
  8. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  9. if (bean != null) {
  10. return bean;
  11. }
  12. }
  13. catch (Throwable ex) {
  14. }
  15.  
  16. try {
  17. // 创建Bean
  18. Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  19. if (logger.isDebugEnabled()) {
  20. logger.debug("Finished creating instance of bean '" + beanName + "'");
  21. }
  22. return beanInstance;
  23. }
  24. catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
  25. }
  26. catch (Throwable ex) {
  27. }
  28. }

会先调用resolveBeforeInstantiation,判断当前后置处理器是否是InstantiationAwareBeanPostProcessor,如果是,则提前执行applyBeanPostProcessorsBeforeInstantiation,如果applyBeanPostProcessorsBeforeInstantiation方法返回的结果不是null,则执行applyBeanPostProcessorsAfterInitialization方法,如果最终结果不是null则直接返回不是则进行doCreateBean方法

  1. protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  2. Object bean = null;
  3. if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
  4. // Make sure bean class is actually resolved at this point.
  5. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  6. Class<?> targetType = determineTargetType(beanName, mbd);
  7. if (targetType != null) {
  8. bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
  9. if (bean != null) {
  10. bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
  11. }
  12. }
  13. }
  14. mbd.beforeInstantiationResolved = (bean != null);
  15. }
  16. return bean;
  17. }

1.1.1 doCreateBean方法

  1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException {
  2. BeanWrapper instanceWrapper = null;
  3. ....省略
  4. // 创建bean实例
  5. final Object bean = instanceWrapper.getWrappedInstance();
  6. ....省略
  7.  
  8. synchronized (mbd.postProcessingLock) {
  9. if (!mbd.postProcessed) {
  10. try {
  11. // 触发后置处理器MergedBeanDefinitionPostProcessor
  12. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
  13. }
  14. catch (Throwable ex) {
  15. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  16. "Post-processing of merged bean definition failed", ex);
  17. }
  18. mbd.postProcessed = true;
  19. }
  20. }
  21. ....省略
  22.  
  23. Object exposedObject = bean;
  24. try {
  25. // 为bean属性赋值
  26. populateBean(beanName, mbd, instanceWrapper);
  27. exposedObject = initializeBean(beanName, exposedObject, mbd);
  28. }
  29. }

创建Bean,触发后置处理器MergedBeanDefinitionPostProcessor,执行postProcessMergedBeanDefinition方法

1.1.1.1populateBean方法
  1. protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
  2. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  3. for (BeanPostProcessor bp : getBeanPostProcessors()) {
  4. if (bp instanceof InstantiationAwareBeanPostProcessor) {
  5. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
  6. // 执行后置处理器InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法
  7. if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
  8. continueWithPropertyPopulation = false;
  9. break;
  10. }
  11. }
  12. }
  13. }
  14. ....省略
  15. if (hasInstAwareBpps || needsDepCheck) {
  16. if (pvs == null) {
  17. pvs = mbd.getPropertyValues();
  18. }
  19. PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
  20. if (hasInstAwareBpps) {
  21. for (BeanPostProcessor bp : getBeanPostProcessors()) {
  22. if (bp instanceof InstantiationAwareBeanPostProcessor) {
  23. // 执行后置处理器InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法
  24. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
  25. pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
  26. if (pvs == null) {
  27. return;
  28. }
  29. }
  30. }
  31. }
  32. if (needsDepCheck) {
  33. checkDependencies(beanName, mbd, filteredPds, pvs);
  34. }
  35. }
  36. ....省略
  37. // 为属性赋值
  38. if (pvs != null) {
  39. applyPropertyValues(beanName, mbd, bw, pvs);
  40. }
  41. }
1.1.1.2 initializeBean方法
  1. protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
  2. if (System.getSecurityManager() != null) {
  3. AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
  4. invokeAwareMethods(beanName, bean);
  5. return null;
  6. }, getAccessControlContext());
  7. }
  8. else {
  9. // 处理Aware接口
  10. invokeAwareMethods(beanName, bean);
  11. }
  12.  
  13. Object wrappedBean = bean;
  14. if (mbd == null || !mbd.isSynthetic()) {
  15. // 后置处理器触发postProcessBeforeInitialization方法
  16. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  17. }
  18.  
  19. try {
  20. // 执行初始化方法
  21. invokeInitMethods(beanName, wrappedBean, mbd);
  22. }
  23. catch (Throwable ex) {
  24. throw new BeanCreationException(
  25. (mbd != null ? mbd.getResourceDescription() : null),
  26. beanName, "Invocation of init method failed", ex);
  27. }
  28. if (mbd == null || !mbd.isSynthetic()) {
  29. // 后置处理器触发postProcessAfterInitialization方法
  30. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  31. }
  32.  
  33. return wrappedBean;
  34. }

其它:

SpringBoot_run()启动流程
SpringApplication实例初始化:
a)、根据classpath里面是否存在特征类(org.springframework.web.context.ConfigurableWebApplicationCobtext)来决定创建为web应用使用ApplicationContext类型,还是标准Standalone应用使用的ApplicationContext类型。
b)、使用SpringFactoriesLoader在classpath中查找并加载所有可用的ApplicationContextInitiazier
c)、使用SpringFactoriesLoader在classpath中查找并加载所有可用的ApplicationListener
d)、推断并main方法的定义类

SpringApplication实例初始化完成,遍历SpringFactoriesLoader可以找到并加载的SpringApplicationRunListnner,调用他们的start()方法。

创建并配置当前SpringBoot应用将要使用的Envrioment(包括配置要使用的PropertySource以及Profile)

遍历调用所有SpringApplicationRunListener的environmentPrepared()的方法——即通知【run监听器SpringBoot应用的使用环境已经搭建完成】

创建对应类型的ApplicationContext,根据条件决定是否添加ShutdownHook,决定是否使用自定义的BeanNameGenerator、ResourceLoader。将之前准备好的Enviroment设置给创建好的ApplicationContext使用

完成创建ApplicationContext,通过SpringFactoriesLoader查找并加载classpath中所有可用的ApplicationContextInitializer的Initialize()方法来对ApplicationContext进行进一步的处理

遍历所有的SpringApplicationRunListenner的contextPrepared()方法,通知【run监听器】ApplicationContext已经准备好了。

将之前通过@EnableAutoConfiguration获取的所有配置以及其他形式的IOC容器配置加载到已经准备完毕的ApplicationContext

遍历所有的SpringApplicationRunListener的contextLoaded()方法,通知【run监听器和ApplicationContext装填完毕】

调用ApplicationContext的refresh()——完成填充IOC容器

查找当前ApplicationContext中是否注册有CommandLineRunner,如果有,则遍历执行它们。

遍历执行SpringApplicationRunListener的finished()。
——启动完毕
————————————————

原文链接:https://blog.csdn.net/hackerHL/article/details/78270780

原文链接:https://blog.csdn.net/u010811939/article/details/80592461

SpringBoot启动过程原理(转)的更多相关文章

  1. SpringBoot启动过程原理

    最近这两年springboot突然火起来了,那么我们就来看看springboot的运行原理. 一.springboot的三种启动方式: 1.运行带有main方法的2.通过命令 Java -jar命令3 ...

  2. Spring Boot 学习笔记一(SpringBoot启动过程)

    SpringBoot启动 Spring Boot通常有一个名为*Application的入口类,在入口类里有一个main方法,这个main方法其实就是一个标准的java应用的入口方法. 在main方法 ...

  3. Tomcat启动过程原理详解 -- 非常的报错:涉及了2个web.xml等文件的加载流程

    Tomcat启动过程原理详解 发表于: Tomcat, Web Server, 旧文存档 | 作者: 谋万世全局者 标签: Tomcat,原理,启动过程,详解 基于Java的Web 应用程序是 ser ...

  4. SpringBoot启动流程原理解析(二)

    在上一章我们分析了SpingBoot启动流程中实例化SpingApplication的过程. return new SpringApplication(primarySources).run(args ...

  5. (四)SpringBoot启动过程的分析-预处理ApplicationContext

    -- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇(三)SpringBoot启动过程的分析-创建应用程序上下文,本文将分析上下文创建完毕之后的下一步操作:预处理上下文容器. 预处理上下文 ...

  6. (三)SpringBoot启动过程的分析-创建应用程序上下文

    -- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇(二)SpringBoot启动过程的分析-环境信息准备,本文将分析环境准备完毕之后的下一步操作:ApplicationContext的创 ...

  7. (一)SpringBoot启动过程的分析-启动流程概览

    -- 以下内容均基于2.1.8.RELEASE版本 通过粗粒度的分析SpringBoot启动过程中执行的主要操作,可以很容易划分它的大流程,每个流程只关注重要操作为后续深入学习建立一个大纲. 官方示例 ...

  8. (五)SpringBoot启动过程的分析-刷新ApplicationContext

    -- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇[(四)SpringBoot启动过程的分析-预处理ApplicationContext] (https://www.cnblogs.co ...

  9. springboot启动过程(1)-初始化

    1   springboot启动时,只需要调用一个类前面加了@SpringBootApplication的main函数,执行SpringApplication.run(DemoApplication. ...

随机推荐

  1. .NET细节知识总结,不断更新

    1.catch (Exception)和catch (Exception e) Exception 类包含许多子类 程序执行的时候要将每一个类都搜索一遍 以找到符合的异常类 这样是蛮消耗资源的 影响效 ...

  2. time() 函数时间不同步问题

    1.时区设置问题 处理方法:编辑php.ini  搜索 “timezone” 改写为 PRC 时区 2.服务器时间不同步 处理方法:设置服务器时间和本地时间进行同步

  3. scratch少儿编程第一季——04、想要做到有的放矢,瞄准方向很重要

    各位小伙伴大家好: 上期我们学习了动作模块的前面三个指令,今天我们继续学习下面的5个指令. 首先来看第一个(控制方向): 面向90方向默认就是屏幕的右边. 点击白色文本框上面的▼可以打开下拉菜单. 大 ...

  4. 1.ASP.NET Core Docker学习-Docker介绍与目录

    Docker的优点: 1节约时间,快速部署和启动 2节约成本 3标准化应用发布 4方便做持续集成 5可以用Docker做为集群中的轻量主机或节点 6方便构建基于SOA或者微服务架构 的系统 学习目录: ...

  5. CSS之cursor用法

    cursor: url('~ROOT/shared/assets/image/vn-text-cursor-31-49.png') 22 22, nw-resize; 另外还有一个 cursor: g ...

  6. Intellij IDEA集成JProfiler性能分析神器

    环境 JProfiler 17.1.3(IDEA插件) JProfiler 9.2(可执行软件) IntelliJ IDEA 2017.2.5 下载 下载JProfiler(IDEA)插件 方式1: ...

  7. hdu 1114需要装满的完全背包 重点是背包初始化的问题

    .,. 最近在看背包九讲 所以就刷了一下背包的题目 这道题目是一个典型的完全背包问题 而且要求满包 在这里 我就简单整理一下背包初始化问题吧 对于没有要求满包的问题 也就是背包可以不取满的问题 在背包 ...

  8. (十)mybatis之缓存

    一.缓存的意义 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)去查询,从缓存中进行查询,从而提高查询效率,解决了高并发系统的性能问题. 二.mybatis ...

  9. vue引入警告:There are multiple modules with names that only differ in casing. This can lead to unexpected behavior when compiling on a filesystem with other case-semantic. Use equal casing. Compare these

    在写vue项目的时候 当我使用 : import dataSource from '../overseaProduct/house/dataSource'; 引入dataSource文件的时候:控制台 ...

  10. tf 2.0

    tf.function和Autograph使用指南-Part 1 "Keras之父发声:TF 2.0 + Keras 深度学习必知的12件事" Effective TensorFl ...