1,在servlet中,分为三种对象,一个应用上下文context,一个是session,一个是request。
2,context,属性的作用范围最大,在整个web应用中都有效,所有的servlet和jsp共享一份context。context的初始化信息在web.xml中配置,如果配置了context-param这个属性,当容器启动的时候,容器就会去读取
web.xml文件的配置信息,然后初始化context对象。在你的监听类(在我的例子中:MyServletContextListener)中,就可以建立关于你要的操作,比如最经常使用使用的,和数据库建立链接。如果要获得在web.xml配置context信息,就必须启动ServletContextListener,然后把它配置到web.xml之中。
context对象的属性内容不是线程安全的,如果涉及到context对象的数据安全,就一定要采用同步,把context对象锁起来,只要锁context对象就可以了,不要把整个servlet都锁起来了
配置的一个example:
<context-param>
<param-name>breed</param-name>
<param-value>Great Dane</param-value>
</context-param>
<listener>
<listener-class>com.example.MyServletContextListener</listener-class>
</listener>
MyServletContextListener是一个继承ServletContextListener的类,在tomcat加载配置信息的时候,一旦初始化context对象,那么这个监听对象的方法就会执行。采用这种配置信息的时候并不是很多,一般采用context配置在web.xml中的,大部分是关于数据库连接的,比如我可以把数据库名,密码,账户不容易发生更改的信息配置到web.xml中,以后更换数据库的时候,就不需要打开源代码了,只需要修改web.xml,然后重启tomcat就可以达到木目的了。
3,session,属性的作用范围是用户第一次访问到关闭浏览器。其实这个也不是线程安全的,如果一个用户打开了几个浏览器,那时候session也不是线程安全了,所以也要把session锁起来,锁关于session的操作部分就好,尽量减少锁带来的开销
4,request,一次请求...作用范围就是一个servlet的service()开始,到doGet()或者doPost()结束。他是线程安全的,因为每次请求,开辟的都是一个新的线程。
5,由于涉及到多线程的问题,所以在使用servlet开发的时候,不要采用类的成员变量,尽可能的设计为局部变量,因为局部变量是线程安全的,但是类的成员变量却不是。
servlet的声明周期:
当容器(通常java中我们用tomcat)启动时,会读取web.xml,读取这个web应用的配置信息。当用户第一次发来请求是,容器通过web.xml的配置信息找到相对应的servlet,然后启动一个全新的线程,让servlet完成操作。如果servlet第一次被访问,那么将执行init()方法,初始化,然后调用service(),service()决定要调用doGet()还是doPost()方法,完成之后,这个线程就结束了。所以对于servlet来说,是属于单例多线程的;单例指的是servlet只有一个实例,但是容器却可以启动多个线程让这个servlet完成服务。