什么是属性?
属性和参数
属性的3个作用域
属性API
属性不好的一面
1、到底什么是属性(Attribute)?
属性就是一个对象,可以被设置(bound,也可以叫绑定)到另外三个servlet API对象ServletContext、HttpSession、HttpServletRequest中。可以把它简单地认为是一个名/值对,名是String、值是object。在实际中,我们并不知道也不关心它具体如何实现,我们关心的只是属性所在的作用域。
2、属性不是参数(Parameter)!
笔记1中的参数——请求参数:
笔记7中的参数——servlet初始化参数:
以及,上下文初始化参数参数:
3、属性的3个作用域:
- ServletContext属性(上下文属性)——Web应用中的每一部分都能访问
- HttpSession属性(会话属性)——能访问特定的HttpSession的部分才可访问
- HttpServletRequest属性(请求属性)——能访问特定的ServletRequest的部分才可访问
4、设置、访问属性的API——每个接口(ServletContext、HttpS......)的属性API完全相同
关于Enumeration,参见Java-Enumeration总结 by IAMTJW
5、属性不好的一面.··.```..``..`.`.`...`..
- 上下文属性不是线程安全的!一个上下文属性可能同时被多个servlet所更改、访问。糟糕的解决方案是给doGet(或者是其它方法)加上synchronized,这样并不能解决问题,原因在于关于synchronized只能防止同一个servlet中的其他线程访问上下文属性,但是不能阻止另外一个servlet访问。关于ynchronized参见java synchronized详解 by Gang.Wang。
正确的方法是:对上下文加锁,而不是对servlet加锁。怎么实现呢?看下面的代码:
- 会话属性是线程安全的吗?不是,因为用户可能打开好几个浏览器窗口...解决方案类似:
- 只有请求属性和局部变量是线程安全的!
要注意的是servlet的实例域不是线程安全的,除非实现了SingleThreadModel,或者是同步服务方法,但这是十分糟糕的做法,会让Web应用的效率变得非常差,所以,一个servlet根本不该有实例变量,有也应该是final的,如果真的需要在多个线程中共享一些东西,那就把它加到合适的作用域上去。
时间: 2024-10-18 13:19:01