springmvc源码解析之配置加载SpringServletContainerI...

用SpringMVC源码解析之配置加载SpringServletContainerInitializer


用SpringMVC配置解析
sdervlet容器启动的时候会加载org.springframework.web.SpringServletContainerInitializer这个类,调用初始化类的onStartup方法
[AppleScript] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Override
public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
throws ServletException {
 
List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>();
if (webAppInitializerClasses != null) {
for (Class<?> waiClass : webAppInitializerClasses) {
// Be defensive: Some servlet containers provide us with invalid classes,
// no matter what @HandlesTypes says...
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
try {
initializers.add((WebApplicationInitializer) waiClass.newInstance());
}
catch(Throwable ex){
throw new ServletException(“无法实例化WebApplicationInitializer类”,ex);
}
}
}
}
 
如果(initializers.isEmpty()){
servletContext.log( “检测到的无弹簧WebApplicationInitializer类型上的类路径”);
返回;
}
 
servletContext.log(initializers.size()+ “类路径上检测到的弹簧WebApplicationInitializers”);
AnnotationAwareOrderComparator.sort(初始化);
for(WebApplicationInitializer initializer:initializers){
initializer.onStartup(servletContext);
}
/ [mw_shl_code]
[color=#000][font=sans-serif][size=16px]进入到DispatcherServlet初始化器org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#onStartup这个方法[/size][/font][/color]
[mw_shl_code=applescript,true] @Override
public void onStartup(ServletContext servletContext) throws ServletException {
//调用上下文加载器初始化类的onStartup方法
super.onStartup(servletContext);
//注册DispatcherServlet
registerDispatcherServlet(servletContext);
}


进入到这个方法org.springframework.web.context.AbstractContextLoaderInitializer#onStartup,执行ContextLoader初始化器

[AppleScript] 纯文本查看 复制代码
?
1
2
3
4
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
registerContextLoaderListener(servletContext);
}


进入到这个方法org.springframework.web.context.AbstractContextLoaderInitializer#registerContextLoaderListener,注册ContextLoader监听器
[mw_shl_code = applescript,true] protected void registerContextLoaderListener(ServletContext servletContext){ 
//获取上层应用上下文对象 - > 
WebApplicationContext rootAppContext = createRootApplicationContext(); 
if(rootAppContext!= null){ 
//创建上下文加载监听器
ContextLoaderListener listener = new ContextLoaderListener(rootAppContext); 
listener.setContextInitializers(getRootApplicationContextInitializers()); 
//把上下文加载监听器加载到servlet容器
servletContext.addListener(listener); 

else { 
logger.debug(“没有注册ContextLoaderListener,因为”+ 
“createRootApplicationContext()没有返回应用程序上下文”); 

} [/ mw_shl_code]
进入到这个方法org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer#createRootApplicationContext

[AppleScript] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
@Override
protected WebApplicationContext createRootApplicationContext() {
//从子类实现中或者从@Configuration、@Component注解配置中获取配置类
Class<?>[] configClasses = getRootConfigClasses();
if (!ObjectUtils.isEmpty(configClasses)) {
// 如果没有配置就默认初始化基于注解的web应用上下文类
AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext();
rootAppContext.register(configClasses);
return rootAppContext;
}
else {
return null;
}
}


进入到这个方法org.springframework.web.context.AbstractContextLoaderInitializer#getRootApplicationContextInitializers

[AppleScript] 纯文本查看 复制代码
?
1
2
3
protected ApplicationContextInitializer<?>[] getRootApplicationContextInitializers() {
return null;
}


返回到这个方法org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#onStartup这一行

[AppleScript] 纯文本查看 复制代码
?
1
2
// 注册DispatcherServlet
registerDispatcherServlet(servletContext);


进入到这个方法org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#registerDispatcherServlet

[AppleScript] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
protected void registerDispatcherServlet(ServletContext servletContext) {
//获取servletName,默认名称是dispatcher
String servletName = getServletName();
Assert.hasLength(servletName,“getServletName()不能返回空或null”);
//创建servlet程序上下文 - >
WebApplicationContext servletAppContext = createServletApplicationContext();
Assert.notNull(servletAppContext,
“createServletApplicationContext()没有返回
servlet [”+ servletName +“]”)的应用程序“+ ”上下文;
//创建DispatcherServlet
FrameworkServlet dispatcherServlet = createDispatcherServlet(servletAppContext);
//注册的servlet上下文初始化器,这里是模板实现
dispatcherServlet.setContextInitializers(getServletApplicationContextInitializers());
//添加的DispatcherServlet到的servlet容器
ServletRegistration.Dynamic registration = servletContext.addServlet(servletName,dispatcherServlet);
Assert.notNull(注册,
“无法注册名称为'的servlet ++ servletName +“'。”+
“检查是否有另一个以相同名称注册的servlet。”);
registration.setLoadOnStartup(1);
//获取servletMapping实现,这里是抽象实现,注册映射
registration.addMapping(getServletMappings());
//设置是否支持异步,默认支持
registration.setAsyncSupported(isAsyncSupported());
//获取servletFilter,这里是模板实现
Filter [] filters = getServletFilters();
if(!ObjectUtils.isEmpty(filters)){
for(Filter filter:filters){
//注册过滤器 - >
registerServletFilter(servletContext,filter);
 
 
 
//定制化注册,默认是模板实现
customizeRegistration(registration);
}


进入到这个方法org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer#createServletApplicationContext

[AppleScript] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
@Override
protected WebApplicationContext createServletApplicationContext() {
//创建基于注解的web应用上下文
AnnotationConfigWebApplicationContext servletAppContext = new AnnotationConfigWebApplicationContext();
//从子类实现中或者从@Configuration、@Component注解配置中获取配置类
Class<?>[] configClasses = getServletConfigClasses();
if (!ObjectUtils.isEmpty(configClasses)) {
// 注册@Configuration配置的配置加载类到AnnotationConfigWebApplicationContext
servletAppContext.register(configClasses);
}
return servletAppContext;
}


进入到这个方法org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#registerServletFilter
[mw_shl_code=applescript,true]protected FilterRegistration.Dynamic registerServletFilter(ServletContext servletContext, Filter filter) {
//获取filteName
String filterName = Conventions.getVariableName(filter);
//添加filter到servlet容器
Dynamic registration = servletContext.addFilter(filterName, filter);
//如果filter注册失败
if (registration == null) {
int counter = -1;
while (counter == -1 || registration == null) {
counter++;
//添加filter#0 到servlet容器
registration = servletContext.addFilter(filterName + "#" + counter, filter);
//提示有同样的名字的过滤器已注册过
Assert.isTrue(计数器<100,
“无法注册过滤器'”+过滤器+“'。”+ 
“可能已经注册了相同的过滤器实例吗?”); 


//是否支持异步,默认是
registration.setAsyncSupported(isAsyncSupported()); 
registration.addMappingForServletNames(getDispatcherTypes(),false,getServletName()); 
退货登记; 
} [/ mw_shl_code]

回退到这个方法org.springframework.web.SpringServletContainerInitializer#onStartup

原文 - 微信公众号:天河聊架构
 

 

发布了604 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/xiaoyaGrace/article/details/104267485