SpringApplication construction analysis
1. Record BeanDefinition source
The spring container is empty at the beginning. Go to various sources to find the beanDefinition. These sources may be configuration classes or xml files. In the construction method, a main source will be obtained, which is the bootstrap class, and the beanDefinition will be obtained according to the bootstrap class.
2. Infer the application type
Determine the reference type based on the jar package
3. Record the ApplicationContext initializer
Expand the ApplicationContext
4. Record listener
Listen to important events
5. Infer the main startup class
Record the running main class.
SpringApplication run analysis
1. Get SpringApplicationRunListeners. The name is not obtained well. It is actually an event publisher
Publishes the application starting event and publishes the event at important nodes when the program starts
public static void main(String[] args) throws Exception{ // 添加 app 监听器 SpringApplication app = new SpringApplication(); app.addListeners(e -> System.out.println(e.getClass())); // 获取事件发送器实现类名 List<String> names = SpringFactoriesLoader.loadFactoryNames(SpringApplicationRunListener.class, A39_2.class.getClassLoader()); for (String name : names) { System.out.println(name); Class<?> clazz = Class.forName(name); Constructor<?> constructor = clazz.getConstructor(SpringApplication.class, String[].class); SpringApplicationRunListener publisher = (SpringApplicationRunListener) constructor.newInstance(app, args); // 发布事件 DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext(); publisher.starting(bootstrapContext); // spring boot 开始启动 publisher.environmentPrepared(bootstrapContext, new StandardEnvironment()); // 环境信息准备完毕 GenericApplicationContext context = new GenericApplicationContext(); publisher.contextPrepared(context); // 在 spring 容器创建,并调用初始化器之后,发送此事件 publisher.contextLoaded(context); // 所有 bean definition 加载完毕 context.refresh(); publisher.started(context); // spring 容器初始化完成(refresh 方法调用完毕) publisher.running(context); // spring boot 启动完毕 publisher.failed(context, new Exception("出错了")); // spring boot 启动出错 }
2. Encapsulate startup args
3. Prepare Environment to add command line parameters (*)
public static void main(String[] args) throws IOException { ApplicationEnvironment env = new ApplicationEnvironment(); // 系统环境变量, properties, yaml env.getPropertySources().addLast(new ResourcePropertySource(new ClassPathResource("step3.properties"))); env.getPropertySources().addFirst(new SimpleCommandLinePropertySource(args)); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } // System.out.println(env.getProperty("JAVA_HOME")); System.out.println(env.getProperty("server.port")); }
4. ConfigurationPropertySources processing (*)
Publish application environment has prepared events
public static void main(String[] args) throws IOException, NoSuchFieldException { ApplicationEnvironment env = new ApplicationEnvironment(); env.getPropertySources().addLast( new ResourcePropertySource("step4", new ClassPathResource("step4.properties")) ); ConfigurationPropertySources.attach(env); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } System.out.println(env.getProperty("user.first-name")); System.out.println(env.getProperty("user.middle-name")); System.out.println(env.getProperty("user.last-name")); } }
5. Env post-processing (*) through EnvironmentPostProcessorApplicationListener
application.properties, parsed by StandardConfigDataLocationResolver
spring.application.json
public class Step5 { public static void main(String[] args) { SpringApplication app = new SpringApplication(); app.addListeners(new EnvironmentPostProcessorApplicationListener()); /*List<String> names = SpringFactoriesLoader.loadFactoryNames(EnvironmentPostProcessor.class, Step5.class.getClassLoader()); for (String name : names) { System.out.println(name); }*/ EventPublishingRunListener publisher = new EventPublishingRunListener(app, args); ApplicationEnvironment env = new ApplicationEnvironment(); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> 增强前"); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } publisher.environmentPrepared(new DefaultBootstrapContext(), env); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> 增强后"); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } } private static void test1() { SpringApplication app = new SpringApplication(); ApplicationEnvironment env = new ApplicationEnvironment(); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> 增强前"); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } ConfigDataEnvironmentPostProcessor postProcessor1 = new ConfigDataEnvironmentPostProcessor(new DeferredLogs(), new DefaultBootstrapContext()); postProcessor1.postProcessEnvironment(env, app); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> 增强后"); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } RandomValuePropertySourceEnvironmentPostProcessor postProcessor2 = new RandomValuePropertySourceEnvironmentPostProcessor(new DeferredLog()); postProcessor2.postProcessEnvironment(env, app); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> 增强后"); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } System.out.println(env.getProperty("server.port")); System.out.println(env.getProperty("random.int")); System.out.println(env.getProperty("random.int")); System.out.println(env.getProperty("random.int")); System.out.println(env.getProperty("random.uuid")); System.out.println(env.getProperty("random.uuid")); System.out.println(env.getProperty("random.uuid")); } }
6. Bind spring.main to the SpringApplication object (*)
Assign the value in the configuration file to the default attribute value of SpringApplication
public class Step6 { // 绑定 spring.main 前缀的 key value 至 SpringApplication, 请通过 debug 查看 public static void main(String[] args) throws IOException { SpringApplication application = new SpringApplication(); ApplicationEnvironment env = new ApplicationEnvironment(); env.getPropertySources().addLast(new ResourcePropertySource("step6", new ClassPathResource("step6.properties"))); System.out.println(application); Binder.get(env).bind("spring.main", Bindable.ofInstance(application)); System.out.println(application); }
7. Print banner (*)
public class Step7 { public static void main(String[] args) { ApplicationEnvironment env = new ApplicationEnvironment(); SpringApplicationBannerPrinter printer = new SpringApplicationBannerPrinter( new DefaultResourceLoader(), new SpringBootBanner() ); // 测试文字 banner // env.getPropertySources().addLast(new MapPropertySource("custom", Map.of("spring.banner.location","banner1.txt"))); // 测试图片 banner // env.getPropertySources().addLast(new MapPropertySource("custom", Map.of("spring.banner.image.location","banner2.png"))); // 版本号的获取 System.out.println(SpringBootVersion.getVersion()); printer.print(env, Step7.class, System.out); } }
8. Create container
private static GenericApplicationContext createApplicationContext(WebApplicationType type) { GenericApplicationContext context = null; switch (type) { case SERVLET -> context = new AnnotationConfigServletWebServerApplicationContext(); case REACTIVE -> context = new AnnotationConfigReactiveWebServerApplicationContext(); case NONE -> context = new AnnotationConfigApplicationContext(); } return context; }
9. Prepare container release
application context initialized event
10.Load bean definition
Publish application prepared event
DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory(); AnnotatedBeanDefinitionReader reader1 = new AnnotatedBeanDefinitionReader(beanFactory); XmlBeanDefinitionReader reader2 = new XmlBeanDefinitionReader(beanFactory); ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanFactory); reader1.register(Config.class); reader2.loadBeanDefinitions(new ClassPathResource("b03.xml")); scanner.scan("com.itheima.a39.sub");
11, refresh container
Publish application started event
12, execute runner
Publish application ready Event
There is an exception, please publish application failed event
The above is the detailed content of What is the underlying startup process of Springboot?. For more information, please follow other related articles on the PHP Chinese website!

JVM'sperformanceiscompetitivewithotherruntimes,offeringabalanceofspeed,safety,andproductivity.1)JVMusesJITcompilationfordynamicoptimizations.2)C offersnativeperformancebutlacksJVM'ssafetyfeatures.3)Pythonisslowerbuteasiertouse.4)JavaScript'sJITisles

