springMVC源码分析--AbstractControllerUrlHandlerMapping(六)
上一篇博客springMVC源码分析--AbstractDetectingUrlHandlerMapping(五)中我们介绍了AbstractDetectingUrlHandlerMapping,其定义了一个抽象方法determineUrlsForHandler在子类AbstractControllerUrlHandlerMapping中实现。
子类中AbstractControllerUrlHandlerMapping中determineUrlsForHandler的实现如下,实现原理就是根据beanName从容器中获取bean,然后调用buildUrlsForHandler完成beanName和beanClass的对应关系,其具体实现还是在其子类中实现。
@Override
protected String[] determineUrlsForHandler(String beanName) {
Class<?> beanClass = getApplicationContext().getType(beanName);
//判断是不是支持的类型
if (isEligibleForMapping(beanName, beanClass)) {
//模板方法,在子类实现
return buildUrlsForHandler(beanName, beanClass);
}
else {
return null;
}
}
抽象方法buildUrlsForHandler
protected abstract String[] buildUrlsForHandler(String beanName, Class<?> beanClass);
除此之外AbstractControllerUrlHandlerMapping还提供了一些配置,用于排除掉一些包或者一些类,可以在配置中进行配置
public void setIncludeAnnotatedControllers(boolean includeAnnotatedControllers) {
this.predicate = (includeAnnotatedControllers ?
new AnnotationControllerTypePredicate() : new ControllerTypePredicate());
}
public void setExcludedPackages(String... excludedPackages) {
this.excludedPackages = (excludedPackages != null) ?
new HashSet<String>(Arrays.asList(excludedPackages)) : new HashSet<String>();
}
public void setExcludedClasses(Class<?>... excludedClasses) {
this.excludedClasses = (excludedClasses != null) ?
new HashSet<Class<?>>(Arrays.asList(excludedClasses)) : new HashSet<Class<?>>();
}
判断beanName和beanClass是否已经配置排除对应关系。
protected boolean isEligibleForMapping(String beanName, Class<?> beanClass) {
if (beanClass == null) {
if (logger.isDebugEnabled()) {
logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
"because its bean type could not be determined");
}
return false;
}
if (this.excludedClasses.contains(beanClass)) {
if (logger.isDebugEnabled()) {
logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
"because its bean class is explicitly excluded: " + beanClass.getName());
}
return false;
}
String beanClassName = beanClass.getName();
for (String packageName : this.excludedPackages) {
if (beanClassName.startsWith(packageName)) {
if (logger.isDebugEnabled()) {
logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
"because its bean class is defined in an excluded package: " + beanClass.getName());
}
return false;
}
}
//
return isControllerType(beanClass);
}
总结:AbstractControllerUrlHandlerMapping的实现机制就是根据beanName从容器中获取实现类beanClass,同时beanName和beanClass的对应关系的操作是在其子类中完成实现的,同时AbstractControllerUrlHandlerMapping提供了一些配置用于排除一些类的关系。
AbstractControllerUrlHandlerMapping完整源码如下:
public abstract class AbstractControllerUrlHandlerMapping extends AbstractDetectingUrlHandlerMapping {
private ControllerTypePredicate predicate = new AnnotationControllerTypePredicate();
private Set<String> excludedPackages = Collections.singleton("org.springframework.web.servlet.mvc");
private Set<Class<?>> excludedClasses = Collections.emptySet();
public void setIncludeAnnotatedControllers(boolean includeAnnotatedControllers) {
this.predicate = (includeAnnotatedControllers ?
new AnnotationControllerTypePredicate() : new ControllerTypePredicate());
}
public void setExcludedPackages(String... excludedPackages) {
this.excludedPackages = (excludedPackages != null) ?
new HashSet<String>(Arrays.asList(excludedPackages)) : new HashSet<String>();
}
public void setExcludedClasses(Class<?>... excludedClasses) {
this.excludedClasses = (excludedClasses != null) ?
new HashSet<Class<?>>(Arrays.asList(excludedClasses)) : new HashSet<Class<?>>();
}
@Override
protected String[] determineUrlsForHandler(String beanName) {
Class<?> beanClass = getApplicationContext().getType(beanName);
//判断是不是支持的类型
if (isEligibleForMapping(beanName, beanClass)) {
//模板方法,在子类实现
return buildUrlsForHandler(beanName, beanClass);
}
else {
return null;
}
}
protected boolean isEligibleForMapping(String beanName, Class<?> beanClass) {
if (beanClass == null) {
if (logger.isDebugEnabled()) {
logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
"because its bean type could not be determined");
}
return false;
}
if (this.excludedClasses.contains(beanClass)) {
if (logger.isDebugEnabled()) {
logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
"because its bean class is explicitly excluded: " + beanClass.getName());
}
return false;
}
String beanClassName = beanClass.getName();
for (String packageName : this.excludedPackages) {
if (beanClassName.startsWith(packageName)) {
if (logger.isDebugEnabled()) {
logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
"because its bean class is defined in an excluded package: " + beanClass.getName());
}
return false;
}
}
//
return isControllerType(beanClass);
}
//判断是否实现了Controller接口或者使用了@Controller
protected boolean isControllerType(Class<?> beanClass) {
return this.predicate.isControllerType(beanClass);
}
protected boolean isMultiActionControllerType(Class<?> beanClass) {
return this.predicate.isMultiActionControllerType(beanClass);
}
protected abstract String[] buildUrlsForHandler(String beanName, Class<?> beanClass);
}
springMVC源码分析--AbstractControllerUrlHandlerMapping(六)的更多相关文章
- springMVC源码分析--ControllerClassNameHandlerMapping(九)
在上一篇博客springMVC源码分析--AbstractControllerUrlHandlerMapping(六)中我们介绍到AbstractControllerUrlHandlerMapping ...
- springMVC源码分析--ControllerBeanNameHandlerMapping(八)
在上一篇博客springMVC源码分析--AbstractControllerUrlHandlerMapping(六)中我们介绍到AbstractControllerUrlHandlerMapping ...
- springMVC源码分析--异常处理机制HandlerExceptionResolver执行原理(二)
上一篇博客springMVC源码分析--异常处理机制HandlerExceptionResolver简单示例(一)中我们简单地实现了一个异常处理实例,接下来我们要介绍一下HandlerExceptio ...
- 框架-springmvc源码分析(二)
框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...
- 8、SpringMVC源码分析(3):分析ModelAndView的形成过程
首先,我们还是从DispatcherServlet.doDispatch(HttpServletRequest request, HttpServletResponse response) throw ...
- 7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解
从上一篇 SpringMVC源码分析(1) 中我们了解到在DispatcherServlet.doDispatch方法中会通过 mv = ha.handle(processedRequest, res ...
- springMVC源码分析--ViewNameMethodReturnValueHandler返回值处理器(三)
之前两篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)和springMVC源码分析--HandlerMethodReturnValu ...
- springMVC源码分析--HandlerMethodReturnValueHandlerComposite返回值解析器集合(二)
在上一篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)我们介绍了返回值解析器HandlerMethodReturnValueHand ...
- springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)
之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)和springMVC源码解析--HandlerMethodArgumentResol ...
随机推荐
- Java内存回收机制.md
1.java的内存 java的内存结构分为 堆 (是gc的主要区域) 线程共享,主要是用于分配实例对象和数组 栈 线程私有,它的生命周期和线程相同,又分成 虚拟机栈和本地方法栈,只有它会报 Stack ...
- [原创]手把手教你写网络爬虫(4):Scrapy入门
手把手教你写网络爬虫(4) 作者:拓海 摘要:从零开始写爬虫,初学者的速成指南! 封面: 上期我们理性的分析了为什么要学习Scrapy,理由只有一个,那就是免费,一分钱都不用花! 咦?怎么有人扔西红柿 ...
- Leetcode 804. Unique Morse Code Words 莫尔斯电码重复问题
参考:https://blog.csdn.net/yuweiming70/article/details/79684433 题目描述: International Morse Code defines ...
- [LeetCode] Design TinyURL 设计精简URL地址
Note: For the coding companion problem, please see: Encode and Decode TinyURL. How would you design ...
- [LeetCode] K Inverse Pairs Array K个翻转对数组
Given two integers n and k, find how many different arrays consist of numbers from 1 to n such that ...
- tooltip.css-2.0文档
tooltip.css 纯CSS鼠标提示工具. v. 2.0.0 更新日期:2018.4.12 预览DEMO. 安装: 只需在页面中引入"tooltip.css"或" ...
- 原生JS面向对象方法实现万年历
###面向对象的方法实现万年历 实现思路: 1.创建构造函数constructor ``` function Calender(main){ this.current ...
- Codeforces Round #430 C. Ilya And The Tree
Ilya is very fond of graphs, especially trees. During his last trip to the forest Ilya found a very ...
- 【USACO】奶牛抗议 树状数组+dp
题目描述 约翰家的 N 头奶牛正在排队游行抗议.一些奶牛情绪激动,约翰测算下来,排在第 i 位的奶牛 的理智度为 A i ,数字可正可负. 约翰希望奶牛在抗议时保持理性,为此,他打算将这条队伍分割成几 ...
- NOIP2014-5-24模拟赛
Problem 1 护花(flower.cpp/c/pas) [题目描述] 约翰留下他的N(N<=100000)只奶牛上山采木.他离开的时候,她们像往常一样悠闲地在草场里吃草.可是,当他回来的时 ...