使用大量 AOP 请求作用域 bean 时出现性能问题

2024-01-21

我正在使用 Spring 3 开发一个半大型应用程序,并且在同时处理数百个用户时遇到性能问题。我正在使用 Spring 的 AOP 代理来使用多个请求范围的 bean,并且我可以看到,每次我对其中一个 bean 调用任何方法时,都会调用 CGLIB 拦截器,然后调用 AbstractBeanFactory.getBean(),后者再调用 add()现有 Spring bean 的同步集。由于此 add() 是同步的,因此当有数千个调用都等待添加到同一列表时,它会有效地锁定服务器。

有没有办法使用请求范围的 bean 来解决这个问题?我在Spring文档中读到,如果bean实现任何接口(http://static.springsource.org/spring/docs/2.0.0/reference/aop.html#d0e9015),则不使用CGLIB,但我的请求范围bean所有人都实施了一种(实际上是同一种),而且这种情况仍在发生。我确实需要将这些 Bean 限定在请求范围内,因为它们的某些字段是在应用程序的某一部分针对特定请求计算的,然后我使用 SpEL 在同一请求期间在应用程序的不同部分获取它们的值。我想如果我将 beans 原型设置为作用域,那么当我第二次使用 SpEL 获取它们时,我就会得到一个新的对象。

这是说明我的问题的代码示例。请参阅最后两行评论,描述我到底遇到问题的地方。

<!-- Spring config -->
<bean name="someBean" class="some.custom.class.SomeClass" scope="request">
    <property name="property1" value="value1"/>
    <property name="property2" value="value2"/>
    <aop:scoped-proxy/>
</bean>

<bean name="executingClass" class="some.other.custom.class.ExecutingClass" scope="singleton">
    <property name="myBean" ref="someBean" />
</bean>


public Interface SomeInterface {
    public String getProperty1();
    public void setProperty1(String property);
    public String getProperty2();
    public void setProperty2(String property);
}

public class SomeClass implements SomeInterface {
    private String property1;
    private String property2;

    public String getProperty1() { return propery1; }
    public void setProperty1(String property) { property1=property;}

    public String getProperty2() { return propery2; }
    public void setProperty2(String property) { property2=property;}
}


public class ExecutingClass {
    private SomeInterface myBean;

    public void execute() {
        String property = myBean.getProperty1(); // CGLIB interceptor is invoked here, registering myBean as a bean
        String otherProperty = myBean.getProperty2(); // CGLIB interceptor is invoked here too!  Seems like this is unnecessary. And it's killing my app.
    }
}

我的想法是以下之一:

  • 我可以在不代理对 bean 进行的每个方法调用的情况下发出范围限定的 Spring Bean 请求吗?并且不将每个方法标记为“最终”?

or...

  • 我可以重写 Spring 的 bean 工厂来实现 Bean 缓存吗?该缓存将在调用 AbstractBeanFactory.getBean() 之前检查 bean 是否已缓存?如果是这样,我在哪里配置 Spring 来使用我的自定义 bean 工厂?

事实证明,Spring 实际上确实在请求属性中缓存了请求范围的 bean。如果您好奇,请看一下 AbstractRequestAttributesScope,它是 RequestScope 的扩展:

public Object get(String name, ObjectFactory objectFactory) {
    RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();
    Object scopedObject = attributes.getAttribute(name, getScope());
    if (scopedObject == null) {
        scopedObject = objectFactory.getObject();
        attributes.setAttribute(name, scopedObject, getScope());
    }
    return scopedObject;
}

因此,虽然由于 aop 代理,AbstractBeanFactory.getBean() 在每个 bean 方法调用中都会被调用,但如果在请求属性中尚未找到该 bean,它只会导致 Spring 添加到该同步集。

避免对我的请求作用域 bean 上的每个方法调用进行代理仍然会降低复杂性,但有了此缓存,对性能的影响将很小。我认为如果我想要大量请求范围的 bean 并且仍然一次服务大量请求,那么我将不得不忍受缓慢的性能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用大量 AOP 请求作用域 bean 时出现性能问题 的相关文章

随机推荐

  • 无法使用 UPDATE 更改 MySQL 上的用户密码

    在 MySql 5 7 17 下 上述指令不起作用 并且我总是没有收到任何反馈或以下错误消息 错误 1064 42000 您的 SQL 语法有错误 检查与您的 MySQL 服务器版本相对应的手册 了解在 UPDATE mysql user
  • 如何使用 ps -axl 查找 Linux 上运行的 Java 线程?

    我有一个正在运行的 JVM 有两个线程 是否可以使用 ps axl 在我的 Linux 操作系统上查看这些正在运行的线程 我试图找出操作系统赋予我的线程的优先级 有关此其他问题的更多信息here https stackoverflow co
  • Error 方法内的 fmt.Sprint(e) 产生的无限循环

    根据四十四十的回复这个问题 https stackoverflow com questions 27474907 error infinite loop fmt Sprint e 将会通知e Error 转换值e to a string 如
  • 更改 pandas 中箱线图的面色

    我需要更改使用绘制的箱线图的颜色pandas实用功能 我可以使用以下命令更改大多数属性color争论但不知道如何改变facecolor盒子的 有人知道该怎么做吗 import pandas as pd import numpy as np
  • 将 SAML 身份验证添加到 .net WebAPI

    我需要将 SAML 身份验证添加到我的 Web 应用程序 WebAPI 后端 Angular 前端 并使用 Azure AD 作为我的身份提供商 我计划使用 Sustainsys Saml2 库 但我不确定如何正确使用该库提供的方法 我已将
  • 计算 Modbus RTU CRC 16

    我正在实现一个软件 可以通过串行方式读取和写入 Modbus RTU 协议中的数据 为此 我需要计算字节字符串末尾的两个 CRC 字节 但我无法执行此操作 在网上搜索 我发现两个函数似乎可以正确计算 CRC WORD CRC16 const
  • 如何使用 Google API PHP 客户端库和 Youtube API V3 将视频上传到 YouTube?

    尝试简单地使用上传视频Google API PHP 客户端 最新版本 1 1 6 https github com google google api php client releases but Youtube API V3 中的代码
  • 填充/大小/边距,当使用 ToolstripControlHost 作为弹出控件时

    我正在使用 VB2008 Express 我一直在研究一个 弹出窗口 来选择日期范围 DateTimePicker 并不理想 因为其目的是选择一个日期范围 该范围始终是一整周 从星期日到星期六 控制效果很好 我对此感到非常自豪 我的问题与使
  • React Suspense 未按预期工作

    我想在我的Powers正在获取 未定义 我实施了React Suspense按照我的逻辑 使用代码
  • 如何在 DataGrid 中的按钮上设置 CssClass

    我在 DataGrid 中有一个 ButtonColumn
  • React Native - Redux - 无法访问状态变量

    情况 我正在尝试在我的 React Native 应用程序中实现 redux 状态管理 下面的例子非常简单 当用户登录时 应用程序会将授权令牌保存到 keychain keystore 以及 redux store 中 按照教程 我创建了以
  • 在字符串插值中转义美元符号

    如何在字符串插值中转义美元符号 def getCompanion name String Class forName s my package name gt error unclosed string literal 只需加倍即可 sca
  • 嵌入式与非嵌入式 Java 服务器

    我正在开发一个 Java 项目 并一直使用 Tomcat 服务器进行本地测试 然而我正要升级到 Heroku 并发现一篇文章 https devcenter heroku com articles create a java web app
  • Python:通过局域网连接?

    只是这个问题的前言 我不知道我在做什么 所以请原谅任何愚蠢的行为 我正在制作一个基于套接字的聊天室 我想在本地网络上使用它 我爸爸的计算机和我的计算机通过同一个 wifi 连接 这是服务器代码 import socket import sy
  • 在抽象基类中定义的 clr 属性的 Setter,仅具有 getter

    有没有办法为在抽象基类中定义的仅具有 getter 的 clr property 声明 setter 反之亦然 abstract class BaseClass public abstract string Test get class C
  • 仅命名“gitbranch--list”选项?

    git branch输出分支列表 但也输出其他以人为本的绒毛 例如星号 在当前分支旁边 git branch HEAD detached at origin master branch foo some branch bar 如何获得更多机
  • 如何使用批处理或 PowerShell 从文本文件中删除换行符

    本质上 我想从 file txt 中读取内容 apple banana carrot 并写入 newfile txt 以便它包含内容 apple banana carrot 我需要在没有安装权限的 Windows 计算机上执行此操作 I t
  • SQL 数据库系统中临时表的用例有哪些?

    使用临时表的主要目的是什么 我想知道临时表在小型和大型公司的实际软件中的实际和商业用途 根据我的经验 临时表通常用于存储一系列复杂的 CREATE 或 UPDATE 查询中的中间计算 这些查询会产生某种分析结果 一个示例可能是为 OLAP
  • const 成员函数优先于返回值类型匹配

    In Y test1 非常数X operator void 优先于看似更好的匹配 X operator bool const 这是为什么 标准中在哪里描述了这种现象 include
  • 使用大量 AOP 请求作用域 bean 时出现性能问题

    我正在使用 Spring 3 开发一个半大型应用程序 并且在同时处理数百个用户时遇到性能问题 我正在使用 Spring 的 AOP 代理来使用多个请求范围的 bean 并且我可以看到 每次我对其中一个 bean 调用任何方法时 都会调用 C