// 配置拦截器(方式一)
<mvc:interceptors>
// 会自动封装成MappedInterceptor
<mvc:interceptor>
<mvc:mapping path="/*"/>
<bean class="com.luck.mvc.controller.LuckInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
// 解析interceptors标签
public BeanDefinition parse(Element element, ParserContext context) {
// 解析XML表桥
List<Element> interceptors = DomUtils.getChildElementsByTagName(element, "bean", "ref", "interceptor");
// 遍历拦截器标签
for (Element interceptor : interceptors) {
// 封装成MappedInterceptor对象
RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
mappedInterceptorDef.setSource(context.extractSource(interceptor));
// 自己配置的包含路径和排除路径
ManagedList<String> includePatterns = null;
ManagedList<String> excludePatterns = null;
Object interceptorBean;
// 解析属性
if ("interceptor".equals(interceptor.getLocalName())) {
includePatterns = getIncludePatterns(interceptor, "mapping");
excludePatterns = getIncludePatterns(interceptor, "exclude-mapping");
Element beanElem = DomUtils.getChildElementsByTagName(interceptor, "bean", "ref").get(0);
interceptorBean = context.getDelegate().parsePropertySubElement(beanElem, null);
}
// 给对象MappedInterceptor的构造方法赋值
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, includePatterns);
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, excludePatterns);
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, interceptorBean);
// 是否存在路径解析
if (pathMatcherRef != null) {
mappedInterceptorDef.getPropertyValues().add("pathMatcher", pathMatcherRef);
}
// 注册成组件
String beanName = context.getReaderContext().registerWithGeneratedName(mappedInterceptorDef);
context.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, beanName));
}
return null;
}
配置拦截器(方式二)
@EnableWebMvc // 必须开启,否则无效
@Configuration
public class LuckConfig implements WebMvcConfigurer {
@Bean
public LuckInterceptor luckInterceptor() {
return new LuckInterceptor();
}
// 添加拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(luckInterceptor()).addPathPatterns("/**");{
InterceptorRegistration registration = new InterceptorRegistration(interceptor);
// 注册到容器中
this.registrations.add(registration);
return registration;
}
}
}
@EnableWebMvc 导入了DelegatingWebMvcConfiguration类,内部注册了requestMappingHandlerMapping的Bean
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping(
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
mapping.setOrder(0);
mapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider){
if (this.interceptors == null) {
InterceptorRegistry registry = new InterceptorRegistry();
// 将自己注册的拦截器
addInterceptors(registry);{
// this.configurers = WebMvcConfigurerComposite implements WebMvcConfigurer
this.configurers.addInterceptors(registry);{
// 扫描所有的WebMvcConfigurer,添加拦截器,这就是为什么要实现WebMvcConfigurer接口
for (WebMvcConfigurer delegate : this.delegates) {
delegate.addInterceptors(registry);
}
}
}
// 注册内置的拦截器
registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService));
registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider));
// 将拦截器注册表所有的拦截器
this.interceptors = registry.getInterceptors();{
return this.registrations.stream()
.sorted(INTERCEPTOR_ORDER_COMPARATOR)
// 封装成MappedInterceptor
.map(InterceptorRegistration::getInterceptor){
// 如果没有自定义的拦截设置,直接返回,不包装
if (this.includePatterns == null && this.excludePatterns == null) {
return this.interceptor;
}
// 否则包装成MappedInterceptor
MappedInterceptor mappedInterceptor = new MappedInterceptor(
StringUtils.toStringArray(this.includePatterns),
StringUtils.toStringArray(this.excludePatterns),
this.interceptor);
// 如果存在路径匹配器
if (this.pathMatcher != null) {
mappedInterceptor.setPathMatcher(this.pathMatcher);
}
return mappedInterceptor;
}
.collect(Collectors.toList());
}
}
});
return mapping;
}
配置拦截器(方式三)
@Bean
public MappedInterceptor luckInterceptor() {
return new MappedInterceptor(new String[]{"/**"}, new LuckInterceptor());
}
在AbstractHandlerMapping中,初始化的时候会执行
// 扫描自己注册的MappedInterceptorBean
detectMappedInterceptors(this.adaptedInterceptors);{
// 从Spring容器中获取MappedInterceptor类型的bean
mappedInterceptors.addAll(BeanFactoryUtils.beansOfTypeIncludingAncestors(
obtainApplicationContext(), MappedInterceptor.class, true, false).values());
}
// 在所有的AbstractHandlerMapping中都会执行
// 拦截器存在AbstractHandlerMapping这个类中是因为Handler就是存在这里,而拦截器就是对handler进行处理的
class AbstractHandlerMapping extends WebApplicationObjectSupport
extends ApplicationObjectSupport implements ApplicationContextAware
implements HandlerMapping{
public final void setApplicationContext(@Nullable ApplicationContext context) {
this.initApplicationContext(context);{
// 空实现,是将所有配置的拦截器给子类继承,扩展
// this.interceptors是在HandlerMapping中自己设置的
// 如果是默认的HandlerMapping,那么是没有设置拦截器的
// 如果是使用了@EnableMvc,导入的配置类中添加了HandlerMapping的Bean,这些bean中设置了拦截器
extendInterceptors(this.interceptors);
// 扫描MappedInterceptors,就是对原生的Interceptor进行了包装
// 因为我们定义的Interceptor是可以设置匹配路径的,这样内部最少需要一个匹配器来校验
// 所以才会有MappedInterceptors
// 扫描我们自己定义的拦截器MappedInterceptors
// this.adaptedInterceptors这个是我们适配之后,实实在在能用的拦截器
detectMappedInterceptors(this.adaptedInterceptors);{
// 从Spring容器中获取MappedInterceptor类型的bean
mappedInterceptors.addAll(BeanFactoryUtils.beansOfTypeIncludingAncestors(
obtainApplicationContext(), MappedInterceptor.class, true, false).values());
}
// 初始化所有的拦截器
initInterceptors();{
// 遍历所有的拦截器
for (int i = 0; i < this.interceptors.size(); i++) {
Object interceptor = this.interceptors.get(i);
// adaptedInterceptors是我们适配之后,实实在在能用的拦截器
this.adaptedInterceptors.add(adaptInterceptor(interceptor){
// 适配拦截器
if (interceptor instanceof HandlerInterceptor) {
return (HandlerInterceptor) interceptor;
}
// 转换为HandlerInterceptor类型
if (interceptor instanceof WebRequestInterceptor) {
return new WebRequestHandlerInterceptorAdapter((WebRequestInterceptor) interceptor);
}
});
}
}
}
}
}
}