Springboot How to Get Context ApplicationContext

  • 2021-12-13 07:50:46
  • OfStack

The directory Springboot obtains the application context ServletWebServerApplicationContext extended function AnnotationConfigServletWebServerApplicationContext of the context ApplicationContextspringboot

Springboot Get Context ApplicationContext

One scenario encountered in the project is by getting the context and then getting the specific bean. I encountered a lot of pits here, so I left this article and made a record.


import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
 
@Component
public class SpringContextUtil implements ApplicationContextAware {
    /**
     *  Context object instance 
     */
    private static ApplicationContext applicationContext;
 
    @Autowired
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
 
    /**
     *  Get applicationContext
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
 
    /**
     *  Pass name Get  Bean.
     * @param name
     * @return
     */
    public static Object getBean(String name){
        return getApplicationContext().getBean(name);
    }
 
    /**
     *  Pass class Get Bean.
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz){
        return getApplicationContext().getBean(clazz);
    }
 
    /**
     *  Pass name, As well as Clazz Returns the specified Bean
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }
}

Looking at the above code, we can see that in the tool class, 1 declares a static variable of ApplicationContext type at the beginning, but because the static variable cannot be managed by Spring container, 1 can't get a specific bean with normal getter and setter methods at the beginning. Practice has proved that it is necessary to add @ Autowired annotation on setter method of this variable and remove static keyword in setter method. The injection of a specific bean can be realized.

Application Context of springboot

The springboot context has two

ServletWebServerApplicationContext AnnotationConfigServletWebServerApplicationContext (Inherit above)

ServletWebServerApplicationContext

This class belongs to spring-boot-2. 1.1 Release. jar, which is derived from the birth of springboot and a subclass of Application, the application context of spring framework.

It is useless to say more, show me code

Extended functionality

First of all, let's look at 1. What does this class do and what is the value of existence?


    private volatile WebServer webServer;
 @Override
 protected void onRefresh() {
  super.onRefresh();
  try {
   createWebServer();
  }
  catch (Throwable ex) {
   throw new ApplicationContextException("Unable to start web server", ex);
  }
 }

There is an WebServer member variable in this class. Let's think about it with our toes. It should also be known that this is actually an web service object, and it can basically be guessed that it is related to tomcat (of course, it can also be other web servers, such as jetty)

Then we found the onRefresh method, which I believe is no stranger to us. This is one of the hook methods in the spring core refresh method (that is, it indicates that all the configured bean have been loaded at this time) to create the WebServer object


 @Override
 protected void finishRefresh() {
  super.finishRefresh();
  WebServer webServer = startWebServer();
  if (webServer != null) {
   publishEvent(new ServletWebServerInitializedEvent(webServer, this));
  }
 }

We also found that finishRefresh exists in this class. If you think about it carefully, this is also a hook method in the spring core # refresh method. (However, this method is special because it is the last step in the refresh method, which instantiates all beandefinition objects in the spring container.)

First of all, praise one. This is very clever. It calls super. finishRefresh (), and does not discard the logical function of the parent class (this is in polymorphism, I believe some people will make mistakes. It was originally an extended function, but it was rewritten directly and discarded the method of the parent class. Of course, spring framework development bosses will definitely not make such mistakes, right!)

The second point comes, that is, startWebServer, that is, after spring is instantiated, web service will be started.

AnnotationConfigServletWebServerApplicationContext

Under Summary 1:

First of all, this class is the implementation class for springboot to start running run () to create ApplicationContext, but unfortunately, this class does not have a strong substantive extension.

** The only function is to have the function of loading configuration classes through annotations, that is, like AnnotationConfigApplication1, except that the running start of springboot has already loaded bean classes through annotations **

(Although it is chicken ribs, it is also in line with spring's 1-way style of creating classes, that is, each class is highly cohesive, that is, each class has other extended functions besides the functions of the parent class. Even if it is abandoned before it is created, it still can't prevent spring development bosses from creating this class, haha)


Related articles: