The ApplicationContext of the Spring core family

Hello, everyone. From today, MY brother is going to launch the blog of Spring series. I hope you enjoy it. In fact, I don’t need to introduce more about Spring. Those who have done Web development basically use Spring, including the fashionable Spring Cloud microservice architecture, which is actually based on Spring Boot. Spring Boot is still the traditional three-piece set. Instead of configuring beans by the user, the beans are automatically configured, and Spring Boot has time to publish a series of blogs. This is the first installment of Spring. Let’s start with some basic, OK, routines.

  1. Resource interface in Spring.
  2. The BeanFactory and ApplicationContext
  3. WebApplicationContext

1. Resource interface in Spring.

In fact, for many business development programmers, this interface is relatively unfamiliar, we know that the container is initialized directly when specifying the file path, and then the container is initialized. This Resource interface is provided by Spring, which provides stronger access to the underlying resources for the application. This is much better than the JDK’s own File and URL classes. List the following class structure:

Resource res =new ServletContectResource(/WEB-INF/classes/spring/application.xml);
Copy the code

When you use a different Resource type, you must use the corresponding Resource class. This is a bit of a hassle. Can you use an unrealistic Resource class? Can a resource be accessed only by a special identification of its address? With a framework as great as Spring, of course it can. Spring not only identifies different resource types with resource address prefixes such as “classpath:” and “file”, but also supports Ant style wildcard resource addresses. Spring uses the Resource loader internally to select the appropriate Resource implementation class based on the different Resource paths. Avoided consumers choose their own implementation classes.

1.1 Resource Address expression

Let’s take a look at some of Spring’s built-in resource prefixes:

  • ? : Matches a character in the file name.
  • *: matches any character that the file matches.
  • ** : matches multi-level paths.

Without giving specific examples, Ant style wildcards are all too common.

1.2 Resource loader

public class GaoshiApplication {

	public static void main(String[] args) throws IOException {

		PathMatchingResourcePatternResolver resolver=new PathMatchingResourcePatternResolver();
		Resource[] res =resolver.getResources("file:/Users/zdy/Desktop/sql.txt");
		for (Resource  resource : res){
			System.out.println(resource.getDescription()+"--"+resource.getFilename()); } SpringApplication.run(GaoshiApplication.class, args); }}Copy the code
Output: URL (file: / Users/zdy/Desktop/SQL. TXT] -- SQL. TXTCopy the code

Well, actually, this section why want to tell everyone about the Resource and PathMatchingResourcePatternResolver Resource loaders, a lot of people may feel useless, anyway, the Spring inside their use is finished, it’s ok with me. In fact, it is not true, old iron, internal use of Spring, first of all, know the underlying principle is not good? Second, if you have a configuration file in your classpath and want to load it in code (although this is rare), you can use the resource loader provided by Spring. The loader is handy, loading resources directly based on prefixes and supporting Ant wildcards. Impressive, you say.

2. The BeanFactory and ApplicationContext

2.1 the BeanFactory

BeanFactory, which many of you have heard of, but have never used, is used to start the container using an implementation of the ApplicationContext, so the BeanFactory has become obsolete, let alone its implementation class. Talk about the features:

  1. BeanFactory is lazy-loaded. If a property of the Bean is not injected, the BeanFacotry is loaded and does not throw an exception until the first use of the getBean method. The ApplicationContext initializes itself as a check, which helps check whether the dependent properties are injected. So generally we choose to use ApplicationContext.
  2. ApplicationContext is derived from the BeanFactory and provides more power. ApplicationContext is usually used

Here’s an example of initializing a BeanFactory:

// Call the resource loader to load the Spring configuration file
		PathMatchingResourcePatternResolver resolver=new PathMatchingResourcePatternResolver();
		Resource res =resolver.getResource("classpath:/application.xml");
		
		// Create the BeanFactory implementation class provided by Spring by default
		DefaultListableBeanFactory bf =new DefaultListableBeanFactory();
		
		//BeanDefinition reader, which reads resources into containers
		XmlBeanDefinitionReader reader =new XmlBeanDefinitionReader(bf);
		
		// Read resources into the container
		reader.loadBeanDefinitions(res);
		
		// The container can be initialized to fetch beans.
		bf.getBean("...");
