SpringMVC底层机制简单实现-02
https://github.com/liyuelian/springmvc-demo.git
4.任务3-从web.xml动态获取容器配置文件
4.1分析
任务3:MyDispatcherServlet (自定义的前端分发器)在创建并初始化自定义的spring容器时,可以动态地从web.xml中获取到配置的容器文件。
我们之前实现的时候,是直接在 MyWebApplicationContext 中指定要读取的容器文件。
改进:在web.xml中通过init-param指定容器文件,然后通过读取web.xml获取即可。这样可以动态地读取容器文件,不需要改变源代码。
4.2代码实现
(1)修改 MyDispatcherServlet 的 init 方法。通过 ServletConfig 对象,获取 Servlet 的初始化参数 init-param,将该参数的值传入 spring 容器的初始化方法。
部分代码:
@Override
public void init(ServletConfig servletConfig) throws ServletException {
/** web.xml文件,前端控制器的配置中:
* <init-param>
* <param-name>contextConfigLocation</param-name>
* <param-value>classpath:myspringmvc.xml</param-value>
* </init-param>
*/
//configLocation ==> classpath:myspringmvc.xml
String configLocation =
servletConfig.getInitParameter("contextConfigLocation");
//初始化ioc容器,传入指定的spring配置文件
myWebApplicationContext = new MyWebApplicationContext(configLocation);
myWebApplicationContext.init();
//调用 initHandlerMapping(),完成url和控制器方法的映射
initHandlerMapping();
//测试输出 handlerList
System.out.println("handlerList输出的结果=" + handlerList);
}
(2)修改 MyApplicationContext 自定义spring 容器,额外提供一个带参构造器,用于获取传入的 容器配置文件名,然后传给 MyApplicationContext 的 init() 方法去初始化。
部分代码:
//无参构造器
public MyWebApplicationContext() {
}
//表示spring容器配置文件名
private String configLocation;
//带参构造器
public MyWebApplicationContext(String configLocation) {
this.configLocation = configLocation;
}
/**
* 该方法完成对自己的 spring容器的初始化
*/
public void init() {
//configLocation的值是 classpath:myspringmvc.xml
// 按冒号分割,取索引为 1的子串:myspringmvc.xml
String basePackage =
XMLParse.getBasePackage(configLocation.split(":")[1]);
String[] basePackages = basePackage.split(",");
if (basePackages.length > 0) {
//遍历这些包
for (String pack : basePackages) {
scanPackage(pack);
}
}
System.out.println("扫描后的路径classFullPathList=" + classFullPathList);
//将扫描到的类反射到ioc容器
executeInstance();
System.out.println("扫描后的ioc容器=" + ioc);
}
//scanPackage方法,略..该方法完成对包的扫描
//executeInstance方法,略..该方法将扫描到的类,在满足条件的情况下进行反射,并放入到ioc容器中