Spring Boot Source Analysis (i) Springapplication.run (i.)

Source: Internet
Author: User
Tags addall

Springapplication.run (Main.class, args);

Let's start with this method:

 Public Static Configurableapplicationcontext Run (class<?> primarysource, String ... args) {  return run (  New class<?>[] {primarysource}, args);}

Configurableapplicationcontext this interface, familiar with the spring source of children's shoes will certainly have a sense of intimacy

As for the unfamiliar children's shoes ... I might open another spring hole in the future.

This is not covered in detail here.

Back to this method itself:

The method content is simple and points to another run method:

 Public Static Configurableapplicationcontext Run (class<?>[] primarysources, string[] args) {  returnNew  springapplication (primarysources). Run (args);

First, a Springapplication object is created.

It then points to a new run method.

But before we look at the next run method, in order,

Let's take a look at this construction method of Springapplication:

 Public Springapplication (class<?> ...primarysources) {  this (null, primarysources);}
 PublicSpringapplication (Resourceloader Resourceloader, class<?>... primarysources) {//set the Resourceloader property to a parameter with the same name     This. Resourceloader =Resourceloader; //determines whether the primarysources is empty, and if null, throw new IllegalArgumentException ("primarysources must not is null");Assert.notnull (primarysources, "primarysources must not is null"); //To determine if primarysources is not empty, inject primarysource into the property primarysources     This. primarysources =NewLinkedhashset<>(Arrays.aslist (primarysources)); //Set Property Webapplicationtype//about Deducewebapplicationtype () This method, for the moment, press no table, the following will talk about     This. Webapplicationtype =Deducewebapplicationtype (); //set the initializers and listeners two properties by setter method//as to what he has set up, he'll talk about it later .Setinitializers (Collection) getspringfactoriesinstances (Applicationcontextinitializer.class)); Setlisteners (Collection) getspringfactoriesinstances (Applicationlistener.class)); //Finally, set the property Mainapplicationclass//Deducemainapplicationclass () This method we'll talk about later.     This. Mainapplicationclass =Deducemainapplicationclass ();}

A brief summary is:

A round of initialization was carried out;

Set up a whole bunch of parameters that don't know what the hell to use

After the object has been generated, let's take a look at this run method ...

Wait a minute

In the spirit of inquiring, we will first resolve the unresolved issues:

About Deducewebapplicationtype (); This method:

PrivateWebapplicationtype Deducewebapplicationtype () {//Here are three parameters//full class name of Reactive_web_environment_class:dispatcherhandler//full class name of Mvc_web_environment_class:dispatcherservlet//web_environment_classes: Is a string[], there are two items://one is the full class name of the servlet, one is the full class name of the Configurablewebapplicationcontext//The ispresent method, simply speaking, is to determine if the class exists, to return true if it exists, and vice versa to return False .//Therefore, the Spring boot project maven dependency can not be done casually, can not add more and not less. //Spring boot will determine the nature of your project based on your dependencies .//There will be a lot of this in the back, depending on the difference to determine the place//and then say this webapplicationtype://is an enumeration class with three items in it://Servlet,reactive,none//just a logo to indicate whether you are a servlet project, a reactive project, or a non-networked (none) Project    if(Classutils.ispresent (Reactive_web_environment_class,NULL)                &&! Classutils.ispresent (Mvc_web_environment_class,NULL)) {        returnwebapplicationtype.reactive; }     for(String classname:web_environment_classes) {if(! Classutils.ispresent (ClassName,NULL)) {            returnWebapplicationtype.none; }    }    returnWebapplicationtype.servlet;}

So, in the previous constructor:

This.webapplicationtype = Deducewebapplicationtype ();

is based on your jar dependency, which sets the type of the project

Then there are our two setter methods:

Setinitializers and Setlisteners

You might be wondering why there are constructors and how to use setter methods.

The answer is simple, because the setter method is obviously not that simple:

this.xx = XX;

It's just this stuff.

Although, it is not complicated to where to go:

 Public void setinitializers (Collectionextends applicationcontextinitializer<?>> initializers) {    thisnew arraylist<>();      This . Initializers.addall (initializers);}

The above code shows that this initializers is a ArrayList that puts all the items in the itializers in your parameters. on the sauce;

 Public void extends Applicationlistener<?>> listeners) {    thisnew arraylist<>();      This . Listeners.addall (listeners);}

In addition to the variable name and parameter generics, it seems to be exactly the same as the one above = =

Two setter methods are done, but the parameters of these two setter methods in the constructor are determined by a method called Getspringfactoriesinstances.

Next we look at this method:

private <T> collection<t> getspringfactoriesinstances (class<t> type) {      Returnnew class<?>[] {});}
Private<T> collection<t> getspringfactoriesinstances (class<t> type, class<?>[] parametertypes, Object ... args) {//gets the class loader for the current threadClassLoader ClassLoader =Thread.CurrentThread (). Getcontextclassloader (); //use names and ensure unique to protect against duplicates (this is an official note that means to make sure that duplicates are not duplicated with different names)//As for this loadfactorynames method, it is simply to find all class names of all corresponding factory classes based on the class object and ClassLoader of the interface or abstract class .set<string> names =NewLinkedhashset<>(Springfactoriesloader.loadfactorynames (Type, classLoader)); //as the name implies, Createspringfactoriesinstances is the example of creating a spring factory//The specific code of this method we wait to seelist<t> instances =createspringfactoriesinstances (Type, parametertypes, ClassLoader, args, names); //Simply put, this is a sequence. //In a little more detail, sort by the order value of the object//in more detail, wait till I open the Spring pit .//declare beforehand, this pit I may not necessarily open = =//This hole is too big.//write Spring is spring, say spring is winterAnnotationawareordercomparator.sort (instances); //after the order is finished, return back.     returninstances;}

So the above method, the actual focus is that createspringfactoriesinstances.

Again, in the above method, we call the Createspringfactoriesinstances method with five parameters:

Type: A Class object. In the previous constructor:

The Setinitializers method injects the Applicationcontextinitializer.class class object,

The Setlisteners method injects Applicationlistener.class as the class object.

Paramertertypes: a class array.

In the Getspringfactoriesinstances (class<t> type) method, he injects an empty array.

ClassLoader: Class loader. method is the class loader for the thread.

Args: a bunch of parameters.

In the Getspringfactoriesinstances (class<t> type) method, he injects null.

Names: a linkedhashset<string>

The full class name of all corresponding factory classes is found by the type and ClassLoader above

Okay, remember this, and here's how it looks:

Private<T> list<t>createspringfactoriesinstances (Class<T>type, Class<?>[] parametertypes, ClassLoader ClassLoader, object[] args, Set<String>names) {//Obviously, instances is the list we're going to go back to eventually.//In terms of this ArrayList, it's clear that every item in this list is related to names .list<t> instances =NewArraylist<>(Names.size ());  for(String name:names) {Try{//find class objects based on name and ClassLoader//so make sure the names here is different, otherwise the list will be duplicated. Class<?> Instanceclass =classutils.forname (name, ClassLoader); //briefly, see if type is a Instanceclass or interface. //If yes, go down, if not, error. assert.isassignable (type, instanceclass); //if the code executes to this, the description type is a superclass of instanceclass. //Parametertypes This shows the parameter type table of the Instanceclass constructorConstructor<?> Constructor =instanceclass. Getdeclaredconstructor (parametertypes); //To put it simply, it is to construct an instance of T with the constructor you just got, and args.//so args and parametertypes are one by one corresponding. //As already determined, type is the superclass or interface of the Instanceclass. //therefore this coercion type conversion is established. T instance =(T) Beanutils.instantiateclass (constructor, args); //Add this instance to the list at the beginning of the declaration.Instances.add (instance); } Catch(Throwable ex) {//If there is an error in front of you, then one more mistake.//Spring has always been so, error one after another//The end result is that no matter what the P is a big mistake, you have to quote a long list of mistakes//and then every time I look at the console ... Hey, big head.        Throw NewIllegalArgumentException ("Cannot instantiate" + Type + ":" +name, ex); }}//finally , back up the top list.    returninstances;}

In summary, the above approach is to create a class object for all the type's factory classes.

This is called Createspringfactoriesinstances

Back to the previous construction method:

Setinitializers ((Collection) getspringfactoriesinstances (Applicationcontextinitializer.class));

is to initialize the initializers as a collection of objects of all factory classes corresponding to Applicationcontextinitializer.class

Setlisteners ((Collection) getspringfactoriesinstances (Applicationlistener.class));

is to initialize the listeners as a collection of objects of all factory classes corresponding to Applicationlistener.class

At this point, the construction method is complete.

Then we look at the Run method ...

Look at a ghost, write so much, you look tired?

I'm tired anyway.

The rest of the next time.

Bye, ~~~~~~~~~.

Spring Boot Source Analysis (i) Springapplication.run (i.)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.