SpringMVC的启动

Spring MVC中的Servlet

Spring MVC中Servlet一共有三个层次,分别是HttpServletBean、FrameworkServlet和DispatcherServlet。HttpServletBean直接继承自Java的HttpServlet,其作用是将Servlet中配置的参数设置到相应的属性;FrameworkServlet初始化了WebApplicationContext;DispatcherServlet初始化了自身的9个组件。

DispatcherServlet

DispatcherServlet的入口方法是onRefresh方法,其中简单地调用了initStrategies方法,其中又调用了9个初始化方法,初始化策略组件。

protected void onRefresh(ApplicationContext context) {
    this.initStrategies(context);
}
onRefresh
protected void initStrategies(ApplicationContext context) {
    // 上传组件
    this.initMultipartResolver(context);
    // 国际化组件
    this.initLocaleResolver(context);
    this.initThemeResolver(context);
    this.initHandlerMappings(context);
    this.initHandlerAdapters(context);
    this.initHandlerExceptionResolvers(context);
    this.initRequestToViewNameTranslator(context);
    this.initViewResolvers(context);
    this.initFlashMapManager(context);
}
initStrategies
// 以initLocaleResolver为例分析初始化组件过程
private void initLocaleResolver(ApplicationContext context) {
    try {
        // 按照名称或类型在容器中获取
        // 我们只要在SpringMVC的配置文件中配置相应类型的组件,容器就可以自动找到
        this.localeResolver = (LocaleResolver)context.getBean("localeResolver", LocaleResolver.class);
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Using LocaleResolver [" + this.localeResolver + "]");
        }
    } catch (NoSuchBeanDefinitionException var3) {
        // 如果没有配置,使用默认策略
        this.localeResolver = (LocaleResolver)this.getDefaultStrategy(context, LocaleResolver.class);
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Unable to locate LocaleResolver with name 'localeResolver': using default [" + this.localeResolver + "]");
        }
    }
}
initLocaleResolver
protected <T> T getDefaultStrategy(ApplicationContext context, Class<T> strategyInterface) {
    // 调用复数的方法
    List<T> strategies = this.getDefaultStrategies(context, strategyInterface);
    if (strategies.size() != 1) {
        throw new BeanInitializationException("DispatcherServlet needs exactly 1 strategy for interface [" + strategyInterface.getName() + "]");
    } else {
        // 返回第一个
        return strategies.get(0);
    }
}
protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
    String key = strategyInterface.getName();
    // Properties类型的defaultStrategies在静态代码块中初始化
    String value = defaultStrategies.getProperty(key);
    if (value == null) {
        return new LinkedList();
    } else {
        // 如果有多个默认值,以逗号分隔数组
        String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
        List<T> strategies = new ArrayList(classNames.length);
        String[] var7 = classNames;
        int var8 = classNames.length;
        // 初始化组件
        for(int var9 = 0; var9 < var8; ++var9) {
            String className = var7[var9];
            try {
                Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
                Object strategy = this.createDefaultStrategy(context, clazz);
                strategies.add(strategy);
            } catch (ClassNotFoundException var13) {
                throw new BeanInitializationException("Could not find DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]", var13);
            } catch (LinkageError var14) {
                throw new BeanInitializationException("Error loading DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]: problem with class file or dependent class", var14);
            }
        }

        return strategies;
    }
}

static {
    try {
        // DispatcherServlet.properties在DispatcherServlet.java文件的旁边
        ClassPathResource resource = new ClassPathResource("DispatcherServlet.properties", DispatcherServlet.class);
        defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
    } catch (IOException var1) {
        throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + var1.getMessage());
    }
}
View Code

DispatcherServlet.properties文件内容:

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,
    org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,
    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter

org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,
    org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,
    org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
View Code

一共定义了8个组件,上传组件MultipartResolver没有默认配置,因为不是每个应用都需要上传功能,即使需要上传也不一定就要使用MultipartResolver;HandlerMapping、HandlerAdapter和HandlerExceptionResolver都配置了多个;ViewResolver也可以配置多个,默认是一个。
默认配置并不是最优配置,也不是spring的推荐配置。
当使用<mvc:annotation-driven/>后,并不会全部使用默认配置,因为它配置了HandlerMapping、HandlerAdapter和HandlerExceptionResolver,而且还做了很多别的工作。

Spring MVC的启动

启动DispatcherServlet之前先创建HttpServletBean、FrameworkServlet,创建DispatcherServlet后调用其onRefresh方法,再调用initStrategies方法初始化其它组件。 

转载于:https://www.cnblogs.com/Mike_Chang/p/10495854.html

Spring MVC 是一个基于 Java 的 Web 框架,用于构建 Web 应用程序。要启动 Spring MVC,需要完成以下步骤: 1. 配置 web.xml 文件:在你的 Web 项目的 web.xml 文件中,配置一个 Servlet,作为 Spring MVC 的前端控制器。配置示例如下: ```xml <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> ``` 2. 创建 applicationContext.xml 文件:在 WEB-INF 目录下创建 applicationContext.xml 文件,用于配置 Spring MVC 相关的组件和 bean。配置示例如下: ```xml <!-- 设置扫描的包 --> <context:component-scan base-package="com.example.controller" /> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> ``` 3. 创建 Controller 类:在指定的包中创建控制器类,用于处理请求和返回响应。示例代码如下: ```java @Controller public class MyController { @RequestMapping("/hello") public String hello(Model model) { model.addAttribute("message", "Hello, Spring MVC!"); return "hello"; } } ``` 4. 创建视图文件:在 /WEB-INF/views/ 目录下创建 hello.jsp 文件,用于展示视图。示例代码如下: ```jsp <html> <head> <title>Hello Page</title> </head> <body> <h2>${message}</h2> </body> </html> ``` 5. 运行应用程序:将应用程序部署到支持 Java 的 Web 服务器(如 Tomcat)上,并启动服务器。访问 http://localhost:8080/yourapp/hello,将会看到 "Hello, Spring MVC!" 的页面返回。 这样就完成了 Spring MVC 的启动过程。当然,以上只是一个简单的示例,实际的项目中可能会更复杂。你可以根据自己的需求进行配置和开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值