源码解析:WebMvcAutoConfiguration


注:此篇文章适合对为什么自定义拦截器或者视图解析器生效的原因困惑的同学来看,带你从源码分析为什么。

一:WebMvcAutoConfiguration做了什么

1.WebMvcAutoConfiguration 源码

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
		ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
*****省略*******
}

@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
从这里可以看到,这个自动配置类将会去主动加载以上的三个类,我们重点看WebMvcConfigurer.class

2.WebMvcConfigurer接口源码

在这里插入图片描述
可以看出,这是一个接口,里边声明了很多的方法,什么拦截器,视图解析器,格式转化器。既然是一个接口,我们看看是谁实现了它,那么实现的类就会被WebMvcAutoConfiguration 加载到。

3. WebMvcAutoConfigurationAdapter

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
		ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
*****省略*******


//实现类
public static class **WebMvcAutoConfigurationAdapter** implements WebMvcConfigurer {
*****
}


******省略******
}

震惊,实现类WebMvcAutoConfigurationAdapter居然是WebMvcAutoConfiguration 的静态内部类。所以说我们的WebMvcAutoConfiguration 会自动加载WebMvcAutoConfigurationAdapter的所有东西,因为WebMvcAutoConfigurationAdapter实现了WebMvcConfigurer接口。

4.自定义类实现WebMvcConfigurer这个接口,这样我们是不是就可以加上一些我们自己的配置了?试一试

4.1如果我们想增加拦截器,怎么做,先看源码
public interface WebMvcConfigurer {
//拦截器的声明
default void addInterceptors(InterceptorRegistry registry) {
	}
}

可以看出拦截器需要一个InterceptorRegistry 拦截器注册器,我们点开看看

public class InterceptorRegistry {

	private final List<InterceptorRegistration> registrations = new ArrayList<>();

	public InterceptorRegistration addInterceptor(HandlerInterceptor interceptor) {
		InterceptorRegistration registration = new InterceptorRegistration(interceptor);
		this.registrations.add(registration);
		return registration;
	}
}

从上面的源码可以看到,InterceptorRegistry 有一个包含InterceptorRegistration的List,同时有一个addInterceptor的方法,主要内容是往这个list中增加InterceptorRegistration,我们点开InterceptorRegistration看看。

public class InterceptorRegistration {
	private final HandlerInterceptor interceptor;
	
	public InterceptorRegistration(HandlerInterceptor interceptor) {
		Assert.notNull(interceptor, "Interceptor is required");
		this.interceptor = interceptor;
	}
}

可以看到InterceptorRegistration 他有一个HandlerInterceptor 的类属性,同时有一个构造方法来赋值。我们点开HandlerInterceptor 这个看看。

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

可以看到这是一个接口。我们可以写一个类实现这个接口。

4.2写代码实践下

先写一个我们的拦截器实现这个接口HandlerInterceptor

@Component
public class MyInterceptor implements HandlerInterceptor {
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler) throws Exception {
		return true;
		}

我们再写一个自己的配置类

@Configuration
public class MyConfiguration implements WebMvcConfigurer {
	 @Override
	 public void addInterceptors(InterceptorRegistry registry) {
		  //将我们自定义的拦截器加入配置
	 	 InterceptorRegistration interceptor = registry.addInterceptor(new MyInterceptor());
		  //设置拦截的url
		  interceptor.addPathPatterns("/user/**");
	 }
}

这样我们的自定义拦截器就写好啦。
如果想在webmvc中添加自己的功能,只需要去WebMvcConfigurer看看自己想增加什么功能就好啦,然后按照源码来写。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值