Servlet是单例吗?如何证明?属于懒汉式还是饿汉式
servlet是单例的,只需通过构造方法区证明,多次调用servlet,若构造方法只执行依稀,则说明servlet是单例的。
servlet默认是在使用时才会实例化,也就说这个单例属于懒汉式。
Servlet生命周期:
1、实例化 在第一次访问servlet的时候创建servlet对象,只调用一次。证明servlet对象在Tomcat中是单例。
2、初始化init()方法 创建完servlet对象的时候调用,只调用1次。
3、服务service()方法 每次发出请求是调用。调用N次
4、销毁 destroy()方法 销毁servlet对象的时候调用,停止服务器或者重新部署web应用时销毁servlet对象。只调用一次。
Servlet执行流程:
- 浏览器发送请求
- Tomcat服务器找到对应项目中web.xml,根据截取的servlet的访问路径检查web.xml是否存在匹配的url-pattern。
- 如果存在,找到web.xml中对应servlet配置的servlet-class属性。利用反射构造对象。调用构造方法实例化。
- 执行初始化方法init();
- 创建request,response对象,调用service方法。
- 返回数据
- 如果Tomcat服务器停止,调用destroy()方法。
Servlet的自动加载:
默认情况下,第一次访问servlet的时候创建servlet对象。如果servlet的构造方法或init方法中执行了比较多的逻辑代码,那么导致用户第一次访问sevrlet的时候比较慢。这时我们可以让servlet对象在Tomcat服务器启动时进行自动加载。参考代码如下。
<servlet>
<servlet-name>LifeDemo</servlet-name>
<servlet-class>com.itmayiedu.life.LifeDemo</servlet-class>
<!-- 让servlet对象自动加载 -->
<load-on-startup>1</load-on-startup> 注意: 整数值越大,创建优先级越低!!
</servlet>
Servlet线程安全吗?
如果多个线程同时访问servlet的共享数据,如成员变量,可能会引发线程安全问题,也就是说线程不安全。
解决办法:1、把使用到共享数据的代码块进行同步(用synchronized关键字进行同步)
2、尽量避免成员变量的使用,若必须使用,尽量缩小同步代码块的覆盖范围(在使用到成员变量处,家同步代码即可),避免导致效率的降低。
重定向和转发的区别
1、地址栏 转发不改变,重定向改变
2、跳转区域:转发只能转发到当前的web应用内的资源,重定向可以跳转到当前的web应用,也可以跳转道其他的web应用。
3、Request域,转发使用同一个request,重定向使用的不是同一个request域。