弹簧上的aop性能(idk,Aspectj) [英] aop performance on spring (idk, aspectj)

查看:126
本文介绍了弹簧上的aop性能(idk,Aspectj)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在Spring框架4.1.6和更高版本上测试AOP的性能

I tried to test the performance of AOP on Spring framework 4.1.6 and

AOP方法干净,jdk动态代理和AspectJ.

AOP methods were clean, jdk dynamic proxy and aspectJ.

我向他们提出了1-5条简单的建议,并检查了每条建议的经过时间.

I made one to five simple advices to them and checked elapsed time for each.

结果:

jdk动态代理:

  • aspect1:2.499秒.
  • aspect2:2.574
  • aspect3:2.466
  • aspect4:2.436
  • aspect5:2.563

aspectJ(ctw):

  • aspect1:2.648
  • aspect2:2.562
  • aspect3:2.635
  • aspect4:2.520
  • aspect5:2.574

干净(无任何方面):

  • aspect1:2.699
  • aspect2:2.513
  • aspect3:2.527
  • aspect4:2.458
  • aspect5:2.402

在测试它们之前,我预计AspectJ(ctw)将比Jdk动态代理更快,因为AspectJ修改了字节码.但是即使它们之间没有性能差异也是错误的.

Before testing them, I expected AspectJ (ctw) will be faster than Jdk dynamic proxy because AspectJ modified bytecode. But it was wrong even there was no performance difference among them.

因此,我检查了修改后的目标类(.class)以识别AspectJ编译器已使用,并发现字节码已修改.

So, I checked the target class(.class) modified to recognise that AspectJ Compiler used and found bytecode modified.

在这里,我有一个问题: 它们之间是否有性能差异? (idk动态代理,aspectj,无aop)

Here, I have question: Is there any performance difference among them? (idk dynamic proxy, aspectj, no aop)

我的代码:

public class HelloAOP {

public static void main(String [] args) {

    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/application-context.xml");
    Order order = (Order) ctx.getBean("orderImpl");
    SimpleDateFormat format = new SimpleDateFormat("mm:ss.SSS");

    StopWatch watch = new StopWatch();

    watch.start();
    order.placeOrder();
    watch.stop();

    System.out.println("Elapsed: " + format.format(watch.getTotalTimeMillis()));
    }
}

目标:

@Service
public class OrderImpl implements Order {
    public void placeOrder() {
        System.out.println("::Target Object");
        for(long i = 0; i < 5000000000L; i++);
    }
}

方面:

@Aspect
@Component
public class Aspect1 {

    @Before("execution(* com.cafe.beans.impl.OrderImpl.placeOrder())")
    public void aspect() {
        System.out.println("Aspect 1 *");
    }
}

pom.xml:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>4.1.6</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.1.6</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-instrument</artifactId>
        <version>4.1.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.6</version>
    </dependency>

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.6</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjtools</artifactId>
        <version>1.8.6</version>
    </dependency>

<build>
    <finalName>testAop</finalName>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>3.3</source>
                <target>3.3</target>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <includes>
                    <include>**/*Tests.java</include>
                </includes>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.7</version>
            <configuration>
                <showWeaveInfo>true</showWeaveInfo>
                <verbose>true</verbose>
                <complianceLevel>1.8</complianceLevel>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

推荐答案

看到任何区别也就不会感到惊讶,因为您只测量一个方法调用.方法中的循环是所测量时间的99.9%.因此,您没有衡量正确的事情.您应该采用另一种方法,也许类似于我在此处:

You should not be surprised not to see any difference because you are just measuring one single method call. 99.9% of the time measured is the loop inside your method. Ergo you are not measuring the right thing. You should do it the other way around, maybe similar to what I did here:

  • 该方法应该什么也不做,或者什么也不做,什么也不打印.
  • 您应该测量重复调用方面建议的方法的总时间,因为您想了解应用方面的开销,而不是方法主体运行时(方法主体在您的方面保持不变).

现在,您可以将Spring AOP与AspectJ的性能进行比较,并且应该看到AspectJ具有优越的性能.一些警告:

Now you can compare Spring AOP to AspectJ performance and should see that AspectJ is superior. A few caveats:

  • 希望您知道需要更改Spring配置,以便从Spring AOP切换到AspectJ,反之亦然.例如.如果您始终在构建时使用AspectJ Maven插件,则将使用编译时的AspectJ编织,无论是否如Spring手册第 10.8将AspectJ与Spring应用程序.
  • 您应该衡量不同类型的切入点和建议,例如@Before/@After vs. @Around,(不是)通过this()target()args()等使用参数绑定.
  • 还请注意,您的示例代码在类而不是接口上使用切入点.但是,JDK动态代理不能直接在类上工作,而只能在接口上工作.为了在类上应用Spring AOP,您需要将CGLIB作为Spring中的依赖项,否则它将无法正常工作. 好的,您的类实现了Order接口,因此它仍然可以与JDK动态代理一起使用.
  • I hope you know that you need to change the Spring configuration so as to switch from Spring AOP to AspectJ and vice versa. E.g. if you use the AspectJ Maven Plugin all the time for your builds, you will use compile-time AspectJ weaving, no matter if you configure Spring to use Spring AOP or AspectJ via load-time weaving as described in the Spring manual, section 10.8 Using AspectJ with Spring applications.
  • You should measure different types of pointcuts and advice, e.g. @Before/@After vs. @Around, (not) using parameter binding via this(), target() or args() etc.
  • Please also note that your sample code uses a pointcut on a class rather than an interface. JDK dynamic proxies do not work directly on classes, though, only on interfaces. In order to apply Spring AOP on classes, you need CGLIB as a dependency in Spring, otherwise it simply will not work. Okay, your class implements the Order interface, so it might still work with JDK dynamic proxies.

这篇关于弹簧上的aop性能(idk,Aspectj)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