باستخدام Servlet Servlet التلقائي الخاص للتهيئة على بدء التشغيل ومشاركة بيانات التطبيق

StackOverflow https://stackoverflow.com/questions/3468150

سؤال

أحتاج إلى الحصول على بعض التكوين والاتصال بالموارد/الكائنات/الأنظمة الخارجية في مكان ما وتخزينها في نطاق التطبيق.

أستطيع أن أرى طريقتان لإعداد طلبي:

  • تجاوز init() في servlets الحالية والرمز المطلوب هناك والحفاظ على جميع الكائنات التي تم بناؤها داخل نفس servlet.
  • وجود نوع من servlet التهيئة واستخدامها init() للقيام بالعمل. ثم تخزين الأشياء التي تم إنشاؤها في ServletContext لمشاركتها مع servlets الأخرى.

أي من أعلاه هو نهج أفضل؟ هل هناك طريقة أفضل لتبادل الكائنات بين servlets؟ استدعائهم مباشرة من بعضهم البعض أو نحو ذلك ...؟

هل كانت مفيدة؟

المحلول

لا شيء من كليهما هو النهج الأفضل. تهدف Servlets إلى الاستماع إلى أحداث 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.
    }

}

إذا لم تكن على Servlet 3.0 حتى الآن ولا يمكنك الترقية ، وبالتالي لا يمكنك الاستخدام @WebListener التعليق التوضيحي ، ثم تحتاج إلى تسجيله يدويًا /WEB-INF/web.xml مثل أدناه:

<listener>
    <listener-class>com.example.Config</listener-class>
</listener>

لتخزين والحصول على كائنات في نطاق التطبيق (بحيث يمكن لجميع servlets الوصول إليها) ، استخدمها ServletContext#setAttribute() و #getAttribute().

إليك مثال يتيح للمستمع متجر نفسه في نطاق التطبيق:

    public void contextInitialized(ServletContextEvent event) {
        event.getServletContext().setAttribute("config", this);
        // ...
    }

ثم الحصول عليها في servlet:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        Config config = (Config) getServletContext().getAttribute("config");
        // ...
    }

إنه متوفر أيضًا في JSP EL بواسطة ${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.
    }
}

هذا متاح في servlet عبر @Inject. اجعله إذا لزم الأمر أيضًا @Named لذلك فهو متاح عبر #{config} في EL كذلك.

يجب الإشارة إلى أن هذا جديد منذ 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} في EL كذلك.


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.
    }
}

هذا متاح في servlet عبر @EJB. أنا أقول "فكر" ، لأنه يجب ألا تسيء إلى EJB من أجل خطاف بدء التشغيل. علاوة على ذلك ، أ @Singleton يتم تأمين القراءة/الكتابة بشكل افتراضي ومن المقصود في المقام الأول للأشياء المعاملة مثل جدولة وظائف الخلفية.

أنظر أيضا:

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top