SpringMVC——Servlet3.0

WEB三大组件:servlet、filter、listener。以前经常在web.xml配置使用。


ServletContainerInitializer——初始化web容器

在web容器启动时为提供给第三方组件机会做一些初始化的工作。每个框架要使用ServletContainerInitializer就必须在对应的jar包的META-INF/services目录创建一个名为javax.servlet.ServletContainerInitializer的文件,文件内容指定具体的ServletContainerInitializer实现类——全类名。那么,当web容器启动时就会运行这个初始化器做一些组件内的初始化工作。
ServletContainerInitializer接口:

public interface ServletContainerInitializer {
	// 通过 @HandlesTypes(WebApplicationInitializer.class) 注解指定 c 入参。
	// 继承了 WebApplicationInitializer 的类
	// ServletContext 代表当前的 web 应用。
    public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException; 
}

比如SpringServletContainerInitializer

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
	@Override
	public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
		List<WebApplicationInitializer> initializers = Collections.emptyList();
		if (webAppInitializerClasses != null) {
			initializers = new ArrayList<>(webAppInitializerClasses.size());
			// 挨个实例化并放入 initializers list
			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 ...
				}
			}
		}

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

		servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
		// 排序并挨个执行实现了 WebApplicationInitializer 的类的 onStartup 方法。
		AnnotationAwareOrderComparator.sort(initializers);
		for (WebApplicationInitializer initializer : initializers) {
			initializer.onStartup(servletContext);
		}
	}
}

WebApplicationInitializer的实现类:
WebApplicationInitializer
AbstractContextLoaderInitializer——注册监听器ContextLoaderListener

public abstract class AbstractContextLoaderInitializer implements WebApplicationInitializer {
	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		registerContextLoaderListener(servletContext);
	}
	protected void registerContextLoaderListener(ServletContext servletContext) {
		// 创建 IOC 容器
		WebApplicationContext rootAppContext = createRootApplicationContext();
		if (rootAppContext != null) {
			// 添加监听器
			ContextLoaderListener listener = new ContextLoaderListener(rootAppContext);
			listener.setContextInitializers(getRootApplicationContextInitializers());
			servletContext.addListener(listener);
		} // else log ...
	}
}

createRootApplicationContext()子类实现创建IOC容器——WebApplicationContext
AbstractDispatcherServletInitializer——注册DispatcherServlet和过滤器

public abstract class AbstractDispatcherServletInitializer extends AbstractContextLoaderInitializer {
    public void onStartup(ServletContext servletContext) throws ServletException {
        super.onStartup(servletContext);
        this.registerDispatcherServlet(servletContext);
    }
	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);
	}
}

AbstractAnnotationConfigDispatcherServletInitializer——创建Servlet和Root的IOC容器
继承了AbstractDispatcherServletInitializer,提供了创建两种IOC容器的实现方法。

public abstract class AbstractAnnotationConfigDispatcherServletInitializer extends AbstractDispatcherServletInitializer {
	protected WebApplicationContext createRootApplicationContext() {
		Class<?>[] configClasses = getRootConfigClasses();
		if (!ObjectUtils.isEmpty(configClasses)) {
			AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
			context.register(configClasses);
			return context;
		}
		else {
			return null;
		}
	}
	protected WebApplicationContext createServletApplicationContext() {
		AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
		Class<?>[] configClasses = getServletConfigClasses();
		if (!ObjectUtils.isEmpty(configClasses)) {
			context.register(configClasses);
		}
		return context;
	}

	// 根容器配置,子类实现
	protected abstract Class<?>[] getRootConfigClasses();
	// 子容器配置,子类实现
	protected abstract Class<?>[] getServletConfigClasses();
}

DispatcherServlet中两类容器的区别

  • Servlet WebApplicationContext
    • Controllers
    • ViewResolver
    • HandlerMapping
    • other web-related beans
  • Root WebApplicationContext
    • Services
    • Repositories

这些都是抽象类,需要自己实现,继承了以后自动处理,因为它一定继承了WebApplicationInitializer,不需要额外操作。


Filter——过滤器

需要添加到 ServletContext中。

public interface Filter {
    default public void init(FilterConfig filterConfig) throws ServletException {}
    public void doFilter(ServletRequest request, ServletResponse response,  FilterChain chain) throws IOException, ServletException;
    default public void destroy() {}
}

ServletContextListener——监听器

监听项目的启动或停止,需要添加到 ServletContext中。

public interface ServletContextListener extends EventListener {
    default public void contextInitialized(ServletContextEvent sce) {}
    default public void contextDestroyed(ServletContextEvent sce) {}
}

HttpServlet——定制web应用

web应用继承该类,需要添加到 ServletContext中。或直接使用 @WebServlet注解。
HttpServlet
比如SpringMVC中的DispatcherServlet
DispatcherServlet


@EnableWebMvc

页面请求定制,静态资源托管给tomcat,注解版自定义拦截器。

需要继承WebMvcConfigurer接口

public interface WebMvcConfigurer {
	default void configurePathMatch(PathMatchConfigurer configurer) {
	}
	default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
	}
	default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
	}
	default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
	}
	default void addFormatters(FormatterRegistry registry) {
	}
	default void addInterceptors(InterceptorRegistry registry) {
	}
	default void addResourceHandlers(ResourceHandlerRegistry registry) {
	}
	default void addCorsMappings(CorsRegistry registry) {
	}
	default void addViewControllers(ViewControllerRegistry registry) {
	}
	default void configureViewResolvers(ViewResolverRegistry registry) {
	}
	default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
	}
	default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
	}
	default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
	}
	default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
	}
	default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
	}
	default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
	}
	default Validator getValidator() {
		return null;
	}
	default MessageCodesResolver getMessageCodesResolver() {
		return null;
	}
}

WebMvcConfigurerComposite继承了WebMvcConfigurer接口,可以直接继承它:

class WebMvcConfigurerComposite implements WebMvcConfigurer {
	private final List<WebMvcConfigurer> delegates = new ArrayList<>();

	public void addWebMvcConfigurers(List<WebMvcConfigurer> configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
			this.delegates.addAll(configurers);
		}
	}

	public void configurePathMatch(PathMatchConfigurer configurer) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.configurePathMatch(configurer);
		}
	}

	public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.configureContentNegotiation(configurer);
		}
	}

	public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.configureAsyncSupport(configurer);
		}
	}

	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.configureDefaultServletHandling(configurer);
		}
	}

	public void addFormatters(FormatterRegistry registry) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.addFormatters(registry);
		}
	}

	public void addInterceptors(InterceptorRegistry registry) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.addInterceptors(registry);
		}
	}

	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.addResourceHandlers(registry);
		}
	}

	public void addCorsMappings(CorsRegistry registry) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.addCorsMappings(registry);
		}
	}

	public void addViewControllers(ViewControllerRegistry registry) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.addViewControllers(registry);
		}
	}

	public void configureViewResolvers(ViewResolverRegistry registry) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.configureViewResolvers(registry);
		}
	}

	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.addArgumentResolvers(argumentResolvers);
		}
	}

	public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.addReturnValueHandlers(returnValueHandlers);
		}
	}

	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.configureMessageConverters(converters);
		}
	}

	public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.extendMessageConverters(converters);
		}
	}

	public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.configureHandlerExceptionResolvers(exceptionResolvers);
		}
	}

	public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.extendHandlerExceptionResolvers(exceptionResolvers);
		}
	}

	public Validator getValidator() {
		Validator selected = null;
		for (WebMvcConfigurer configurer : this.delegates) {
			Validator validator = configurer.getValidator();
			if (validator != null) {
				if (selected != null) {
					throw new IllegalStateException("No unique Validator found: {" +
							selected + ", " + validator + "}");
				}
				selected = validator;
			}
		}
		return selected;
	}

	public MessageCodesResolver getMessageCodesResolver() {
		MessageCodesResolver selected = null;
		for (WebMvcConfigurer configurer : this.delegates) {
			MessageCodesResolver messageCodesResolver = configurer.getMessageCodesResolver();
			if (messageCodesResolver != null) {
				if (selected != null) {
					throw new IllegalStateException("No unique MessageCodesResolver found: {" +
							selected + ", " + messageCodesResolver + "}");
				}
				selected = messageCodesResolver;
			}
		}
		return selected;
	}
}

WebMvcConfigurerAdapter也继承了WebMvcConfigurer接口,但是已经被弃用了,因为里面都是空方法,接口可以默认实现空方法,所以还不如直接继承WebMvcConfigurer接口。

HandlerInterceptor——SpringMVC拦截器

public interface HandlerInterceptor {
	// 在目标方法执行之前调用
	default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		return true;
	}
	// 在目标方法执行之后调用
	default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
	}
	// 页面响应之后执行
	default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值