SpringMVC学习总结

springMVC搭建流程和源码解析(零配置)

官方文档:

https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html

以以下代码替换原生的web.xml文件配置

public class MyWebApplicationInitializer implements WebApplicationInitializer {

//tomcat启动的时候会默认调用onstart方法
    @Override
    public void onStartup(ServletContext servletCxt) {

        // Load Spring web application configuration
        //使用注解方式配置(零配置)
        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
        ac.register(AppConfig.class);
        ac.refresh();
//类型与使用xml方式配置
//ClassPathXmlApplicationContext
        // Create and register the DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(ac);
        ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/app/*");
    }
}

相当于以下传统web.xml配置:

<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>

AppConfig.java

package com.init;

import com.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.ServletException;
import javax.servlet.ServletRegistration;

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext ac=new AnnotationConfigWebApplicationContext();
        ac.register(AppConfig.class);
        ac.refresh();
        DispatcherServlet servlet=new DispatcherServlet(ac);
        ServletRegistration.Dynamic app = servletContext.addServlet("app", servlet);
        app.setLoadOnStartup(1);
        app.addMapping("/app/*");
    }
}

pom.xml

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>


    <build>
        <finalName>spring-mvc</finalName>

            <plugins>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <path>/</path>
                        <port>8080</port>
                        <uriEncoding>UTF-8</uriEncoding>
                    </configuration>
                </plugin>
            </plugins>
    </build>

说明:

onstart方法之所以能被tomcat启动是因为

在这里插入图片描述在这里插入图片描述
当META-INF/services/添加的类必定是tomcat加载的类
我们再来看@HandlesTypes(WebApplicationInitializer.class)这个注解表示将WebApplicationInitializer这个类传递给这个启动类,我们接着看源码:

//Set<Class<?>> webAppInitializerClasses这个参数是为了接受上述@HandlesTypes里的所有继承WebApplicationInitializer的子类集合
//ServletContext 这个就是上下文对象 是tomcat里的
public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
			throws ServletException {

		List<WebApplicationInitializer> initializers = new LinkedList<>();

		if (webAppInitializerClasses != null) {
			for (Class<?> waiClass : webAppInitializerClasses) {
				// Be defensive: Some servlet containers provide us with invalid classes,
				// no matter what @HandlesTypes says...
				if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
						WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
					try {
						initializers.add((WebApplicationInitializer)
								ReflectionUtils.accessibleConstructor(waiClass).newInstance());
					}
					catch (Throwable ex) {
						throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
					}
				}
			}
		}

		if (initializers.isEmpty()) {
			servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
			return;
		}

		servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
		AnnotationAwareOrderComparator.sort(initializers);
		//这个地方就是遍历参数的集合来启动子类的onStartUp方法,所以会被tomcat启动即加载
		for (WebApplicationInitializer initializer : initializers) {
			initializer.onStartup(servletContext);
		}
	}

springMVC是如何找到请求的controller的

1:springMVC在初始化会扫描整个项目
2:扫描到所有加了controller注解的类
3:反射拿出类里面所有方法对象然后遍历
4:判断是否有@RequestMapping("/xxx")注解
5:如果有,他会维护一个map 注解得到值作为key,方法的对象作为value
6:通过request拿到请求uri(xxx) 并去map.get出来

springMVC流程图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值