Intereting Posts
Как точно сканировать IP-адрес и MAC-адрес всех устройств, подключенных к Wi-Fi в Android? Инъекция автоуведомленных зависимостей не удалась; Вложенное исключение – org.springframework.beans.factory.BeanCreationException: Заменить пробельные символы на пути? Должен ли я использовать DataInputStream или BufferedInputStream Как установить параметры для WS.post () в игре 2.1 Java Кто-нибудь еще поддерживал Лямбду-выражения на Java 7? Как высмеять статический метод void для исключения исключений из Powermock? Как получить имя JTextField, в котором размещен документ? подсчитывать экземпляры classа для каждого производного classа вход в консоль java Ячейки таблиц со строками HTML, непоследовательно отображаемые как многострочные OAuth – недопустимый токен: маркер запроса, используемый, когда он не разрешен Отправка данных JSONP и JSON? Почему шифрование RSA может возвращать разные результаты с помощью C # и Java? Guice: различия между Singleton.class и @Singleton

JSF инициализирует компонент области приложения при инициализации контекста

Я создаю веб-приложение JSF + Facelets, одним из которых является метод, который так часто сканирует каталог и индексирует любые изменения. Этот метод является частью компонента, который находится в области приложения. Я создал подclass TimerTask для вызова метода каждые X миллисекунд. Моя проблема заключается в том, чтобы инициализировать компонент. Я могу ссылаться на компонент на странице, и когда я иду на страницу, компонент инициализируется и работает по назначению; вместо этого я хотел бы, чтобы компонент был инициализирован при инициализации веб-контекста, так что для запуска метода индексирования не требуется посещать страницу. Google показала несколько людей, которые хотят эту функциональность, но никаких реальных решений за пределами интеграции с Spring, которые я действительно не хочу делать, чтобы получить эту функциональность.

Я пробовал играть с обоими сервлетами, на которых установлен «load-on-startup», и ServletContextListener, чтобы добиться успеха, и не смог получить правильную настройку, потому что отсутствует FacesContext ansible или потому, что я не могу ссылаться на компонент из среды JSF.

Есть ли способ получить JSF-компонент, инициализированный при запуске веб-приложения?

Если ваш код вызывает FacesContext , он не будет работать за пределами streamа, связанного с жизненным циклом запроса JSF. Объект FacesContext создается для каждого запроса и размещается в конце запроса. Причина, по которой вы можете получить его через статический вызов, состоит в том, что он установлен в ThreadLocal в начале запроса. Жизненный цикл FacesContext не имеет отношения к циклу ServletContext.

Возможно, этого недостаточно (похоже, что вы уже на этом пути), но вы должны иметь возможность использовать ServletContextListener, чтобы делать то, что вы хотите. Просто убедитесь, что любые обращения к FacesContext хранятся в streamе запросов JSP.

web.xml:

 appobj.MyApplicationContextListener  

Реализация:

 public class MyApplicationContextListener implements ServletContextListener { private static final String FOO = "foo"; public void contextInitialized(ServletContextEvent event) { MyObject myObject = new MyObject(); event.getServletContext().setAttribute(FOO, myObject); } public void contextDestroyed(ServletContextEvent event) { MyObject myObject = (MyObject) event.getServletContext().getAttribute( FOO); try { event.getServletContext().removeAttribute(FOO); } finally { myObject.dispose(); } } } 

Вы можете адресовать этот объект через область приложения JSF (или просто напрямую, если никакая другая переменная не существует с тем же именем):

     

Если вы хотите получить объект в управляемом компоненте JSF, вы можете получить его из ExternalContext :

 FacesContext.getCurrentInstance() .getExternalContext().getApplicationMap().get("foo"); 

Используя прослушиватели или загрузку при запуске, попробуйте следующее: http://www.thoughtsabout.net/blog/archives/000033.html

В JSF 2+ вы можете использовать SystemEventListener для его обработки. Вы должны установить его для принятия решения в PostConstructApplicationEvent для его инициализации.

   listeners.SystemEventListenerImpl   javax.faces.event.PostConstructApplicationEvent   

Реализация будет выглядеть примерно так:

 public class SystemEventListenerImpl implements SystemEventListener { @Override public void processEvent(SystemEvent event) throws AbortProcessingException { Application application = (Application) event.getSource(); //TODO } @Override public boolean isListenerForSource(Object source) { return (source instanceof Application); } } 

Это позволит вам сделать намного больше, чем просто передать значение.