Использование специального автозапуска сервлета для инициализации при запуске и обмена данными приложения
Мне нужно получить некоторую конфигурацию и подключиться к внешним ресурсам / объектам / системам где-нибудь и сохранить его в области приложения.
Я вижу два способа настройки моего приложения:
- Переопределение
init()
в существующих сервлетах и требуемом коде и сохраняя все построенные объекты в этом же сервлете. - Наличие какого-то сервлета инициализации и использование его
init()
делать работу. Затем хранить созданные объекты вServletContext
поделиться этим с другими моими сервлетами.
Какой из вышеперечисленных является лучшим подходом? Есть ли лучший способ для обмена объектами между сервлетами? Звонить им напрямую друг от друга или так...?
1 ответ
Ни то, ни другое не является лучшим подходом. Сервлеты предназначены для прослушивания 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>
Чтобы сохранить и получить объекты в области приложения (чтобы все сервлеты могли получить к ним доступ), используйте 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}
, Таким образом, вы можете сделать это простым бобом.
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}
в 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.
}
}
Это доступно в сервлете через @EJB
, Я говорю "рассмотреть", потому что вы не должны злоупотреблять EJB ради запуска запуска. Кроме того, @Singleton
по умолчанию блокировка чтения / записи заблокирована и предназначена главным образом для транзакционных операций, таких как планирование фоновых заданий.