解读Spring源代码(Web MVC)

  Spring的Web启动是个神马原理呢,看了一天源代码,晚上自己动手写个Demo。Spring启动web容器时通过Servlet或者定义一个Listener来初始化自己的Ioc容器,还有一个DispatchServlet来给你的ActionBean中注入你所需要的类。

我定义一个类WebLoader 来继承org.springframework.web.context.ContextLoader并重写他的createWebApplicationContext方法,我只改源代码中的一句话    wac.setConfigLocation(sc.getInitParameter(“xcontextConfigLocation”));

这个wac是ConfigurableWebApplicationContext

Spring源代码中默认的是contextConfigLocation参数你每次需要这样定义

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

现在我改了以后

Spring就在web.xml中找下面这个东西

<context-param>
<param-name>xcontextConfigLocation</param-name>
<param-value>WEB-INF/c2.xml</param-value>
</context-param>

c1.xml中定义一句话<bean id=”b1″ class=”com.Bean1″/>

c2.xml中定义一句话<bean id=”b2″ class=”com.Bean2″/>

然后我定义一个Servlet在web容器启动时自动加载

<servlet>
<servlet-name>Context</servlet-name>
<servlet-class>com.InitWeb</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>

这个servlet的Init方法为

@Override
public void init() throws ServletException {
System.out.println(“Hei i am init”);
ServletContext sc = getServletContext();
WebApplicationContext parent=WebApplicationContextUtils.getWebApplicationContext(sc);
WebLoader loader=new WebLoader();
WebApplicationContext  wac=loader.createWebApplicationContext(sc, parent);
System.out.println(wac.getBeanDefinitionCount());
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
super.init();
}

我在jsp中写

<%
WebApplicationContext wac = WebApplicationContextUtils
.getRequiredWebApplicationContext(getServletContext());
Bean1 b1 = (Bean1) wac.getBean(“b1″);
out.println(b1.getName()+”<br/>”);
Bean2 b2 = (Bean2) wac.getBean(“b2″);
out.println(b2.getName()+”<br/>”);
%>

输出结果为

I am Bean One!
I am Bean Two!

在Servlet中Web容器中的ApplicationContext被我重写了,原本按默认参数只加载了c1.xml中的bean,我把容器中的WebApplicationContext 提取出来作为c2.xml的parent创建一个新的WebApplicationContext然后加载到ServletContext现在web上下文中的applicationcontext就含有两个配置文件中的bean了。

归根到底Spring在web容器中注入的基本原理就是在web容器启动时初始化WebApplicationContext 存到ServletContext中去,用这WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE就可以读到当前的Ioc容器。

 

发表评论

邮箱地址不会被公开。 必填项已用*标注