Note: The spring Boot version of this series is 2.1.1.release.
Start the
Importing and starting a SpringBoot project is very simple. After maven imports the JAR package, a simplest SpringBoot project requires only one comment and one line of code.
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(DemoApplication.class); springApplication.run(args); }}Copy the code
SpringApplication has a lot of properties, and we can assign attributes to member variables using the set method before run, or we can assign attributes to variables using the builder pattern, which is essentially the same.
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { new SpringApplicationBuilder(DemoApplication.class) .build() .run(args); }}Copy the code
instantiation
SpringApplication->SpringApplication(): this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); / / set the servlet environment enclosing webApplicationType = webApplicationType. DeduceFromClasspath (); / / a member variable initializers set ApplicationContextInitializer setInitializers ((Collection) getSpringFactoriesInstances ( ApplicationContextInitializer.class)); / / a member variable listeners to add listeners setListeners ((Collection) getSpringFactoriesInstances (ApplicationListener. Class)); / / set the main method in the class is given priority to application class enclosing mainApplicationClass = deduceMainApplicationClass ();Copy the code
GetSpringFactoriesInstances () method, and according to the Class called SpringFactoriesLoader. LoadFactoryNames () to get the spring configuration file. The fully qualified name of the factories, We then use reflection to instantiate and finally return a List collection.
The listener works just like the Tomcat listener in that it handles events when the lifecycle changes.
Preface:
- LoadFactoryNames method of the SpringFactoriesLoader
- Listeners in Tomcat
Run the listener class SpringApplicationRunListeners
Once the instantiation is complete, call the run() method
SpringApplication->run(): / / getRunListeners (args) get the configuration file to specify / / org. Springframework. Boot. SpringApplicationRunListener properties SpringApplicationRunListeners listeners = getRunListeners(args); // Note that all listeners under the run method are listeners.Copy the code
GetRunListeners (args) from spring. Factories in running listener, only in the SpringBoot EventPublishingRunListener, just as its name implies is associated with the release of the event, Finally encapsulated into SpringApplicationRunListeners class to return.
SpringApplicationRunListeners->starting():
for (SpringApplicationRunListener listener : this.listeners) {
listener.starting();
}
EventPublishingRunListener->starting():
this.initialMulticaster.multicastEvent(
new ApplicationStartingEvent(this.application, this.args));
SimpleApplicationEventMulticaster->multicastEvent():
multicastEvent(event, resolveDefaultEventType(event));
Copy the code
Note that the event type is ApplicationStartingEvent, which is a subclass of the abstract SpringApplicationEvent class. In fact, all event classes of SpringBoot are subclasses of SpringApplicationEvent.
SimpleApplicationEventMulticaster->multicastEvent(): ApplicationStartingEvent (final ApplicationListener<? > listener : getApplicationListeners(event, type)) { invokeListener(listener, event); } SimpleApplicationEventMulticaster->invokeListener(): doInvokeListener(listener, event); SimpleApplicationEventMulticaster->doInvokeListener(): listener.onApplicationEvent(event);Copy the code
The SpringBoot listener in this example is shown below
Whether listeners support event types is ultimately determined by supportsEvent(), as shown in the following flowchart
Listener classes all need to implement the ApplicationListener interface, whose generics are ApplicationEvent or subclasses of it, as shown in the figure.
Custom listener classes
Appendix: banner
So in the startup method we notice that we have a line of code that says Banner printedBanner = printBanner(environment); (Forget the previous process for a moment.)
SpringApplication->printBanner(): / / the default in the console print return bannerPrinter. Print (environment, enclosing mainApplicationClass, System. Out); SpringApplicationBannerPrinter->print(): Banner banner = getBanner(environment); banner.printBanner(environment, sourceClass, out); SpringApplicationBannerPrinter->getBanner(): banners.addIfNotNull(getImageBanner(environment)); banners.addIfNotNull(getTextBanner(environment));Copy the code
GetImageBanner () to obtain the spring configuration file. The banner. Image. The location path set, if not, GIF, bannner. JPG, bannner. PNG in the resources directory. GetTextBanner () gets the path set by spring.banner. Location in the configuration file. If not, try reading bannner.txt in the resources directory. Print either method if it has one, or print the default banner (the SpringBoot logo) if it does not.
You can also set the font, color, version number and other attributes for Bannner. For details, you can study the source code (located in ResourceBanner->printBanner()).