Ответ 1
Ни один из них не лучший подход. Сервлеты намерены прослушивать HTTP-события (HTTP-запросы), а не события развертывания (запуск/выключение).
CDI/JSF/EJB недоступен? Используйте ServletContextListener
@WebListener
public class Config implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
// Do stuff during webapp startup.
}
public void contextDestroyed(ServletContextEvent event) {
// Do stuff during webapp shutdown.
}
}
Чтобы хранить и получать объекты в области приложения (чтобы все сервлеты могли обращаться к ним), используйте 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 на ${config}
. Таким образом, вы можете сделать его простым bean.
Если вы еще не находитесь в Servlet 3.0 и не можете обновить и, следовательно, не можете использовать аннотацию @WebListener
, вам необходимо вручную зарегистрировать ее в /WEB-INF/web.xml
, как показано ниже:
<listener>
<listener-class>com.example.Config</listener-class>
</listener>
Доступен 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 startup.
}
public void destroy(@Observes @Destroyed(ApplicationScoped.class) ServletContext context) {
// Do stuff during webapp shutdown.
}
}
Это доступно в сервлете через @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 startup.
}
@PreDestroy
public void destroy() {
// Do stuff during webapp shutdown.
}
}
Это доступно через #{config}
в EL.
Доступен EJB? Рассмотрим @Startup
@Singleton
@Startup
@Singleton
public class Config {
@PostConstruct
public void init() {
// Do stuff during webapp startup.
}
@PreDestroy
public void destroy() {
// Do stuff during webapp shutdown.
}
}
Это доступно в сервлете через @EJB
. Я говорю "считаю", потому что вы не должны злоупотреблять EJB ради запуска. Более того, a @Singleton
по умолчанию блокирует чтение и запись и в первую очередь предназначен для транзакционных материалов, таких как планирование фоновых заданий.