2016-09-26 3 views
1

Чтобы оптимизировать sql-запрос, я сделал службу, которая объединяет другие сервисы, чтобы избежать ненужных вызовов. (Некоторые страницы моего веб-приложение называется миллионы раз в день, поэтому я хочу, чтобы повторно использовать результаты запросов базы данных столько раз, сколько возможно по каждому запросу)Spring 4 @Service с @RequestScope

Решение создать этот один:

Мои служба @RequestScope вместо рамки по умолчанию (Singleton)

В MyService

@Service 
@RequestScope 
public MyService { 

private int param; 

@Autowired 
private OtherService otherService; 

@Autowired 
private OtherService2 otherService2; 

private List<Elements> elements; 

private List<OtherElements> otherElements; 

public void init(int param) { 
    this.param = param; 
} 

public List<Elements> getElements() { 

    if(this.elements == null) { 
     //Init elements 
     this.elements = otherService.getElements(param); 
    } 

    return this.elements; 

} 

public List<OtherElements> getOtherElements() { 

    if(this.otherElements == null) { 
     //Init otherElements 
     this.otherElements = otherService2.getOtherElements(param); 
    } 

    return this.otherElements; 

} 

public String getMainTextPres() { 

    //Need to use lElements; 
    List<Elements> elts = this.getElements(); 

    .... 

    return myString; 

} 

public String getSecondTextPres() { 

    //Need to use lElements; 
    List<Elements> elts = this.getElements(); 
    //Also Need to use lElements; 
    List<OtherElements> otherElts = this.getOtherElements();   

    .... 

    return myString; 

} 
} 

В мой контроллер:

public class myController { 
@Autowired MyService myService; 

@RequestMapping... 
public ModelAndView myFunction(int param) { 
myService.init(param); 

String mainTextPres = myService.getMainTextPres(); 

String secondTextPres = myService.getSecondTextPres(); 

} 

@OtherRequestMapping... 
public ModelAndView myFunction(int param) { 
myService.init(param); 

String secondTextPres = myService.getSecondTextPres(); 

} 
} 

Конечно, я упростил свой пример, потому что использование MYSERVICE много других элементов, и я защищать инициализацию членов его атрибутов

Этот метод имеет то преимущество, что делает отложенную загрузку атрибутов только тогда, когда я нужно их. Если где-то в моем проекте (в том же или другом контроллере) мне нужен только SecondTextPres, тогда вызов «getSecondTextPres» будет инициализировать оба списка, которые не имеют места в моем примере, потому что первый список был инициализирован при вызове «getMainTextPres».

Мой вопрос являются:

  • Что вы думаете об этом способ делать вещи?
  • Могу ли я иметь проблемы с производительностью, потому что я выполняю свою службу по каждому запросу?

Большое спасибо!

Julien

+0

И почему это было бы оптимизировано с использованием компонента с запросом. Каждый запрос имеет свой собственный экземпляр, в нем нет ничего повторного использования. Если вы действительно хотите оптимизировать исправление своих запросов или использовать кеш. Я предлагаю изучить, что Spring может сделать для вас (и как вы можете кэшировать результаты) вместо того, чтобы пытаться взломать что-то вместе. –

+0

Он оптимизирован, потому что один и тот же запрос я использую несколько раз с той же информацией низкого уровня, и этот способ делать вещи помогает мне повторно использовать данные, которые у меня уже есть на уровне обслуживания. Я не намерен оптимизировать его по двум запросам на разные запросы –

+0

Если вам нужна такая оптимизация в одном запросе, возможно, вам придется пересмотреть свой поток. В запросе проконсультируется только один контроллер, все остальное - новый запрос. Судя по вашему описанию, кажется, что вы пытаетесь оптимизировать то, что вы даже не измеряли, или это действительно проблема. Похоже, вы пытаетесь оптимизировать вещи, которые даже не нуждаются в оптимизации. Помните: * преждевременная оптимизация - это корень всего зла *. Вместо того, чтобы вводить области видимости, есть, вероятно, лучшие (и более простые?) Способы улучшить ситуацию. Но сначала измерьте, измерьте, измерьте. –

ответ

0

Я думаю, что ваша идея не собирается летать. Я называю тот же или другой контроллер, это будет другой запрос - в этом случае будет создан новый bean-элемент (элементы и другие элементы снова пустуют).

Вы думали о кешировании? Весна имеет хорошую поддержку, где вы можете определить срок действия кеша и т. Д.

+0

Благодарим вас за ответ. На самом деле, я хочу/должен иметь несколько экземпляров, потому что каждый запрос отличается (зависит от параметров) –

+0

О кеше: я упростил свой пример, поскольку данные получены из разных источников. Основные данные, которые я использую, поступают из базы данных с миллионами записей, поэтому я не уверен, что у меня будет хороший кэш (недостаточно памяти) –

+0

«зависеть от параметров», это, вероятно, неправильное предположение. Вам просто нужна услуга, которая может предоставлять разные ответы для разных параметров и не сохраняет никакого внутреннего состояния. – Observer

0

Не совсем ясно, что именно вы хотите оптимизировать для создания экземпляра службы в области запроса? Если вы беспокоитесь о печати стопки памяти, вы можете легко измерить ее с помощью JMX или VisualVM.

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

Это решение позволит вам сэкономить разумное количество ресурсов, так как вы не создадите экземпляр возможного графа объектов на каждом вызове и не будете требовать, чтобы GC очистил предмет после выполнения запроса.

Правило большого пальца состоит в том, чтобы думать, почему именно вам нужен конкретный класс, созданный при каждом вызове, и если он не поддерживает какое-либо состояние для вызова, сделайте его Singleton.

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

+0

Спасибо. Я думаю, что я не был достаточно ясен. Каждый день одна и та же страница «шаблон» загружается в миллионы раз, но с разными данными. Каждый раз, когда страница загружается, у меня есть около десяти выходных данных, которые я использую для создания информации, возвращаемой клиенту. Моя цель, когда я делал эту услугу, заключалась в том, чтобы избежать сбора в базе данных (или других источников) одних и тех же данных несколько раз для создания выходных данных. –

+0

Кроме того, у меня есть другие страницы (и другие контроллеры), которые иногда могут использовать эту услугу для получения информации. Например, у меня может быть другой контроллер, который должен только распечатать secondTextPres. –

+0

@JulienO, я бы сказал, вам нужно разделить эту службу на две отдельные вещи: кеш и фактическое обслуживание. Первый может быть предоставлен на разных уровнях (DB, HTTP, Service), и я не могу предложить, какой из них вы должны использовать, не зная своего приложения очень хорошо. Пожалуйста, копайте в типы кеша и решите, какой из них вам подходит. Второе должно быть сделано чистым и предусмотрено как одноэлементное. – Observer