特別なオートスタートサーブレットを使用して、起動時に初期化し、アプリケーションデータを共有する
-
28-09-2019 - |
質問
構成を取得し、どこかに外部リソース/オブジェクト/システムに接続し、アプリケーションスコープに保存する必要があります。
アプリケーションをセットアップする2つの方法が表示されます。
- オーバーライド
init()
既存のサーブレットと必要なコードで、同じサーブレット内に構築されたすべてのオブジェクトを保持します。 - 何らかの初期化サーブレットを持っていて、その使用
init()
仕事をするために。次に、作成したオブジェクトをに保存しますServletContext
私の他のサーブレットと共有します。
上からどちらがより良いアプローチですか?サーブレット間でオブジェクトを共有するより良い方法はありますか?互いに直接それらを呼び出しますか...?
解決
どちらもより良いアプローチではありません。サーブレットは、展開イベント(スタートアップ/シャットダウン)ではなく、HTTPイベント(HTTPリクエスト)で聞くことを目的としています。
CDI/JSF/EJBは利用できませんか?使用する ServletContextListener
@WebListener
public class Config implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
// Do stuff during webapp's startup.
}
public void contextDestroyed(ServletContextEvent event) {
// Do stuff during webapp's shutdown.
}
}
まだサーブレット3.0にいない場合、アップグレードできないため、使用できない場合 @WebListener
注釈、その後、手動で登録する必要があります /WEB-INF/web.xml
以下のように:
<listener>
<listener-class>com.example.Config</listener-class>
</listener>
アプリケーションスコープにオブジェクトを保存および取得するには(すべてのサーブレットがアクセスできるように)、使用してください。 ServletContext#setAttribute()
と #getAttribute()
.
リスナーがアプリケーションの範囲に自らを保存できる例は次のとおりです。
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("config", this);
// ...
}
そして、それをサーブレットで取得します:
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
Config config = (Config) getServletContext().getAttribute("config");
// ...
}
また、JSP El byで利用できます ${config}
. 。だからあなたもそれを単純な豆にすることができます。
CDIは利用可能ですか?使用する @Observes
の上 ApplicationScoped.class
import javax.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class Config {
public void init(@Observes @Initialized(ApplicationScoped.class) ServletContext context) {
// Do stuff during webapp's startup.
}
public void destroy(@Observes @Destroyed(ApplicationScoped.class) ServletContext context) {
// Do stuff during webapp's shutdown.
}
}
これは、サーブレットで使用できます @Inject
. 。必要に応じて作ってください @Named
だからそれは介して利用可能です #{config}
エルでも。
これは、CDI 1.1以降、これが新しいことであることに注意してください。まだCDI 1.0を使用していて、アップグレードできない場合は、別のアプローチを選択してください。
JSFが利用可能ですか?使用する @ManagedBean(eager=true)
import javax.faces.bean.ManagedBean
import javax.faces.bean.ApplicationScoped;
@ManagedBean(eager=true)
@ApplicationScoped
public class Config {
@PostConstruct
public void init() {
// Do stuff during webapp's startup.
}
@PreDestroy
public void destroy() {
// Do stuff during webapp's shutdown.
}
}
これは経由で利用できます #{config}
エルでも。
EJBは利用可能ですか?検討 @Startup
@Singleton
@Startup
@Singleton
public class Config {
@PostConstruct
public void init() {
// Do stuff during webapp's startup.
}
@PreDestroy
public void destroy() {
// Do stuff during webapp's shutdown.
}
}
これは、サーブレットで使用できます @EJB
. 。スタートアップフックのためにEJBを乱用してはいけないからです。さらに、a @Singleton
デフォルトでは、読み取り/書き込みがロックされており、主にバックグラウンドジョブのスケジューリングなどのトランザクションのものを目的としています。