Jakarta サーブレットのライフサイクルを徹底解説!init・service・destroyの流れを初心者向けに紹介
生徒
「先生、Jakarta Servletにはライフサイクルってあると聞いたんですけど、それってどういう意味なんですか?」
先生
「サーブレットはWebアプリケーションで動作するコンポーネントなので、決まった流れに従って生成されて動きます。その流れをサーブレットのライフサイクルと呼びます。具体的には、init、service、destroyという三つの段階があるんです。」
生徒
「三つの段階…それぞれどんな役割なんですか?」
先生
「それでは、サーブレットのライフサイクルをひとつずつ丁寧に見ていきましょう。」
1. サーブレットのライフサイクルとは
サーブレットのライフサイクルとは、Webサーバー上でサーブレットが生成され、リクエスト処理を行い、最後に破棄されるまでの一連の流れを指します。Jakarta EEのサーブレット仕様では、このライフサイクルを明確に定義しており、開発者はその仕組みに従って処理を実装します。ライフサイクルを理解することで、効率的なリソース管理や安定したWebアプリケーションの動作を実現できます。
2. initメソッド(初期化処理)
サーブレットが初めて呼び出されるときに一度だけ実行されるのがinitメソッドです。このメソッドはサーブレットの初期化処理を行う場面で使用され、例えばデータベース接続の準備や設定ファイルの読み込みなどに利用されます。initは一度だけ呼ばれるため、時間のかかる処理をここにまとめておくことで、後のリクエスト処理を効率化できます。
@Override
public void init() throws ServletException {
// 初期化処理
System.out.println("サーブレットが初期化されました");
}
3. serviceメソッド(リクエスト処理の中心)
serviceメソッドは、クライアントからのリクエストがあるたびに実行されます。HTTPリクエストの種類(GETやPOSTなど)に応じてdoGetやdoPostといったメソッドを呼び出す仕組みになっています。通常、開発者はserviceを直接オーバーライドするのではなく、doGetやdoPostを実装して処理を記述します。
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.setContentType("text/html; charset=UTF-8");
response.getWriter().println("<h2>GETリクエストを処理しました</h2>");
}
この仕組みにより、サーブレットは複数のクライアントから同時にリクエストを受け取っても効率的に処理を分担できます。
4. destroyメソッド(終了処理)
サーブレットが不要になったときに呼び出されるのがdestroyメソッドです。Webアプリケーションの終了時やサーバーの停止時に実行され、データベース接続のクローズやキャッシュの保存など、リソースを解放する処理を記述します。destroyを正しく実装しておくことで、メモリリークを防ぎ、システム全体の安定性を高められます。
@Override
public void destroy() {
// 終了処理
System.out.println("サーブレットが破棄されました");
}
5. ライフサイクルの流れを整理
サーブレットのライフサイクルは、次のような流れになります。
- Webアプリケーションが起動すると、必要に応じてサーブレットインスタンスが生成される
- 最初の一回だけ
initメソッドが呼ばれて初期化が行われる - 以降、クライアントからリクエストが来るたびに
serviceメソッドが実行される - アプリケーション終了時やサーブレットが不要になったときに
destroyメソッドが呼ばれる
この流れを理解することで、どの処理をどこに記述すべきか判断できるようになります。
6. ライフサイクルを意識した開発のポイント
サーブレットのライフサイクルを意識して開発することで、パフォーマンスや保守性が大きく向上します。例えば、初期化処理をinitにまとめることでリクエスト処理の高速化が可能になります。また、終了処理をdestroyに記述することでリソースの無駄を防げます。初心者のうちは、何度もリクエストを実行してログ出力を確認することでライフサイクルの動きを体感すると理解しやすいでしょう。
7. 実際の動作イメージ
例えば、以下のようにサーブレットを実装してサーバーを起動すると、最初に一度だけinitが呼ばれ、ブラウザからアクセスするたびにserviceが呼ばれます。そしてサーバーを停止するとdestroyが呼ばれる、という流れを確認できます。
public class LifeCycleServlet extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("init実行");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.getWriter().println("service実行中");
}
@Override
public void destroy() {
System.out.println("destroy実行");
}
}
まとめ
今回の記事では、Jakarta サーブレットがどのようなライフサイクルに沿って動作しているのかを、初心者にもわかりやすく整理しました。サーブレットは通常のJavaクラスとは違い、Webアプリケーションの中で特定の流れに従って生成・実行・破棄されるという特徴を持っています。この流れを理解することは、安定したWebアプリケーションを構築するために欠かせない重要な知識です。特に、init・service・destroyという三つのメソッドがサーブレットの動きを決める中心であり、それぞれが別々の目的と役割を持つため、正しい使い分けを意識することが大切になります。 initでは初回処理として必要な準備を行い、serviceではアクセスごとのリクエスト処理を担当し、destroyではリソース解放を担当します。この流れを意識することで、必要な場所に必要な処理を配置できるようになり、複数ユーザーからのアクセスが同時に行われる場面でも安定した動作を維持できます。また、データベースと連携するアプリケーション場合には、initで接続準備を行い、destroyで解放するという設計が一般的です。こうした構造は保守性やパフォーマンスの向上にもつながり、初心者でも一歩進んだ設計を実践できるようになります。 さらに、ライフサイクルを理解することは、サーブレットの動きを可視化して学ぶうえでも大きな助けとなります。ログ出力を使って動作を確認することは特に効果的で、どのタイミングでどのメソッドが呼ばれているのかが感覚的に理解できるため、初心者にとって学習しやすいポイントです。以下に、記事の内容を踏まえてライフサイクルの動きを確認できる簡単なサンプルコードを掲載します。
サンプルプログラム:ライフサイクルをログで確認するサーブレット例
@WebServlet("/lifecycle")
public class SampleLifeServlet extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("initメソッドが実行されました(初期化処理)");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.setContentType("text/plain; charset=UTF-8");
response.getWriter().println("serviceメソッドが実行されました(リクエスト処理)");
}
@Override
public void destroy() {
System.out.println("destroyメソッドが実行されました(終了処理)");
}
}
このように、init・service・destroyの動きを実際にログとして確認することで、サーブレットのライフサイクルがより鮮明にイメージできるようになります。そして、Webアプリケーションを構築するうえで、このライフサイクルを理解して設計することは非常に大切です。例えば、時間のかかる処理をserviceに何度も書いてしまうとパフォーマンスが低下する原因になりますが、initに集約することで改善することができます。また、destroyでリソースを確実に解放しておくことにより、長時間動作するシステムでも安定性と信頼性を保てます。 今回の内容をふり返ると、サーブレットは単にリクエストを受け取って処理するだけの仕組みではなく、Webサーバーと連携する中で「いつ準備し、いつ動き、いつ終了するのか」という明確な流れを持っています。この理解は、今後フィルターやリスナーといった他のJakarta EE技術を学ぶ際にも役立つ基礎となります。初心者のうちからライフサイクルへの意識を持っておくことで、より複雑なWebアプリケーションも構築しやすくなり、開発の幅が広がります。
生徒
「今日はサーブレットのライフサイクルの流れがよく分かりました!initが最初だけ、serviceがアクセスのたびに、destroyが最後に呼ばれるという仕組みがすごく整理できました。」
先生
「きちんと理解できたようでよかったです。特にserviceが中心となる部分なので、そこを意識するとより実践的な開発ができるようになりますよ。」
生徒
「initやdestroyに処理をまとめておくとパフォーマンスや安定性が上がるという話も納得でした。今後のアプリケーション設計にも活かせそうです。」
先生
「その通り。ライフサイクルを意識して設計できると、開発がとてもスムーズになりますし、保守のしやすさも大きく変わります。これからは実際にコードを書きながら動きを確認してみましょう。」
生徒
「はい!ログを出して実行順を確かめながら練習してみます!」
先生
「とても良い姿勢ですね。理解がさらに深まりますよ。」