好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Springboot启动原理和自动配置原理解析

放本地文件夹都快吃土了,准备清理文件夹,关于Springboot的!

启动原理

?

1

2

3

4

5

6

7

8

@SpringBootApplication

public class Start {

 

     public static void main(String[] args) {

         SpringApplication.run(Start. class , args);

     }

 

}

SpringApplication

1、初始化

?

1

2

3

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {

         return ( new SpringApplication(primarySources)).run(args);

     }

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {

        this .sources = new LinkedHashSet(); //

        this .bannerMode = Mode.CONSOLE; // 控制banner

        this .logStartupInfo = true ; // 是否启动日志

        this .addCommandLineProperties = true ; // 读取命令行配置

        this .addConversionService = true ; //添加转换器

        this .headless = true ; //

        this .registerShutdownHook = true ; // 注册重启

        this .additionalProfiles = Collections.emptySet(); // 读取配置环境

        this .isCustomEnvironment = false ; // 是否是自定义环境

        this .lazyInitialization = false ; // 是否懒加载

        this .applicationContextFactory = ApplicationContextFactory.DEFAULT;

        this .applicationStartup = ApplicationStartup.DEFAULT; // ApplicationStartup DEFAULT = new DefaultApplicationStartup();

        this .resourceLoader = resourceLoader; // 资源加载器

        Assert.notNull(primarySources, "PrimarySources must not be null" );

        this .primarySources = new LinkedHashSet(Arrays.asList(primarySources)); // 主程序

        this .webApplicationType = WebApplicationType.deduceFromClasspath(); //  SERVLET||REACTIVE; 是servlet还是reactive环境

        // BootstrapRegistryInitializer

    this .bootstrapRegistryInitializers = new ArrayList( this .getSpringFactoriesInstances(BootstrapRegistryInitializer. class ));

        // ApplicationContextInitializer

    this .setInitializers( this .getSpringFactoriesInstances(ApplicationContextInitializer. class ));

    // ApplicationListener       

    this .setListeners( this .getSpringFactoriesInstances(ApplicationListener. class ));

        this .mainApplicationClass = this .deduceMainApplicationClass();

    }

注册 BootstrapRegistryInitializer

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

this .bootstrapRegistryInitializers = new ArrayList( this .getSpringFactoriesInstances(BootstrapRegistryInitializer. class ));

 

//

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {

         ClassLoader classLoader = this .getClassLoader();

         // 1、从配置文件读取名称加载

         Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));

         // 2、获取构造器实例

     List<T> instances = this .createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);

         // 3、排序

      AnnotationAwareOrderComparator.sort(instances);

         return instances;

}

 

// 1、加载配置

  private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {

         Map<String, List<String>> result = (Map)cache.get(classLoader);

         if (result != null ) {

             return result;

         } else {

             HashMap result = new HashMap();

 

             try {

                  //核心 从这里知道读取配置文件位置 默认

                 Enumeration urls = classLoader.getResources( "META-INF/spring.factories" );

         // ... 这里省略迭代器遍历注册

                 result.replaceAll((factoryType, implementations) -> {

                     return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));

                 });

         // 添加到缓存中,下次读取。根据类名读取

                 cache.put(classLoader, result);

                 return result;

             } catch (IOException var14) {

                 throw new IllegalArgumentException( "Unable to load factories from location [META-INF/spring.factories]" , var14);

             }

         }

     }

 

// 2、获取构造器实例

private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args, Set<String> names) {

         List<T> instances = new ArrayList(names.size());

         Iterator var7 = names.iterator();

 

         while (var7.hasNext()) {

             String name = (String)var7.next();

 

             try {

                 // 通过类名反射机制调用,读取Class<T> class

                 Class<?> instanceClass = ClassUtils.forName(name, classLoader);

                 Assert.isAssignable(type, instanceClass);

                 Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);

                 // 获取构造器实例

         T instance = BeanUtils.instantiateClass(constructor, args);

                 // 添加到构造器中

                 instances.add(instance);

             } catch (Throwable var12) {

                 throw new IllegalArgumentException( "Cannot instantiate " + type + " : " + name, var12);

             }

         }

     // 返回

         return instances;

     }

 

 

// 排序 通过debug这里调用的是Integer类型排序方法 List<Integer> list

   public static void sort(List<?> list) {

         if (list.size() > 1 ) {

             list.sort(INSTANCE);

         }

 

     }

配置文件

spring-boot:2.7.1.META-INF\spring.factorie

?

1

2

3

4

5

6

org.springframework.context.ApplicationContextInitializer=\

org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\

org.springframework.boot.context.ContextIdApplicationContextInitializer,\

org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\

org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\

org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

?

像 BootstrapRegistryInitializer

另外几个配置是从其他配置文件中读取的

例如

?

注册 ApplicationContextInitializer 、ApplicationListener

同  BootstrapRegistryInitializer 加载原理

2、调用run方法

核心

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

