【发布时间】:2016-09-26 10:57:56
【问题描述】:
为了优化sql请求,我做了一个聚合其他服务消耗的服务,以避免不必要的调用。 (我的 webapp 的某些页面每天被调用数百万次,所以我想在每个请求上尽可能多次重用数据库查询的结果)
我创建的解决方案是这个:
我的服务有 @RequestScope 而不是默认范围(单例)
在我的服务中
@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”时第一个列表已被初始化。
我的问题是:
- 您如何看待这种做事方式?
- 我是否会因为每个请求都实例化我的服务而出现性能问题?
非常感谢!
朱利安
【问题讨论】:
-
为什么要使用请求范围的 bean 进行优化。每个请求都有自己的实例,没有重用。如果您真的想优化修复您的查询或使用缓存。我建议研究 Spring 可以为您做什么(以及如何缓存结果),而不是自己尝试破解某些东西。
-
它是优化的,因为一个相同的请求我多次使用相同的低级信息,这种处理方式有助于我重用服务层上已有的数据。我不打算针对 2 个不同的请求对其进行优化
-
如果您需要在单个请求中进行这样的优化,您可能需要重新考虑您的流程。在一个请求中,只咨询一个控制器,其他一切都是一个新请求。从您的描述来看,您似乎正在尝试优化您甚至没有测量过的东西,或者这确实是一个问题。看起来您正在尝试优化甚至可能不需要优化的东西。请记住:过早的优化是万恶之源。除了引入范围之外,可能还有更好(更简单?)的方法来改进事情。但首先要衡量、衡量、衡量。
-
接下来,如果数据被大量查询,当使用一个像样的数据库时,这将优化数据的获取或优化查询。
-
你说得对,我没有办法。事实上,我知道这样做可以减少数据库调用,这就是我想要这样做的原因,我的数据库服务器负载很重,所以如果我可以减少请求的数量,这对我来说是件好事。但我知道我这样做的方式不寻常,这就是我今天提出问题的原因:)
标签: java spring spring-mvc service scope