[JavaEE learning post 3] Analysis of the spring webmvc startup process-IoC container creation, bean initialization

concept

The IOC container is a container with dependency injection function. The IOC container is responsible for instantiating, locating, configuring the objects in the application and establishing the dependencies between these objects. The application does not need to directly new related objects in the code, the application is assembled by the IOC container.

Spring provides one of the most basic IoC container-BeanFactory, but this IoC container can provide relatively few functions, so we usually choose another-ApplicationContext (application context) as the IoC container. ApplicationContext is also inherited from BeanFactory, but is extended on the basis of BeanFactory interface.

in web.xml

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

This configuration is meant to add a listener to the Servlet, which needs to implement the ServletContextListener interface.

public interface ServletContextListener extends EventListener {
    
    
    void contextInitialized(ServletContextEvent var1);

    void contextDestroyed(ServletContextEvent var1);
}

Let's take a look at ContextLoaderListener, the initialization of WebApplicationContext is actually done by ContextListener.

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
    
    
    public ContextLoaderListener() {
    
    
    }

    public ContextLoaderListener(WebApplicationContext context) {
    
    
        super(context);
    }

    public void contextInitialized(ServletContextEvent event) {
    
    
        this.initWebApplicationContext(event.getServletContext());
    }

    public void contextDestroyed(ServletContextEvent event) {
    
    
        this.closeWebApplicationContext(event.getServletContext());
        ContextCleanupListener.cleanupAttributes(event.getServletContext());
    }
}

public void initWebApplicationContext(ServletContext servletContext)

public void initWebApplicationContext(ServletContext servletContext) 
    ......
    if(this.context == null) {
    
    
        this.context = this.createWebApplicationContext(servletContext);    //创建根上下文,在这之前会检查是否已经存在,如果存在则抛出IllegalStateExcpetion异常,跳到第22行
    }
    ......
    if(this.context instanceof ConfigurableWebApplicationContext) {
    
        
        ConfigurableWebApplicationContext err = (ConfigurableWebApplicationContext)this.context;
        if(!err.isActive()) {
    
    
            if(err.getParent() == null) {
    
    
                ApplicationContext elapsedTime = this.loadParentContext(servletContext);
                err.setParent(elapsedTime);
            }
        this.configureAndRefreshWebApplicationContext(err, servletContext);    //ApplicationContext上下文创建好后对其进行赋值和初始化,跳到第31行
        }
    }
    //将WebApplicationContext根上下文绑定到Web应用程序的ServletContext上.
    servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
    .....
     return this.context;
}
protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
    
    
    Class contextClass = this.determineContextClass(sc);    //判断使用什么样的类在Web容器中作为IoC容器,跳到第26行
    ......
}
protected Class<?> determineContextClass(ServletContext servletContext) {
    
    
    String contexClassName = servlet.getInitParameter(CONTEXT_CLASS_PARAM);    //读取web.xml中的配置<context-param>contextClass</context-param>
    //如果配置了需要使用的CONTEXT_CLASS,那就是用这个class,如果没有额外的配置,就是用默认的ContextClass也就是XmlWebApplicationContext.
}
//设置IoC容器的参数,并通过refresh启动容器的初始化
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc){
    
    
    String configLocationParam;
if(ObjectUtils.identityToString(wac).equals(wac.getId())) {
    
    
    configLocationParam = sc.getInitParameter("contextId");
    if(configLocationParam != null) {
    
    
        wac.setId(configLocationParam);
    } else {
    
    
        wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath()));
    }
}
    wac.setServletContext(sc);
    configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);    //contextConfigLocation,Spring根应用上下文重要的配置文件,很多bean的定义等等
    ......
    wac.refresh();    //启动容器的初始化
}

The specified IoC container with the configuration of web.xml specified

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

bean is defined in applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="JDBC" class="jdbc.StudentHomeworkJdbc" xml:id="JDBC1"></bean>
    <bean id="pool" class="jdbc.DatabasePool" xml:id="pool1"></bean>
</beans>

In this way, you can create an instance

ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
StudentHomeworkJdbc jdbc=(StudentHomeworkJdbc)applicationContext.getBean("JDBC");
jdbc.addHomework(homework);

Guess you like

Origin blog.csdn.net/Shadownow/article/details/105534478