黑马程序员技术交流社区

标题: 【杭州校区】springmvc源码解析之配置加载SpringServletContainerI... [打印本页]

作者: 小江哥    时间: 2019-9-19 17:08
标题: 【杭州校区】springmvc源码解析之配置加载SpringServletContainerI...
用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]
进入到DispatcherServlet初始化器org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#onStartup这个方法
[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
原文 - 微信公众号:天河聊架构








欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2