2015-09-05 36 views
1

我试图测试AOP对Spring框架4.1.6和AOP性能(IDK,AspectJ的)

AOP方法很干净,JDK动态代理和AspectJ的性能。

我做了一到五个简单的建议给他们,并检查经过的时间为每个。

结果:

JDK动态代理:

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

    的AspectJ(征服):

      • 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(征服)会比JDK动态代理要快,因为AspectJ的修改字节码。但即使它们之间没有性能差异也是错误的。

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

        在这里,我有问题: 他们之间有任何性能差异?(IDK动态代理,AspectJ中,没有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> 
        

        回答

        2

        因为您只是测量一个方法调用,所以您不应该感到惊讶而不会看到任何区别。测量时间的99.9%是方法内部的循环。你不是在衡量正确的事情。你应该这样做的其他方式,也许类似于我所做here

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

        现在你可以比较Spring AOP和AspectJ的性能,并且应该看到AspectJ更好。一些注意事项:

        • 我希望你知道你需要改变Spring配置,以便从Spring AOP切换到AspectJ,反之亦然。例如。如果您始终使用AspectJ Maven Plugin进行构建,则无论您将Spring配置为使用Spring AOP还是AspectJ,都可以使用编译时AspectJ编织,如Spring手册10.8 Using AspectJ with Spring applications中所述,通过加载时编织方式来使用Spring AOP或AspectJ。
        • 您应该测量不同类型的切入点和建议,例如, @Before/@After@Around,(不)使用参数通过this()target()args()结合等
        • 也请注意,您的代码示例使用一个切入点的一类,而不是一个接口。 JDK动态代理不直接在类上工作,但只能在接口上工作。为了将Spring AOP应用于类,您需要在Spring中将CGLIB作为依赖项,否则它将无法工作。 编辑:好吧,你的班级实现了Order接口,所以它仍然可以与JDK动态代理一起工作。
        +0

        感谢您的亲切建议,它真的帮了我。并且,我很抱歉迟到对您的帮助发表评论。 – jongseok