JSF инициализирует компонент области приложения при инициализации контекста - PullRequest
16 голосов
/ 24 ноября 2008

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

Я попытался поиграть как с сервлетами, у которых установлен режим «загрузка при запуске», так и с ServletContextListener, чтобы добиться успеха, и не смог правильно настроить его, так как нет Доступен FacesContext или я не могу сослаться на bean-компонент из среды JSF.

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

Ответы [ 3 ]

14 голосов
/ 27 ноября 2008

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

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

web.xml:

<listener>
    <listener-class>appobj.MyApplicationContextListener</listener-class>
</listener>

Реализация:

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 (или просто напрямую, если не существует другой переменной с таким именем):

<f:view>
    <h:outputText value="#{applicationScope.foo.value}" />
    <h:outputText value="#{foo.value}" />
</f:view>

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

FacesContext.getCurrentInstance()
            .getExternalContext().getApplicationMap().get("foo");
0 голосов
/ 13 июля 2012

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

<system-event-listener>
    <system-event-listener-class>
     listeners.SystemEventListenerImpl
    </system-event-listener-class>
    <system-event-class>
     javax.faces.event.PostConstructApplicationEvent
    </system-event-class>                       
</system-event-listener>

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

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);
  }
}

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

0 голосов
/ 24 ноября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...