Мне нужно получить некоторую конфигурацию и где-то подключиться к внешним ресурсам / объектам / системам и сохранить их в области приложения.
Я вижу два способа настройки моего приложения:
init ()
в существующих сервлетах и требуемый код, а также сохранение всех сконструированных объектов внутри того же сервлета. init ()
для выполнения работы. Затем сохраняю созданные объекты в ServletContext
, чтобы поделиться им с другими моими сервлетами. Какой из вышеперечисленных подходов лучше? Есть ли лучший способ обмена объектами между сервлетами? Вызов их напрямую друг от друга или около того ...?
Ни один из них не является лучшим подходом. Сервлеты предназначены для прослушивания событий HTTP (HTTP-запросы), а не событий развертывания (запуск / завершение работы).
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 от $ {config}
. Так что вы также можете сделать его простым bean-компонентом.
@Observe
в 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 и не можете выполнить обновление, выберите другой подход.
@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.
@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
по умолчанию заблокирован для чтения / записи и в первую очередь предназначен для транзакционных операций, таких как планирование фоновых заданий.