A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

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


用SpringMVC配置解析
sdervlet容器启动的时候会加载org.springframework.web.SpringServletContainerInitializer这个类,调用初始化类的onStartup方法

[AppleScript] 纯文本查看 复制代码
@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] 纯文本查看 复制代码
@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] 纯文本查看 复制代码
@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] 纯文本查看 复制代码
protected ApplicationContextInitializer<?>[] getRootApplicationContextInitializers() {
return null;
}

返回到这个方法org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#onStartup这一行
[AppleScript] 纯文本查看 复制代码
// 注册DispatcherServlet
registerDispatcherServlet(servletContext);

进入到这个方法org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#registerDispatcherServlet
[AppleScript] 纯文本查看 复制代码
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] 纯文本查看 复制代码
@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
原文 - 微信公众号:天河聊架构



0 个回复

您需要登录后才可以回帖 登录 | 加入黑马