首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring 4带有@RequestScope的服务

Spring 4带有@RequestScope的服务
EN

Stack Overflow用户
提问于 2016-09-26 10:57:56
回答 2查看 2.4K关注 0票数 1

为了优化sql请求,我创建了一个聚合其他服务消耗的服务,以避免不必要的调用。(我的webapp应用程序的某些页面每天被调用数百万次,因此我希望在每个请求中尽可能多地重用数据库查询的结果)

我创造的解决方案是这个:

我的服务有@RequestScope,而不是默认范围(Singleton)

在MyService中

代码语言:javascript
复制
@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;

}
}

在我的控制器里:

代码语言:javascript
复制
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”时初始化的。

我的问题是:

  • 你觉得这种做事方式怎么样?
  • 因为我对每个请求实例化了我的服务,所以可能会出现性能问题吗?

非常感谢!

朱利安

EN

回答 2

Stack Overflow用户

发布于 2016-09-26 11:17:57

我认为你的想法是行不通的。如果您调用相同或不同的控制器,这将是不同的请求--在这种情况下,将创建新bean (元素和其他元素再次为空)。

你有没有考虑过缓存?Spring提供了很好的支持,您可以在其中定义缓存过期等。

票数 0
EN

Stack Overflow用户

发布于 2016-09-26 11:24:37

我不太清楚您到底想在请求范围内优化什么?如果您对内存脚印感到烦恼,您可以很容易地通过JMX或VisualVM来测量它。

另一方面,您可以使所有服务调用都是纯的,即依赖于函数参数和(ofc)数据库状态,并将默认作用域实例化为Singleton。

这个决定将为您节省合理的资源,因为您不会在每个调用上实例化可能的大型对象图,并且在请求完成后不需要GC来清理。

经验法则是考虑为什么需要在每个调用上实例化特定的类,如果它没有保持任何特定的调用状态,那么就让它成为Singleton。

说到懒惰加载,总是有助于思考最坏的情况重复了100次。它是否真的为您节省了与加载一次和整个容器生命周期相比较的东西。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39701043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档