3. servlet 和 springmvc框架关系


在springmvc上我们会编写很多相关的配置

  • 编写springmvc.xml
    • 配置映射器
    • 配置 处理适配器
      ...
  • web.xml
    • 配置前端控制器 (DispatcherServlet)

官网: https://spring.io/
弱小和无知并不是生存的障碍,傲慢才是。

=================================================================

=================================================================

  • 注解方式
public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletCxt) {

        // Load Spring web application configuration
        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
        ac.register(AppConfig.class);
        ac.refresh();

        // Create and register the DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(ac);
        ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/app/*");
    }
}

=================================================================

  • 配置方式
<web-app>

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

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

    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>

</web-app>

=================================================================

* 创建maven项目,然后导入web支持

=================================================================

  • 导入springmvc相关依赖
<dependencies>
        <!--springmvc框架-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.8.RELEASE</version>
        </dependency>
        <!--servlet3.0-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!-- 嵌入式tomcat -->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>9.0.20</version>
        </dependency>
        <!--解决JSP异常-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <version>9.0.20</version>
        </dependency>
</dependencies>

=================================================================

=================================================================

* 创建一个跟官网上一样的类

package com.min.mvc;

import com.min.config.AppConfig;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext servletCxt) {

        // 通过 注解的方式 创建 IOC容器
        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
        // 注册一个配置类
        ac.register(AppConfig.class);
        // 刷新 IOC 容器配置
        ac.refresh();

        // 创建和注册servlet
        DispatcherServlet servlet = new DispatcherServlet(ac);
        // 注册 servlet
        ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
        // 启动加载
        registration.setLoadOnStartup(1);
        // DistpatcherServlet 映射关系
        registration.addMapping("*.do");
    }
}

* 创建配置类

package com.min.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类
 * @Configuration : 通过他注册一个配置类
 * @ComponentScan : 通过他开启一个扫描
 */
@Configuration
@ComponentScan(value = "com.min.controller")
public class AppConfig {
}

=================================================================

  • 编写一个controller

package com.min.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {

    @RequestMapping("/hello.do")
    @ResponseBody
    public String hello(){
        return "Hello World!";
    }
}

=================================================================

* 访问hello.do


经过一番波折发现通过官网上的代码也能跑通。。我丢😂😂😂

=================================================================

更有趣的是这哥们跟我们之前写的Servlet3.0的似曾相识哈哈,那我们一探究竟吧。

=================================================================

  • 会发现这个类也是实现ServletContainerInitializer 接口,@HandlesTypes注解以及重写onStartup方法


package org.springframework.web;

import java.lang.reflect.Modifier;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils;

@HandlesTypes({WebApplicationInitializer.class})
public class SpringServletContainerInitializer implements ServletContainerInitializer {
    public SpringServletContainerInitializer() {
    }

    public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
        List<WebApplicationInitializer> initializers = new LinkedList();
        Iterator var4;
        if (webAppInitializerClasses != null) {
            var4 = webAppInitializerClasses.iterator();

            while(var4.hasNext()) {
                Class<?> waiClass = (Class)var4.next();
                if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
                    try {
                        initializers.add((WebApplicationInitializer)ReflectionUtils.accessibleConstructor(waiClass, new Class[0]).newInstance());
                    } catch (Throwable var7) {
                        throw new ServletException("Failed to instantiate WebApplicationInitializer class", var7);
                    }
                }
            }
        }

        if (initializers.isEmpty()) {
            servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
        } else {
            servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
            AnnotationAwareOrderComparator.sort(initializers);
            var4 = initializers.iterator();

            while(var4.hasNext()) {
                WebApplicationInitializer initializer = (WebApplicationInitializer)var4.next();
                initializer.onStartup(servletContext);
            }

        }
    }
}

=================================================================

  • WebApplicationInitializer接口

package org.springframework.web;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;

public interface WebApplicationInitializer {
    void onStartup(ServletContext var1) throws ServletException;
}

所以经过以上的查看和测试,发现其中的原理就是这样子的!!!
底层源码

  • 迭代
  • 通过反射实例化对象
  • 调用这些实现类的 startup 方法


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM