Spring 梳理 - JavaConfig、SPI、SCI、SpringSCI、WebApplicationInitializer、AbstractAnnotationConfigDispatcherServletInitializer、WebMvcConfigurationSupport
- 总结1:
- SCI:Servlet容器(Tomcat)提供的初始化Servlet容器本身的接口,可替换web.xml
- SpringSCI:SpringServletContainerInitializer,Srping提供的SCI的一个实现,起到中转桥接作用,桥接到 WebApplicationInitializer 接口上
- WebApplicationInitializer :可以自定义配置servlet、listener,进而可以通过代码手动控制两个上下文的创建过程(参考:基于xml 参考:支持注解);只能创建上线文但不能配置上下文详细内容,但可以指定上下文配置文件的路径或配置类的类路径
AbstractAnnotationConfigDispatcherServletInitializer:将两个上下文自动已创建好,已创建好的上下文的类型都是支持注解的;手动继承后只需要指定两个上下文配置类路径即可。- WebMvcConfigurer:
WebMvcConfigurationAdapter已经废弃,最好用implements WebMvcConfigurer代替
@Configuration
public class MyConfig implements WebMvcConfigurer { }如果使用继承,WebMvcConfigurationSupport,DelegatingWebMvcConfiguration,或者使用@EnableWebMvc
If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own
@Configurationclass of typeWebMvcConfigurerbut without@EnableWebMvc. If you wish to provide custom instances ofRequestMappingHandlerMapping,RequestMappingHandlerAdapter, orExceptionHandlerExceptionResolver, you can declare aWebMvcRegistrationsAdapterinstance to provide such components.If you want to take complete control of Spring MVC, you can add your own
@Configurationannotated with@EnableWebMvc.
- 总结2:
- java提供SPI,用于加载指定接口的 特定实现类
- servlet容器提供SCI接口,用于配置servlet容器初始化;这个过程使用了java的SPI机制;类似Logfactory的工作原理
- Spring提供SpringServletContainerInitializer类(该类实现类SCI接口),该类简称SpringSCI,该类不直接配置servlet容器,而是通过查找WebApplicationInitializer接口(用于web初始化)的实现类,间接配置servlet容器;
- Spring MVC提供基类 AbstractAnnotationConfigDispatcherServletInitializer,用于DispatcherServlet初始化(实现了WebApplicationInitializer接口),该基类既要完成WebApplicationInitializer接口中配置servlet容器的功能,又完成了配置MVC的功能,即同时配置了DispatcherServlet 和 ContextLoaderListener
- Spring提供的接口
WebApplicationInitializer,用于配置servlet容器,并不是只用于配置MVC,可通过自定义二次开发继承WebApplicationInitializer,结合ServletRegistration.Dynamic,配置servlet容器,添加自定义的servlet、filter等,可完全替换掉web.xml - 如果是在MVC项目中,想添加自定义的servlet、filter,可不用实现
WebApplicationInitializer,直接只要重写AbstractAnnotationConfigDispatcherServletInitializer类的getServletFilters()方法就行了;不需要 mapping,因为会自动 mapping 到DispatcherServlet上,通过返回多个 filter,可以添加多个 filter。
- 总结3:spring 依据“java的SPI(Service Provider Interface)机制”和“servlet容器的SCI(ServletContainerInitializer)接口”,通过SpringServletContainerInitializer实现spring组件和servlet容器解耦,解耦后,spring组件可以直接使用spring提供的WebApplicationInitializer接口,实现类似SCI功能,通过实现WebApplicationInitializer,可以向servlet容器添加servlet,listener等。
- Servlet 3.0 规范和 Spring DispatcherServlet 配置
在 Servlet 3.0 的环境中,容器会在 classpath 中寻找继承了 javax.servlet.ServletContainerInitializer 接口的类,用它来配置 servlet 容器。
Spring 提供了一个继承这个接口的类 SpringServletContainerInitializer,在这个类中,它会寻找任何继承了 WebApplicationInitializer 接口的类并用其来配置 servlet 容器。 - Spring 3.2 提供了一个继承了 WebApplicationInitializer 接口的基类 AbstractAnnotationConfigDispatcherServletInitializer,用于配置Spring MVC项目。Spring 3.2 开始引入一个简易的 WebApplicationInitializer 实现类,这就是 AbstractAnnotationConfigDispatcherServletInitializer。
在AbstractAnnotationConfigDispatcherServletInitializer中,给我们留下了三个抽象方法要求我们去实现:
- protected abstract String[] getServletMappings(); 这个方法在AbstractDispatcherServletInitializer 中,这个方法可以将一个或多个路径映射到DispatcherServlet上,如果路径设置为“/”,则所有的请求都会由DispatcherServlet处理。
- protected abstract Class<?>[] getRootConfigClasses(); 这两个方法在AbstractAnnotationConfigDispatcherServletInitializer中
- protected abstract Class<?>[] getServletConfigClasses();
- 在Spring MVC项目中
- 你的 servlet 配置类只需要继承 AbstractAnnotationConfigDispatcherServletInitializer,就会被发现而用于 servlet 容器的配置。
- AbstractAnnotationConfigDispatcherServletInitializer用于创建两种应用上下文:
DispatcherServlet创建的和拦截器ContextLoaderListener创建的上下文 在 AbstractAnnotationConfigDispatcherServletInitializer 中 DispatcherServlet 和 ContextLoaderListener 都会被创建,而基类中的方法就可用来创建不同的应用上下文:
getServletConfigClasses():定义 DispatcherServlet 应用上下文中的 beans;
- getRootConfigClasses():定义拦截器 ContextLoaderListener 应用上下文中的 beans
- 示例
-
package spittr.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import spittr.web.WebConfig;
public class SpitterWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
-
- 配置额外的 servlets 和 filters(非Bean,非DispatcherServlet 和 ContextLoaderListener中的元素)
- 如果需要定义额外的 servlets 或 filters,只需要创建额外的初始化类。在 Spring MVC 中可以通过继承
WebApplicationInitializer接口来实现。 定义一个新的 servlet: package com.myapp.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import com.myapp.MyServlet;
public class MyServletInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext throws ServletException {
Dynamic myServlet = servletContext.addServlet("myServlet", MyServlet.class);
myServlet.addMapping("/custom/**");
}
} 定义 filters 和 listeners:
@Override
public void onStartup(ServletContext servletContext)
throws ServletException {
// 定义filter
javax.servlet.FilterRegistration.Dynamic filter =
servletContext.addFilter("myFilter", MyFilter.class);
filter.addMappingForUrlPatterns(null, false, "/custom/*"); }如果你需要为 DispatcherServlet 添加 filter 的话,就不用这么麻烦了,你只要重写 AbstractAnnotationConfigDispatcherServletInitializer 类的 getServletFilters() 方法就行了:
@Override
protected Filter[] getServletFilters() {
return new Filter[] { new MyFilter() };
}不需要 mapping,因为会自动 mapping 到 DispatcherServlet 上,通过返回多个 filter,可以添加多个 filter
- 如果需要定义额外的 servlets 或 filters,只需要创建额外的初始化类。在 Spring MVC 中可以通过继承
- 参考:https://blog.csdn.net/w1196726224/article/details/52687324
- 参考:[Servlet3.0研究之ServletContainerInitializer接口 - 夫礼者的专栏 - CSDN博客: https://blog.csdn.net/lqzkcx3/article/details/78507169]
- 参考:[java中的SPI机制 - 司刚军的个人专栏 - CSDN博客: https://blog.csdn.net/sigangjun/article/details/79071850]
- 参考:[JavaSPI机制学习笔记 - 琴水玉 - 博客园: http://www.cnblogs.com/lovesqcc/p/5229353.html]
- 参考:[Servlet3.0研究之ServletContainerInitializer接口 - 夫礼者的专栏 - CSDN博客: https://blog.csdn.net/lqzkcx3/article/details/78507169]
- Service Provider Interface:
java spi的具体使用如下 :
当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。
基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。
jdk提供服务实现查找的一个工具类:java.util.ServiceLoader
- Servlet 3.0 规范和 Spring DispatcherServlet 配置
- 使用JavaConfig普通web应用(非MVC)
public class App {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(
AppConfig.class);
CustomerBo customer = (CustomerBo) context.getBean("customer");
customer.printMsg("Hello 1");
SchedulerBo scheduler = (SchedulerBo) context.getBean("scheduler");
scheduler.printMsg("Hello 2");
} } ############## import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration @Import({ CustomerConfig.class, SchedulerConfig.class }) public class AppConfig {
} ############## @Configuration
public class CustomerConfig {
@Bean(name="customer")
public CustomerBo customerBo(){
return new CustomerBo();
}
} ##############
public class SchedulerBo {
public void printMsg(String msg) {
System.out.println("SchedulerBo : " + msg); }
}
Spring 梳理 - JavaConfig、SPI、SCI、SpringSCI、WebApplicationInitializer、AbstractAnnotationConfigDispatcherServletInitializer、WebMvcConfigurationSupport的更多相关文章
- Spring 梳理 - javaConfig在App和webApp中的应用
package com.dxz.demo.configuration; import org.springframework.context.annotation.Configuration; @Co ...
- Spring 梳理 - JavaConfig实战(spring MVC)-原创
目录结构 AppInitializer.java package com.jt; import org.springframework.web.servlet.support.AbstractAnno ...
- Spring 梳理 - 开启并配置 Spring MVC 的方法
传统web.xm中配置两个上下文+两个context对应的xml+两个上下文bean分别手动配置 传统web.xm中配置两个上下文+两个context对应的xml+<mvc:annotation ...
- Spring 使用javaconfig配置
除了使用xml,spring提供javaconfig配置,下面是简单的例子: 1.声明接口 /** * */ package com.junge.demo.spring.service; /** * ...
- Spring 梳理-MVC-配置DispatcherServet和ContextLoaderListener
在使用JavaConfig时,AbstractAnnotationConfigDispatcherServletInitializer会自动注册 DispatcherServlet 和 Context ...
- 详细解说Java Spring的JavaConfig注解 【抄】
抄自: http://www.techweb.com.cn/network/system/2016-01-05/2252188.shtml @RestController spring4为了更方便的支 ...
- Java Spring的 JavaConfig 注解
序 传统spring一般都是基于xml配置的,不过后来新增了许多JavaConfig的注解.特别是springboot,基本都是清一色的java config,不了解一下,还真是不适应.这里备注一下. ...
- 使用Spring的JavaConfig 和 @Autowired注解与自动装配
1 JavaConfig 配置方法 之前我们都是在xml文件中定义bean的,比如: 1 2 3 4 5 6 7 8 <beans xmlns="http://www.springf ...
- Spring MVC 零配置 / Spring MVC JavaConfig
1. Spring MVC的核心就是DispatcherServlet类,Spring MVC处理请求的流程如下图所示: 2. Spring MVC中典型的上下文层次 当我们初始化一个Dispatch ...
随机推荐
- excel表格导出之后身份证号列变成了科学计数法
excel表格导出之后身份证号列变成了科学计数法 解决:写sql查询出所有数据,并在身份证列添加字符,然后导出,将要复制的excel表格设置单元格格式问文本类型,然后复制粘贴,再把加入的字符删除,搞定 ...
- Codeforces 246C
题意略. 思路: 我们将数组中的数字从大到小排列,分别考虑取前0 + 1,1 + 1,2 + 1.....个的情况. 所谓i + 1的意思是,取前i个的时候,同时取第[i + 1],[i + 2],. ...
- [转]Android中设置TextView的颜色setTextColor
[转自]http://txlong-onz.iteye.com/blog/1249609 Android中设置TextView的颜色setTextColor android中设置TextView的颜色 ...
- JS核心之DOM操作 下
目录: 1.节点类型之Document类型 2.节点类型之Element类型 3.节点类型之Text类型 4.综合小示例 -- 动态添加外部样式文件 5.查找元素的扩展方法 接上篇,我们先来看常用的三 ...
- netcore 中的动态代理与RPC实现(微服务专题)
一.关于RPC的调用 1. 调用者(客户端Client)以本地调用的方式发起调用: 2. Client stub(客户端存根)收到调用后,负责将被调用的方法名.参数等打包编码成特定格式的能进行网络传输 ...
- CF981B Businessmen Problems map 模拟 二十二
Businessmen Problems time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- == != === equals() 区别
java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型. byte,short,char,int,long,float,double,boolean,他们之间的比较,应用双等号(==) ...
- React-router总结
版本 v3和v4有一些差距: https://blog.csdn.net/qq_35484341/article/details/80500237 以下的总结,都是基于V4的 官方文档:https:/ ...
- 【LeetCode】56-合并区间
题目描述 给出一个区间的集合,请合并所有重叠的区间. 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: 区间 ...
- Vulkan(1)用apispec生成Vulkan库
Vulkan(1)用apispec生成Vulkan库 我的Vulkan.net库已在(https://github.com/bitzhuwei/Vulkan.net)开源,欢迎交流. apispec. ...