【问题标题】:which is high performance in spring aop using cglib or jdk proxy without aspectj?在没有aspectj的情况下使用cglib或jdk代理在spring aop中哪个是高性能?
【发布时间】:2014-05-09 04:49:10
【问题描述】:

我们已经在我们的应用程序中实现了spring AOP,而没有使用aspectj。 我们将自动代理设为 true 以使其使用 CGLIB 代理。

我们将其作为代理目标的原因 class= 'true' 以解决代理错误。作为副作用,应用程序变得缓慢并且需要更长的时间来执行。

有没有一种方法可以帮助我们保持性能不变并避免代理错误。

<!-- Aspects -->
    <bean id="loggingAspect" class="web.aspect.LogAspectAroundMethod" />
    <!-- PointCut -->
    <bean id="myLogPointCut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
    <property name="pattern" value=".*" />
    <property name="excludedPatterns">
    <list>
    <value>.*.isDaemon.*</value>
    </list>
    </property>
    </bean>

    <!-- Advisor Around-->
    <bean id="myLogAroundAdvisor" class="org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor">
      <property name="adviceBeanName" value="loggingAspect" />
      <property name="pointcut" ref="myLogPointCut" />
    </bean>

    <bean id="aprProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <property name="proxyTargetClass" value="true"/>
    <property name="beanNames">
    <value>*Delegate,*Builder*,*Impl*,*Controller,*Handler,*Helper</value>
    </property>
    <property name="interceptorNames">
    <list>
    <value>myLogAroundAdvisor</value>
    </list>
    </property>
    </bean>

顾问代码如下:-

只提供了实现部分:-

    import org.aopalliance.intercept.MethodInterceptor;
    import org.aopalliance.intercept.MethodInvocation;

    public class LogAspectAroundMethod implements MethodInterceptor{

        public Object invoke(MethodInvocation methodInvocation) throws Throwable {

               Object result = methodInvocation.proceed();
               return result;
        }

}

【问题讨论】:

  • 自动代理与 Cglib 或 JDK 动态代理无关。要么你混淆了事情,要么你想说'proxy-target-class'是true
  • 是的,代理目标类是真的。刚刚也修改了问题。

标签: java spring proxy aop cglib


【解决方案1】:

CGLIB 应该更快,JDK 代理在内部使用反射(参见 Spring 的 JdkDynamicAopProxy),CGLIB 代理直接通过生成的代码调用目标方法

【讨论】:

  • 是的,CGLIB 应该更快,但事实并非如此!请建议是否还有其他方法可以帮助我解决此问题?
【解决方案2】:

什么是慢?启动性能或一切都已经设置好以后的性能? JdkRegexpMethodPointcut 可能存在性能问题,我不知道。也许是创建的代理数量多,您似乎匹配了很多类和方法。此外,您的建议本身可能很慢。你没有在这里展示它们。如果您的建议只是调用proceed() 而没有做任何其他事情,会发生什么?您甚至需要around() 建议还是before()after() 就足够了?许多开放性问题。尝试进行差异化调试,即一次更改一件事。首先按照建议轻描淡写建议,以了解它们对性能的影响。还要考虑使用普通的 AspectJ 匹配语法而不是 Regex 匹配,这可能很慢。然后尝试匹配更少的类并衡量影响。

最后但同样重要的是,即使您不想听到它,也请考虑不需要任何代理的 AspectJ。尤其是使用编译时编织,您还可以最大限度地减少对启动时间的影响。

【讨论】:

  • 问题在于以后的性能而不是启动。还添加了顾问实现部分。我们使用了 around() 建议。不使用 aspectj 的原因是出于安全考虑。请提出解决方案。
  • 建议了一种调试方法。你有没有试过?首先,我们需要事实,可以从中得出解决方案。顺便说一句,安全问题听起来像是一个相当笼统的杀手论点。为什么 AspectJ 应该比 Spring AOP 更危险或更不安全?
  • 是的,事实如下:- 方面:我们有一个事件日志组件,用于记录。在这方面,我们试图提出建议。我们进行了性能测试,结果确定使用 AOP 比不使用 AOP 慢。因此寻求帮助。如果我们有任何其他更好的实施方式,请建议我。正如您所说,AspectJ 是一个致命的论点,我们确实存在使用该 Jar 的安全问题。这就是我们没有这样做的原因。
  • 我再说一遍:阅读我的答案并执行我告诉你的分析步骤。如果你想优化,你需要知道瓶颈在哪里。 “AOP 很慢”还不够好。我确实想帮助你,但我们都需要更多关于 what 慢的信息。代理?切入点匹配?编织?建议执行?在这种情况下,仅仅说:“我有问题,在信息不足的情况下为我解决”是不够的。帮自己一个忙,并对此进行差异调试/分析。您不想更改工具。因此,学习如何使用该工具,不要再成为使用工具的傻瓜。
  • 再想一想:为了找到瓶颈,想想系统是否也会因为手动添加数千条日志语句而变慢。为了评估开销,您可以暂时使用 AspectJ 而不是 Spring AOP 来查看它是否仍然很慢 - 不要永远切换到 AJ,只是为了找出问题是否真的是代理。
【解决方案3】:

我看到的一个问题是使用JdkRegexpMethodPointcut 创建的代理数量。

在确定是否需要执行建议时,有两个部分在起作用。首先是切入点的静态部分。这基本上是创建代理的地方,在这种情况下,基于名称。您似乎有相当多的豆子需要应用建议。

其次是在代理上为每个方法调用执行的动态部分。在您的情况下,这是一个基于 JDK 的正则表达式,它被执行以确定方法名称是否匹配。现在已知 JDK 正则表达式实现比其他实现要慢。

我预计代理数量与正则表达式相结合会减慢您的应用程序。

我强烈建议您尝试说服您的公司并允许使用 AspectJ,为什么使用数百万开发人员使用的框架会有风险?使用 AOP 联盟的东西(你现在正在使用的东西)存在更大的风险,因为使用它的人远远少于 AspectJ。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 2015-12-17
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    相关资源
    最近更新 更多