springboot系列7,Spring MVC(下)

  • mvc的自动装配

在SpringFramework时代mvc就可以进行自动装配了,

但前提是servlet依赖是3.0+

servlet SPI:ServletContainerInitializer

当servlet容器启动的时候,ServletContainerInitializer中的onStartup方法会被回调,

ServletContext中可动态装载监听器或过滤器或其他组件,那么spring也借助这个接口,实现了自己的东西。 

spring的适配:SpringServletContainerInitializer

图中@HandlesTypes为筛选器,在servlet启动时,servlet的jar包会引入许多jar包,@HandlesTypes用来筛选哪些是需要装载的。 

Spring SPI:WebApplicationInitializer

进去看这个接口:

从注释可看出有三个实现类 

编程实现:AbstractDispatcherServletInitializer

从上图源码注释可以看出,AbstractDispatcherServletInitializer属于WebApplicationInitializer的一个实现类,源码:

/**
	 * Register a {@link DispatcherServlet} against the given servlet context.
	 * <p>This method will create a {@code DispatcherServlet} with the name returned by
	 * {@link #getServletName()}, initializing it with the application context returned
	 * from {@link #createServletApplicationContext()}, and mapping it to the patterns
	 * returned from {@link #getServletMappings()}.
	 * <p>Further customization can be achieved by overriding {@link
	 * #customizeRegistration(ServletRegistration.Dynamic)} or
	 * {@link #createDispatcherServlet(WebApplicationContext)}.
	 * @param servletContext the context to register the servlet against
	 */
	protected void registerDispatcherServlet(ServletContext servletContext) {
		String servletName = getServletName();
		Assert.hasLength(servletName, "getServletName() must not return null or empty");

		WebApplicationContext servletAppContext = createServletApplicationContext();
		Assert.notNull(servletAppContext, "createServletApplicationContext() must not return null");

		FrameworkServlet dispatcherServlet = createDispatcherServlet(servletAppContext);
		Assert.notNull(dispatcherServlet, "createDispatcherServlet(WebApplicationContext) must not return null");
		dispatcherServlet.setContextInitializers(getServletApplicationContextInitializers());

		ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet);
		if (registration == null) {
			throw new IllegalStateException("Failed to register servlet with name '" + servletName + "'. " +
					"Check if there is another servlet registered under the same name.");
		}

		registration.setLoadOnStartup(1);
		registration.addMapping(getServletMappings());
		registration.setAsyncSupported(isAsyncSupported());

		Filter[] filters = getServletFilters();
		if (!ObjectUtils.isEmpty(filters)) {
			for (Filter filter : filters) {
				registerServletFilter(servletContext, filter);
			}
		}

		customizeRegistration(registration);
	}

 onstartup会调registerDispatcherServlet这个方法。

这个方式的实现过程不再写了,为什么不写呢?因为下面的注解实现AbstractAnnotationConfigDispatcherServletInitializer通过源码可知,他继承AbstractDispatcherServletInitializer,所以具体详情看AbstractAnnotationConfigDispatcherServletInitializer源码即可。

注解实现:AbstractAnnotationConfigDispatcherServletInitializer

实现:

web.xml中全部注释

<web-app>
    <!--<servlet>使用可执行 Tomcat Maven 插件
        Spring Framework 时代的重新认识
        Web MVC 核心组件
        <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/app-context.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>-->
</web-app>

新建配置类: 

/**
 * {@link DispatcherServlet} 配置类
 */
@ComponentScan(basePackages = "com.haozi.web")
public class DispatcherServletConfiguration {
}
public class DefaultAnnotationConfigDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {       //对应web.xml中的init-param
        return new Class[0];
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {    //DispatcherServlet
        return new Class[]{DispatcherServletConfiguration.class};
    }

    @Override
    protected String[] getServletMappings() {           //映射
        return new String[]{"/"};
    }
}

其实这种实现方式就是把xml的替换成编码的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值