JavaachievesplatformindependencethroughtheJavaVirtualMachine(JVM),allowingcodetorunonanyplatformwithaJVM.1)Codeiscompiledintobytecode,notmachine-specificcode.2)BytecodeisinterpretedbytheJVM,enablingcross-platformexecution.3)Developersshouldtestacross

TheJVMisanabstractcomputingmachinecrucialforrunningJavaprogramsduetoitsplatform-independentarchitecture.Itincludes:1)ClassLoaderforloadingclasses,2)RuntimeDataAreafordatastorage,3)ExecutionEnginewithInterpreter,JITCompiler,andGarbageCollectorforbytec

JVMhasacloserelationshipwiththeOSasittranslatesJavabytecodeintomachine-specificinstructions,managesmemory,andhandlesgarbagecollection.ThisrelationshipallowsJavatorunonvariousOSenvironments,butitalsopresentschallengeslikedifferentJVMbehaviorsandOS-spe

Java implementation "write once, run everywhere" is compiled into bytecode and run on a Java virtual machine (JVM). 1) Write Java code and compile it into bytecode. 2) Bytecode runs on any platform with JVM installed. 3) Use Java native interface (JNI) to handle platform-specific functions. Despite challenges such as JVM consistency and the use of platform-specific libraries, WORA greatly improves development efficiency and deployment flexibility.

JavaachievesplatformindependencethroughtheJavaVirtualMachine(JVM),allowingcodetorunondifferentoperatingsystemswithoutmodification.TheJVMcompilesJavacodeintoplatform-independentbytecode,whichittheninterpretsandexecutesonthespecificOS,abstractingawayOS

Javaispowerfulduetoitsplatformindependence,object-orientednature,richstandardlibrary,performancecapabilities,andstrongsecurityfeatures.1)PlatformindependenceallowsapplicationstorunonanydevicesupportingJava.2)Object-orientedprogrammingpromotesmodulara

The top Java functions include: 1) object-oriented programming, supporting polymorphism, improving code flexibility and maintainability; 2) exception handling mechanism, improving code robustness through try-catch-finally blocks; 3) garbage collection, simplifying memory management; 4) generics, enhancing type safety; 5) ambda expressions and functional programming to make the code more concise and expressive; 6) rich standard libraries, providing optimized data structures and algorithms.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

SublimeText3 Chinese version
Chinese version, very easy to use

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

Atom editor mac version download
The most popular open source editor