Copy the code

As you can see, the code is cumbersome and verbose. BeanFactory’s functionality is still relatively weak, so we should understand it.

2.2 ApplicationContext

This ApplicationContext is what is often referred to as the Spring container. Since it is relatively important, a rough class inheritance diagram is listed:

  • ApplicationEventPublisher: let the container has release events application context.
  • ResourcePatternResolver: Implements a resource-loader-like feature that recognizes a specific prefix plus an Ant style path and loads it into the container.
  • LifeCycle: manages the LifeCycle of beans in a container.
  • ConfigurableApplicationContext: mainly added the refresh () and close () method, let the ApplicationContext useful start, relationships and refresh the function of the context.
  • ClassPathXmlApplicationContext with FileSystemXmlApplicationContext: Spring ApplicationContext of two commonly used implementation class, the former is the default from the classpath loading configuration file, The latter is loaded from the file system. Then initialize an ApplicationContext and see:
ApplicationContext ac =new ClassPathXmlApplicationContext("application.xml");
ApplicationContext ac =new FileSystemXmlApplicationContext(/User/Desktop/application.xml);
Copy the code

ClassPathXmlApplicationContext if there is no default is the classpath: prefix FileSystemXmlApplicationContext if no prefix is the default file:

Then say a, not only can the Spring container through the XML file to initialize, @ Configuration annotation should all know, is also registered Bean with, of course, Spring also provides a corresponding AnnotationConfigApplicationContext.

ApplicationContext context =new AnnotationConfigApplicationContext(Config.class);
Copy the code

The Config class is the one we added @Configuration to.

3. WebApplicationContext

Actually, WebApplicationContext is also ApplicationContext, so why separate it out? Because it’s important. WebApplicationContext is Spring specifically for Web applications. It allows initialization to be done by loading configuration files from a path relative to the Web root. WebApplicationContext and ServletContext are available to each other. In non-Web applications, beans have only singleton and Prototype scopes, but WebApplicationContext adds three new scopes for beans: Request, Session, and Global Session. Take a look at the class inheritance diagram:

The most core the XmlWebApplicationContext and AnnotationConfigWebApplicationContext, everyone should guess guessed, is an XML Configuration, one is @ the Configuration Configuration.

So let’s talk about how WebApplicationContext and ServletContext get each other, it’s really easy, in WebApplicationContext there’s a ServletContext member variable, just get. There is a writable attrbute in the ServletContext, also directly get.. And Spring provides a WebApplicationContextUtils to encapsulate the attribute to death.

Is called directly the ServletContext. GetAttribute (ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
        return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
    }
Copy the code

If you have done any Web work, you can either configure a ContextLoaderListener in web.xml or configure a LoaderServlet that starts itself. It’s actually a little bit easier, so LET me show the ContextLoaderListener.

  <! Load the spring container -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/applicationContext-*.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
Copy the code

It would be easy to start the Spring container from the @Configuration class instead of an XML file.

  <context-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
  </context-param>
  <! Load the spring container -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>com.zdy.Configuration</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
Copy the code

Configure a ApplicationContext to AnnotationConfigWebApplicationContext contextClass parameters, then the contextConfigLocation not specify XML configuration file location, Instead, specify the location of the Configuration class. With respect to OK.

Finally, it is important to note that due to the Spring container’s built-in Log4j functionality, users can directly place Log4j configuration files in the classpath and this will work. However, if they are not in the classpath, You need to manually specify the location of the file in web.xml and start the Log4J listener, which I won’t demonstrate here. Note that the Log4J listener or servlet must precede the Spring container listenier or servlet. Don’t ask why. That’s the rule. But you don’t use this very often, so I’ll just mention it.

conclusion

Well, as you can see, I prefer to use Spring when talking about it. The underlying principles of Spring are not designed much. Spring is the supreme framework, I think the first macro use of the first clear. We’ll have a chance to talk a little bit more about the underlying implementation later. I hope you will pay more attention to the upcoming Spring series. Over,Have a good day .