热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SpringMvc组件初始化

SpringMVC9大组件初始化由上面的断点流程,可以看出来其实是在spring容器初始化完成的最后一步,通过发送event事件@Overridepublicvoidpublish

SpringMVC 9大组件初始化

技术图片

由上面的断点流程,可以看出来其实是在spring容器初始化完成的最后一步,通过发送event事件

@Override
public void publishEvent(ApplicationEvent event) {
Assert.notNull(event, "Event must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Publishing event in " + getDisplayName() + ": " + event);
}
getApplicationEventMulticaster().multicastEvent(event);
if (this.parent != null) {
this.parent.publishEvent(event);
}
}

然后进入下面的SimpleApplicationEventMulticaster的类中,去遍历所有的监听类

@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public void multicastEvent(final ApplicationEvent event) {
for (final ApplicationListener listener : getApplicationListeners(event)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@Override
public void run() {
listener.onApplicationEvent(event);
}
});
}
else {
listener.onApplicationEvent(event);
}
}
}

onApplicationEvent这个方法一直被重写,最后执行的是FrameworkServlet的onApplicationEvent方法,在去调用DispatcherServlet的onRefresh方法。

@Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
/**
* Initialize the strategy objects that this servlet uses.
*

May be overridden in subclasses in order to initialize further strategy objects.
*/
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}

再去初始化9大组件,这里就简单的介绍其中的一个组件的初始化过程。

private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
if (this.detectAllHandlerMappings) {
// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
Map matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList(matchingBeans.values());
// We keep HandlerMappings in sorted order.
OrderComparator.sort(this.handlerMappings);
}
}
else {
try {
HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, we‘ll add a default HandlerMapping later.
}
}
// Ensure we have at least one HandlerMapping, by registering
// a default HandlerMapping if no other mappings are found.
if (this.handlerMappings == null) {
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
if (logger.isDebugEnabled()) {
logger.debug("No HandlerMappings found in servlet ‘" + getServletName() + "‘: using default");
}
}
}

其中:detectAllHandlerMappings这个值为true,也可以在配置文件里面设置false,当true的时候,值为下面。

技术图片

其中:this.handlerMappings == null,当走进这个方法的时候,回去读取配置文件中默认的处理器映射器。

protected List getDefaultStrategies(ApplicationContext context, Class strategyInterface) {
String key = strategyInterface.getName();
String value = defaultStrategies.getProperty(key);
if (value != null) {
String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
List strategies = new ArrayList(classNames.length);
for (String className : classNames) {
try {
Class clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
Object strategy = createDefaultStrategy(context, clazz);
strategies.add((T) strategy);
}
catch (ClassNotFoundException ex) {
throw new BeanInitializationException(
"Could not find DispatcherServlet‘s default strategy class [" + className +
"] for interface [" + key + "]", ex);
}
catch (LinkageError err) {
throw new BeanInitializationException(
"Error loading DispatcherServlet‘s default strategy class [" + className +
"] for interface [" + key + "]: problem with class file or dependent class", err);
}
}
return strategies;
}
else {
return new LinkedList();
}
}

其中

private static final Properties defaultStrategies;
static {
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load ‘DispatcherServlet.properties‘: " + ex.getMessage());
}
}

回去加载配置文件里面的默认值。

技术图片

先简单的记录一下,等后面在结合SpringMVC源码的书,在进行补充。

个人感觉这个工具类还是挺有用的,其中springboot的自动配置原理也有用到,下面就简单测试一下。

/**
* @author WGR
* @create 2021/4/14 -- 22:27
*/
public class Test {
@SneakyThrows
public static void main(String[] args) {
ClassPathResource resource = new ClassPathResource("test.properties", Test.class);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
System.out.println(properties.getProperty("org.springframework.web.servlet.HandlerAdapter"));
}
}
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter, org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter, org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter

我这里是idea,跑起来的时候,直接报错,然后百度了一下,要在pom.xml配置.因为IDEA有个配置项,默认只把.class的文件放到编译目录中,也就是target目录。



src/main/java

**/*.*


**/*.java



技术图片

SpringMvc组件初始化



推荐阅读
author-avatar
刁琼婉
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有