2014-12-05 2 views
1

Я показываю некоторые данные статистики как услугу REST с использованием Джерси. Я использую Weblogic@PostConstruct используется с Джерси 1.17, Weblogic

Однако каждый раз, когда я выполняю запрос на получение статистики System.out.println («In PostConstruct»); называется.

Это происходит, даже если я аннотируюсь рядом с дорогой @Stateless.

Это ведет себя как StorageService конкретизируется по каждому запросу (REQ области видимости)

Есть ли способ, чтобы Initialize вызывается только один раз и не создавать StorageService на каждом запросе?

@Path("/statistics") 
public class StorageService { 

    @Context 
    private ServletContext application; 

    StatisticsStorage statisticsStorage; 

    @PostConstruct 
    public void initialize() { 
     System.out.println("In PostConstruct"); 
     try { 
      statisticsStorage = new StatisticsStorage((String) application.getAttribute(AppProperties.PropKey.STATS_OUTPUT_PATH_PROP.toString())); 
     } catch (Exception sqle) { 
      sqle.printStackTrace(); 
     } 
    } 


    @GET 
    // The Java method will produce content identified by the MIME Media type "text/plain" 
    @Produces({MediaType.APPLICATION_JSON}) 
    public Domain getSnapshot() {} 

Благодаря

ответ

1

«Сфера» по умолчанию классов JAX-RS ресурсов является сферой по-запроса. Мы также можем зарегистрировать класс как одноэлементный. Различные реализации JAX-RS могут иметь другой способ, которым это может быть выполнено. Например, Apache Wink имеет @Scope(ScopeType.SINGLETON). Но единственным портативным способом является использование подкласса javax.ws.rs.core.Application. Что-то вроде:

@ApplicationPath("/api") 
public class MyApplication extends Application { 
    @Override 
    public Set<Class<?>> getClasses() { 
    } 
    @Override 
    public Set<Object> getSingletons() { 
     Set<Object> singletons = new HashSet<>(); 
     singletons.add(new StorageService()); 
     return singletons; 
    } 
} 

Все вернулись в getClasses() будет ресурс за запрос. И getSingletons() вернет ресурсы, которые являются «областью применения». Джерси никогда не попытается создать экземпляр класса, поэтому мы можем справиться со всей инициализацией.

С другой стороны, вы можете рассмотреть, если сделать этот класс одноэлементно является то, что вы действительно хотите. Делая это, это приведет к тому, что класс ресурсов будет состоять из состояния, и вам придется обрабатывать любые проблемы параллелизма.

Если все, что вы хотите сделать в @PostConstruct, создайте StatisticsStorage, возможно, лучший вариант - использовать фреймворк для инъекций, например Guice. Вот good Guice example(s). Или EE's CDI

2

Джерси конкретизирует класс по каждому запросу. Обратите внимание, что большинство вещей, которые вы можете комментировать с помощью @Context, зависят от запросов. Лучше всего сделать свой стат StatStorage статическим и инициализировать его по первому запросу (потребуется синхронизация). Может быть, что-то вроде этого:

public StorageService(@Context ServletContext application) { 
    super(servletConfig, request, httpServletRequest, uriInfo, httpHeaders, securityContext); 
    synchronized (this.getClass()) { 
     if (statisticsStorage == null) { 
      try { 
       statisticsStorage = new StatisticsStorage((String) application.getAttribute(AppProperties.PropKey.STATS_OUTPUT_PATH_PROP.toString())); 
      } catch (Exception sqle) { 
       sqle.printStackTrace(); 
      } 
     } 
    } 
} 
static StatisticsStorage statisticsStorage; 
Смежные вопросы