手動配置檢視解析器流程分析
springboot有一些類是自動幫我們配置好的,那麼我們想自動配置一些類該怎麼配置呢?
以檢視解析器為例,進入mvc的自動配置類
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnWebApplication(
type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
public static final String DEFAULT_PREFIX = "";
public static final String DEFAULT_SUFFIX = "";
private static final String[] SERVLET_LOCATIONS = new String[]{"/"};
@Bean
@ConditionalOnBean({ViewResolver.class})
@ConditionalOnMissingBean(
name = {"viewResolver"},
value = {ContentNegotiatingViewResolver.class}
)
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class));
resolver.setOrder(-2147483648);
return resolver;
}
關鍵類 ContentNegotiatingViewResolver
public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport implements ViewResolver, Ordered, InitializingBean {
@Nullable
private ContentNegotiationManager contentNegotiationManager;
private final ContentNegotiationManagerFactoryBean cnmFactoryBean = new ContentNegotiationManagerFactoryBean();
private boolean useNotAcceptableStatusCode = false;
@Nullable
private List<View> defaultViews;
@Nullable
private List<ViewResolver> viewResolvers;
.......
省略
.......
protected void initServletContext(ServletContext servletContext) {
//從上下文IOC容器中獲取所有的檢視解析器
Collection<ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.obtainApplicationContext(), ViewResolver.class).values();
ViewResolver viewResolver;
if (this.viewResolvers == null) {
this.viewResolvers = new ArrayList(matchingBeans.size());
Iterator var3 = matchingBeans.iterator();
while(var3.hasNext()) {
viewResolver = (ViewResolver)var3.next();
if (this != viewResolver) {
this.viewResolvers.add(viewResolver);
}
}
} else {
for(int i = 0; i < this.viewResolvers.size(); ++i) {
viewResolver = (ViewResolver)this.viewResolvers.get(i);
if (!matchingBeans.contains(viewResolver)) {
String name = viewResolver.getClass().getName() + i;
this.obtainApplicationContext().getAutowireCapableBeanFactory().initializeBean(viewResolver, name);
}
}
}
AnnotationAwareOrderComparator.sort(this.viewResolvers);
this.cnmFactoryBean.setServletContext(servletContext);
}
在候選的檢視解所有檢視中選擇最好的檢視進行返回
public View resolveViewName(String viewName, Locale locale) throws Exception {
RequestAttributes attrs = RequestContextHolder.getRequestAttributes();
Assert.state(attrs instanceof ServletRequestAttributes, "No current ServletRequestAttributes");
List<MediaType> requestedMediaTypes = this.getMediaTypes(((ServletRequestAttributes)attrs).getRequest());
if (requestedMediaTypes != null) {
//返回所有的候選檢視
List<View> candidateViews = this.getCandidateViews(viewName, locale, requestedMediaTypes);
//選擇最好的檢視進行返回
View bestView = this.getBestView(candidateViews, requestedMediaTypes, attrs);
if (bestView != null) {
return bestView;
}
}
遍歷所有的檢視解析器,通過檢視名( viewName )找到所有可以被檢視解析器解析的檢視 ,加入到候選的檢視candidateViews中
private List<View> getCandidateViews(String viewName, Locale locale, List<MediaType> requestedMediaTypes) throws Exception {
List<View> candidateViews = new ArrayList();
if (this.viewResolvers != null) {
Assert.state(this.contentNegotiationManager != null, "No ContentNegotiationManager set");
Iterator var5 = this.viewResolvers.iterator();
while(var5.hasNext()) {
ViewResolver viewResolver = (ViewResolver)var5.next();
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
candidateViews.add(view);
}
自定義一個檢視解析器試試
@Configuration
public class MyViewResolver {
@Bean
public ViewResolver myselfViewResolver() {
return new LuoViewResolver();
}
private static class LuoViewResolver implements ViewResolver{
@Override
public View resolveViewName(String s, Locale locale) throws Exception {
return null;
}
}
}
執行檢視有沒有加入容器中
相關文章
- 配置多檢視解析器
- springmvc配置thymeleaf檢視解析器SpringMVC
- day04-檢視和檢視解析器
- DRF檢視的使用及原始碼流程分析原始碼
- 檢視ipad 電池健康度流程iPad
- 自己動手擼一個cron表示式解析器
- nodejs啟動流程分析NodeJS
- FlutterApp啟動流程分析FlutterAPP
- Activity啟動流程分析
- Unbound啟動流程分析
- ijkplayer 音視訊同步流程分析
- SpringBoot配置外部Tomcat專案啟動流程原始碼分析(長文)Spring BootTomcat原始碼
- Linux 中檢視 DNS 與 配置LinuxDNS
- Mac 檢視本地網路配置Mac
- Linux下檢視、新增及配置Linux
- LINUX 檢視硬體配置命令Linux
- git檢視config配置資訊Git
- 如何檢視Mac電腦配置?Mac
- 手寫javascript json解析器JavaScriptJSON
- 手寫一個解析器
- Linux:uboot啟動流程分析Linuxboot
- 活動效果分析1——活動流程
- 手動配置ip
- SpringBoot(3)-MVC自動配置及自定義檢視控制器Spring BootMVC
- springboot自動配置原理和啟動流程Spring Boot
- 自己動手寫json解析器0x01-分詞JSON分詞
- StarRocks 物化檢視重新整理流程及原理
- StarRocks 物化檢視重新整理流程和原理
- ASP.NET Core 5.0 MVC中的檢視分類——佈局檢視、啟動檢視、具體檢視、分部檢視ASP.NETMVC
- linux檢視電腦硬體配置Linux
- 檢視JVM預設配置引數JVM
- 電腦配置的三種檢視方法 不用藉助軟體怎麼檢視電腦配置
- 谷歌瀏覽器檢視和手動設定cookie的值谷歌瀏覽器Cookie
- Tomcat原始碼分析--啟動流程Tomcat原始碼
- Android應用啟動流程分析Android
- Flutter啟動流程原始碼分析Flutter原始碼
- Activity啟動流程原始碼分析原始碼
- apiserver原始碼分析——啟動流程APIServer原始碼