一个servlet的生命周期由部署servlet的容器来控制。当一个请求映射到一个servlet时,该容器执行
下列步骤。
1. 如果一个servlet的实例并不存在,Web容器
a. 加载servlet类。
b. 创建一个servlet类的实例。
c. 调用init初始化servlet实例。该初始化过程将在初始化servlet中讲述。
2. 调用service方法,传递一个请求和响应对象。服务方法将在编写服务方法中讲述。
如果该容器要移除这个servlet,可调用servlet的destroy方法来结束该servlet。销毁servlet,gc回
收占用内存
file://web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Copyright 2004 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<web-app>
<servlet>
<servlet-name>couner</servlet-name>
<servlet-class>InitCounter</servlet-class>
<init-param>
<param-name>initial</param-name>
<param-value>1000</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<!-- JSPC servlet mappings end -->
</web-app>
一个servlet 实例一旦加载,就开始处理对这个servlet的所有请求,换句话说就是一个servlet只生成
一个实例。这样的做法对于性能的提高很有好处,能够有效地降低系统开销,而且也能有效实现持久化
(例如数据库连接,cache数据)
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SimpleCounter extends HttpServlet {
int count = 0;
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
count++;
out.println("Since loading, this servlet has been accessed " +
count + " times.");
}
}
上例是一个简单的反映servlet持久化的例子,每个请求均增加本地变量count,然后打印显示。 但是
上例存在多线程风险,对于访问servlet的每个请求都可以看作是一个线程对象,他们均访问同一个
servlet实例,所以会出现并发问题。特别是存在对共享变量的读写操作时(例如上例的本地变量count
),这种危险性更大。
解决的办法是增加synchronized块。
PrintWriter out = res.getWriter();
synchronized(this) {
count++;
out.println("Since loading, this servlet has been accessed " +
count + " times.");
}
事实上,server上对每一个servlet的注册名称都对应servlet的一个实例,用来访问servlet的请求名
称决定哪个实例来处理请求
下列步骤。
1. 如果一个servlet的实例并不存在,Web容器
a. 加载servlet类。
b. 创建一个servlet类的实例。
c. 调用init初始化servlet实例。该初始化过程将在初始化servlet中讲述。
2. 调用service方法,传递一个请求和响应对象。服务方法将在编写服务方法中讲述。
如果该容器要移除这个servlet,可调用servlet的destroy方法来结束该servlet。销毁servlet,gc回
收占用内存
file://web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Copyright 2004 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<web-app>
<servlet>
<servlet-name>couner</servlet-name>
<servlet-class>InitCounter</servlet-class>
<init-param>
<param-name>initial</param-name>
<param-value>1000</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<!-- JSPC servlet mappings end -->
</web-app>
一个servlet 实例一旦加载,就开始处理对这个servlet的所有请求,换句话说就是一个servlet只生成
一个实例。这样的做法对于性能的提高很有好处,能够有效地降低系统开销,而且也能有效实现持久化
(例如数据库连接,cache数据)
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SimpleCounter extends HttpServlet {
int count = 0;
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
count++;
out.println("Since loading, this servlet has been accessed " +
count + " times.");
}
}
上例是一个简单的反映servlet持久化的例子,每个请求均增加本地变量count,然后打印显示。 但是
上例存在多线程风险,对于访问servlet的每个请求都可以看作是一个线程对象,他们均访问同一个
servlet实例,所以会出现并发问题。特别是存在对共享变量的读写操作时(例如上例的本地变量count
),这种危险性更大。
解决的办法是增加synchronized块。
PrintWriter out = res.getWriter();
synchronized(this) {
count++;
out.println("Since loading, this servlet has been accessed " +
count + " times.");
}
事实上,server上对每一个servlet的注册名称都对应servlet的一个实例,用来访问servlet的请求名
称决定哪个实例来处理请求