在内存消耗的情况下,Spring AOP的效率如何

时间:2016-05-13 19:02:07

标签: java spring-aop

在我的宠物项目中,我有一个长期工作,我想向用户显示有关该过程及其进展的状态。所以我正在将状态对象推送到JMS主题,从那里获取并提供给WS应用程序以将它们流式传输到有效的客户端。 我在Spring AOP(即@Before,@ AfterReturn)中编写了切入点,并调用我的服务将消息发送到主题。现在我想记录服务的状态,而不是在方法开始时或在方法内部返回之后。所以我调用了服务(它注入了jmsTamplete并获取了状态对象)。有没有办法最小化这些呼叫,以便我不能重复服务呼叫。 这是我的sudo代码。

public class Myservice{

UserDao userDao;
LegService legservice;
ProviderDao providerDao;
....
StatusServive statusServie;

//aop will call the same service to send info to JMS topic
fetchandCalculateLeg(){
    // here i called statusServie.senStatus(StatusObject);
    List<Users> = userDao.fetchUserInfo();
    // here i called statusServie.senStatus(StatusObject);
    ....
    loop: #forEachUser
    // here i called statusServie.senStatus(StatusObject);
    someList  = legservice.fecthLegInfoForEachUser();
    // here i called statusServie.senStatus(StatusObject);
    :endloop;
    ....
} }

目前我有3个长时间运行的任务,我在每个方法类中调用相同的内容。我想尽量减少电话。

EDIT1: 我也可以在调用方法上应用AOP,但在这种情况下性能如何?如何衡量AOP性能(在应用程序启动或创建代理对象期间消耗的内存量)。很抱歉问了这么多问题。

4 个答案:

答案 0 :(得分:4)

如果使用AOP,性能将优于此,因为它经过了良好的测试和优化框架来执行此类操作。无论如何,你可以通过减去开始和结束时间来检查。

您可以使用当前代码和AOP实现的代码来检查性能。这将是一件非常有趣的工作。执行以下操作设置开始和结束时间并减去。

System.currentTimeMillis()

语法上方,以毫秒为单位返回当前时间。请注意,虽然返回值的时间单位是毫秒,但值的粒度取决于底层操作系统,并且可能更大。例如,许多操作系统以几十毫秒为单位测量时间。 有关“计算机时间”和协调世界时(UTC)之间可能出现的轻微差异的讨论,请参阅类日期说明。

有许多AOP Opensource框架可用。

  1. Spring AOP :使用Spring Framework的AOP。广告。 Spring Framework的一个关键组件是面向方面编程(AOP)框架。面向方面编程需要将程序逻辑分解为称为所谓关注点的不同部分。

  2. AspectJ: AspectJ是面向Java的无缝编程语言的扩展,兼容Java平台,易于学习和使用。 AspectJ实现了横切关注点的清晰模块化,例如:错误检查和处理,同步,上下文敏感行为,性能优化,监视和日志记录,调试支持,多对象协议。

  3. AspectWerkz: AspectWerkz是一个动态,轻量级,高性能的Java AOP框架。 AspectWerkz提供强大功能和简单性,可帮助您轻松地将AOP集成到新项目和现有项目中。 AspectWerkz利用运行时字节码修改在运行时编写类。它挂钩并编织除了引导类加载器之外的任何类加载器加载的类。它具有丰富且高度正交的连接点模型。方面,建议和介绍都是用普通的Java编写的,你的目标类可以是常规的POJO。您可以添加,删除和重新构建建议,以及在运行时交换介绍的实现。可以使用XML定义文件或使用运行时属性来定义方面。

  4. 编辑1

    Spring也支持AspectJ。我用AspectJ 1.7.2测试它没有显示内存泄漏。您可以通过创建大量bean然后在一段时间后进行堆转储来复制应用程序中的相同内容,因为垃圾收集需要一些时间不是即时的。

    按照我的测试。没有电话,性能很不错。

    简单示例在MKYong中可用:http://www.mkyong.com/spring3/spring-aop-aspectj-annotation-example/

    注意:您应该修改您的问题表现是衡量时间和空间。而且,根据您的评论,您似乎在询问更多内存优化或管理内容。此外,您的问题主题与问题不同。

答案 1 :(得分:3)

如果你有这么长时间的工作,为什么不把它放到Spring-Batch运行时?实现自定义阅读器 - &gt;处理器 - &gt;作家和系统将为您做一切。为了显示此类作业执行的详细信息,我创建了此类DTO https://gist.github.com/idyoshin/b035317db8c61b1b49ccb8898848171e和收集器https://gist.github.com/idyoshin/74ad80841a51e1be62208f3fd58eeb6a。这个实用程序是解决方法,因为我不想将spring-batch管理应用程序嵌入到我的主应用程序中。我使用它们来显示我系统的特定作业(基于名称)的活动/存档执行的详细信息。

同样使用此类实用程序,您可以实现基于定制计时器的自定义数据收集器,该数据收集器将此数据推送到JMS或Websocket。 Spring-batch也有很好的监听器,您可以实现,例如自定义org.springframework.batch.core.ChunkListener将允许您进行&#34;进度条&#34;喜欢更新 - 你会知道你的块被处理的时刻,因此出现了进度更新。

与您最初的AOP解决方案相比,使用Spring批处理的方法将是前进的(纯Java代码),并且还将解决您的额外问题:持久大量更新的事务:它将整个数据集切割成块,并在单个事务中处理每个块。

答案 2 :(得分:2)

你问的问题不清楚,问题的标题是误导性的。

你真的可以使用Spring Aop来完成你想做的任务,你只需要在日志调用中注入方法fetchUserInfo()和fecthLegInfoForEachUser()等。 你也可以使用@Around来更好地控制。

对于性能方面,鉴于这段代码非常有限,您可以轻松地使用&amp;没有aop。 请记住,用于日志记录的AOP被广泛使用,并且Spring为许多实体和目的(如工厂)创建代理对象,因此经过了良好的测试和性能。

答案 3 :(得分:1)

(1)长时间运行的任务意味着工作&#39;所以您可能需要:Quartz

(2)如果你只是想知道你的程序去哪里,你可能需要一个日志工具:Logback。定义明确的appender将解决你的问题。