之前一直在博客园写博客,但是自己不怎么会调样式,就换到csdn.
博客园地址上面是随便写的自己的近些时间的离职想法,和之前学习的时候一些学习笔记,新手上路各位多多关照;
近段时间离职,面试次次碰壁,多次打击之后,自然也燃起了我从现在开始,每天写博客的斗志。同时现在心中有了进攻大厂的打算了(今天刚刚接到阿里的一面的电话,问了4个问题就挂了<哭晕>)。大概要花个一年左右吧。
好的现在进入正题。
SpringMVC,学习Java的非常清楚吧。至于启动流程对于想进大厂的同学有必要深究以下。
先来看我的一个web项目 现在是项目启动了tomcat然后在HttpServletBean上的init的方法打上了断点;因为springMVC的核心组件就是dispatchcherServlet,既然是servlet 就有生命周期,init,service,destory方法,所以web容器启动之后,在页面上输入,对应的URL:http://localhost:8080/eduOnline/;这个时候开始实例化一个servlet,有的同学会问,不是启动tomcat就直接会实例化一个servlet对象吗,不是的,这个问题我今天也研究了下,发现确实是要输入地址才会实例化对象,这个是以什么时候掉用init方法做为依据的,这里不做过多阐述。顺便这里献上dispacherServlet的族谱图 FrameworkServlet是它的父类,HttpServletBean是FrameworkServlet的父类。而且它(这里指的是核心组件DispatcherServlet)的爸爸和爷爷。代码里可以看到它自己本身没有init方法,它的爷爷有init方法,接下来看代码的跑动所做的事情。
这里可以看到的是PropertyValues这个类是获取Spring-MVC.xml的配置文件,这个配置是SpringMVC专属的,里面配置了它要扫描的一些包和一些组件
以上的代码就是找到这个配置文件的目录,走下去
可以看到是先包装了一下这个bean,这里也有了contextClass,这个对象在springMVC也很重要,主要是他要参与解析xml文件吧,以上的代码就是包装在propertyValue中了
接下来看initServletBean这个方法很重要,主要是用于能够创建webApplicationContext对象。此时已经是在FrameworkServlet中
然后代码到initWebApplicationContext方法中创建一个WebApplicationContext对象
这里是实例化了一个xmlWebApplicationContext对象并把它加载到了webApplicationContext对象中返回。configureAndRefreshWebApplicationContext中refresh方法
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
if (this.contextId != null) {
wac.setId(this.contextId);
} else {
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(this.getServletContext().getContextPath()) + '/' + this.getServletName());
}
}
wac.setServletContext(this.getServletContext());
wac.setServletConfig(this.getServletConfig());
wac.setNamespace(this.getNamespace());
wac.addApplicationListener(new SourceFilteringListener(wac, new FrameworkServlet.ContextRefreshListener()));
ConfigurableEnvironment env = wac.getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment)env).initPropertySources(this.getServletContext(), this.getServletConfig());
}
this.postProcessWebApplicationContext(wac);
this.applyInitializers(wac);
wac.refresh();
}
refresh方法开始获取beanFactory方法
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
两个方法获取
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
this.refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
protected final void refreshBeanFactory() throws BeansException {
if (this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
beanFactory.setSerializationId(this.getId());
this.customizeBeanFactory(beanFactory);
this.loadBeanDefinitions(beanFactory);
Object var2 = this.beanFactoryMonitor;
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException var5) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
}
}
这个方法,这个类
获取bean实例的这里不做叙述,后期有机会在说下;差多获取到webApplicationContext之后,可以完工了,servlet的init方法也启动差不多了,接着就是操作一些组件,像hardleMappings和hadleAdaptor这两个组件找到对应的控制层,将modelandview发信息展示给页面
这个是我的页面<呲牙>