public ConfigurableApplicationContext run(String... args) {

         long startTime = System.nanoTime();

         DefaultBootstrapContext bootstrapContext = this .createBootstrapContext();

         ConfigurableApplicationContext context = null ;

         this .configureHeadlessProperty();

         SpringApplicationRunListeners listeners = this .getRunListeners(args);

         listeners.starting(bootstrapContext, this .mainApplicationClass);

 

         try {

             ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

             ConfigurableEnvironment environment = this .prepareEnvironment(listeners, bootstrapContext, applicationArguments);

             this .configureIgnoreBeanInfo(environment);

             Banner printedBanner = this .printBanner(environment);

             context = this .createApplicationContext();

             context.setApplicationStartup( this .applicationStartup);

             this .prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);

             // 加载所有注解使用的扫描的组件

         this .refreshContext(context);

         // 刷新

             this .afterRefresh(context, applicationArguments);

             Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);

             if ( this .logStartupInfo) {

                 ( new StartupInfoLogger( this .mainApplicationClass)).logStarted( this .getApplicationLog(), timeTakenToStartup);

             }

 

             listeners.started(context, timeTakenToStartup);

             this .callRunners(context, applicationArguments);

         } catch (Throwable var12) {

             this .handleRunFailure(context, var12, listeners);

             throw new IllegalStateException(var12);

         }

 

         try {

             Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);

             listeners.ready(context, timeTakenToReady);

             return context;

         } catch (Throwable var11) {

             this .handleRunFailure(context, var11, (SpringApplicationRunListeners) null );

             throw new IllegalStateException(var11);

         }

     }

所有组件经过 org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader 方法加载注册组件

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {

         AnnotationMetadata metadata = configClass.getMetadata();

         AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);

         ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);

         configBeanDef.setScope(scopeMetadata.getScopeName());

         String configBeanName = this .importBeanNameGenerator.generateBeanName(configBeanDef, this .registry);

         AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);

         BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);

         definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this .registry);

         // 在这里注册

     this .registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());

         configClass.setBeanName(configBeanName);

         if (logger.isTraceEnabled()) {

             logger.trace( "Registered bean definition for imported class '" + configBeanName + "'" );

         }

 

     }

org.springframework.beans.factory.support.DefaultListableBeanFactory

registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition())

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

@Override

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)

             throws BeanDefinitionStoreException {

 

         Assert.hasText(beanName, "Bean name must not be empty" );

         Assert.notNull(beanDefinition, "BeanDefinition must not be null" );

 

         if (beanDefinition instanceof AbstractBeanDefinition) {

             try {

                 ((AbstractBeanDefinition) beanDefinition).validate();

             }

             catch (BeanDefinitionValidationException ex) {

                 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,

                         "Validation of bean definition failed" , ex);

             }

         }

 

         BeanDefinition existingDefinition = this .beanDefinitionMap.get(beanName);

         if (existingDefinition != null ) {

             if (!isAllowBeanDefinitionOverriding()) {

                 throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);

             }

             else if (existingDefinition.getRole() < beanDefinition.getRole()) {

                 // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE

                 if (logger.isInfoEnabled()) {

                     logger.info( "Overriding user-defined bean definition for bean '" + beanName +

                             "' with a framework-generated bean definition: replacing [" +

                             existingDefinition + "] with [" + beanDefinition + "]" );

                 }

             }

             else if (!beanDefinition.equals(existingDefinition)) {

                 if (logger.isDebugEnabled()) {

                     logger.debug( "Overriding bean definition for bean '" + beanName +

                             "' with a different definition: replacing [" + existingDefinition +

                             "] with [" + beanDefinition + "]" );

                 }

             }

             else {

                 if (logger.isTraceEnabled()) {

                     logger.trace( "Overriding bean definition for bean '" + beanName +

                             "' with an equivalent definition: replacing [" + existingDefinition +

                             "] with [" + beanDefinition + "]" );

                 }

             }

             // 注册

             this .beanDefinitionMap.put(beanName, beanDefinition);

         }

         else {

             if (hasBeanCreationStarted()) {

                 // Cannot modify startup-time collection elements anymore (for stable iteration)

                 synchronized ( this .beanDefinitionMap) {

                     this .beanDefinitionMap.put(beanName, beanDefinition);

                     List<String> updatedDefinitions = new ArrayList<>( this .beanDefinitionNames.size() + 1 );

                     updatedDefinitions.addAll( this .beanDefinitionNames);

                     updatedDefinitions.add(beanName);

                     this .beanDefinitionNames = updatedDefinitions;

                     removeManualSingletonName(beanName);

                 }

             }

             else {

                 // Still in startup registration phase

                 this .beanDefinitionMap.put(beanName, beanDefinition);

                 this .beanDefinitionNames.add(beanName);

                 removeManualSingletonName(beanName);

             }

             this .frozenBeanDefinitionNames = null ;

         }

 

         if (existingDefinition != null || containsSingleton(beanName)) {

             resetBeanDefinition(beanName);

         }

         else if (isConfigurationFrozen()) {

             clearByTypeCache();

         }

     }

自动配置原理

该部分暂时找不到了,之前备份找不到了,先TODO下吧!喜欢的朋友参考下这篇文章: http://HdhCmsTesttuohang.net/article/267085.html

到此这篇关于Springboot启动原理和自动配置原理解析的文章就介绍到这了,更多相关Springboot启动原理和自动配置内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

原文链接:https://HdhCmsTestcnblogs测试数据/wuxin001/archive/2023/04/25/17351482.html

查看更多关于Springboot启动原理和自动配置原理解析的详细内容...

  阅读:10次