- 在容器中的生命周期
服务器先根据server.xml创建应用层面的容器后(即context概念,对应的对象会被组合到servlet对象中),根据web.xml创建servlet层面的容器,此时的描述符对应servlet概念即servlet接口。描述符中,可以配置servlet组件,每一个servlet组件可以组合servletconfig,和servlet定义平级的概念还有filter等,这里先略过。因此web.xml中的元素是整个应用的组成部分(context)而不是servlet概念的组成部分,但是可以在其中设置应用的servlet部分。由此servlet对象又由context和其config等组成,config用于初始化避免硬编码context用于被访问应用的一些信息。
当容器完成了一系列的开始工作之后(暂且不管那些复杂的流程和关系,只要有上面大体的印象现在就足够了),开始调用时序中的最深处的子程序,即servlet.init/service/destory;这就是在服务器中的生命周期,一方面给程序员传递了两个重要对象,一方面传递可部署的参数。
1.init(ServletConfig config){}(参见4web.xml描述符)
描述符中填充了init参数后,容器就会创建config对象并组合到servlet中,避免硬编码,注释中也写了,更适用与和部署工作关联紧密的处理程序;不填充init参数时,该对象显 然为null,当然还是可以重写该init方法,硬编码做一些工作,但是核心的仍然是res/req其他这些只是周全的服务,硬编码违背设计初衷只是奇技淫巧。
2.service
来自服务器源码,服务器本意是根据请求方式调用组件程序源覆写的如doGet等方法,该方法可以重写,但是个人认为没必要,而且不是很认同服务器将该方法暴露给程序员来 重写。
3.destory
我竟然没有找到父类中哪里实现的,不过没关系,这里不是关注的重点,只要牢牢记住,服务器自有实现过程并且必会调用就可以。而且如果没有重写初始化,该方法没 有必要重写,应该任由服务器执行其默认的实现,这才是设计者的本来意图。
4.web.xml
- 总结
web.xml是对应于整个应用概念的,即所组成它的标签就是整个应用容器的组成部分;而servlet只是其中元素,由servlet标签元素的组成部分,可以大体的到它的粗略定义;这 里重点对生命周期做一下回顾init遵循设计意图,只需要和部署相关的servlet重写该方法并填充标签元素即可;service不主张重写,甚至觉得压根就不应该给重写的机会;destory没有重写init时不主张重写,有init并且确实需要关闭一些资源时需要重写。那么程序员必定要重写的,就是客户端所请求的get或post方法。
- 补充
最后关于其他请求方式,如put、delete等,如果重写,则一定要按照其定义,返回合适的状态码;但显然这些请求方式应用并不广泛。
另外,附加一下servletContext在web.xml中的部署,该上下文有点看类似于整个应用的容器对象的初始化,回忆一下,在server.xml中可以给host主机下context起虚拟名,就是 说服务器在此时创建应用容器,但是该容器概念所对应的对象还可以在解析web.xml时根据context-param标签进行对象属性的填充,可理解为应用context的初始化,最终可以 web.xml理解为服务器中一个应用的完全定义。
servlet代码中获取全局变量:req.getServletContext().getInitParameter("adminEmail");