当前位置: 首页 > 知识库问答 >
问题:

spring上的aop性能(idk,aspectj)

云瑞
2023-03-14

我试图在Spring framework 4.1.6和

AOP方法有clean、jdk动态代理和aspectJ。

我给他们提了一到五个简单的建议,并检查了每个建议的运行时间。

结果:

jdk动态代理:

    null
  • aspect1:2.499秒。
  • aspect2:2.574
  • 方面3:2.466
  • 方面4:2.436
  • 方面5:2.563

aspectJ(ctw):

    null
  • 方面1:2.648
  • 方面2:2.562
  • 方面3:2.635
  • 方面4:2.520
  • 方面5:2.574

清洁(无外观):

    null
  • aspect1:2.699
  • aspect2:2.513
  • 方面3:2.527
  • 方面4:2.458
  • 方面5:2.402

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

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

在这里,我有一个问题:它们之间有什么性能差异吗?(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>

共有1个答案

祁景山
2023-03-14

如果没有看到任何差异,您不应该感到惊讶,因为您只测量了一个方法调用。99.9%的测量时间是方法内部的循环。因此,你测量的不是正确的东西。你应该换一种方式来做,也许类似于我在这里做的:

  • 该方法不应执行任何操作或几乎不执行任何操作,也不应打印任何内容
  • 您应该测量重复调用方面建议的方法的总时间,因为您希望了解应用方面的开销,而不是方法体运行时(方法体因方面而保持不变)

现在您可以将Spring AOP与AeyJ的性能进行比较,并且应该会看到AeyJ更优越。一些警告:

  • 我希望您知道,您需要更改Spring配置,以便从Spring AOP切换到AeyJ,反之亦然。例如,如果您在构建中一直使用AeyJ Maven插件,那么您将使用编译时AeyJ编织,无论您将Spring配置为通过加载时编织使用Spring AOP还是AeyJ,如Spring手册第10.8节将AeyJ与Spring应用程序一起使用中所述。
  • 您应该衡量不同类型的切入点和建议,例如@之前/@之后@周围,(不)通过this()target()args()等使用参数绑定。
  • 请注意,您的示例代码在类上使用了切入点,而不是接口。不过,JDK动态代理不能直接在类上工作,只能在接口上工作。为了在类上应用Spring AOP,您需要CGLIB作为Spring中的依赖项,否则它根本无法工作。编辑:好吧,您的类实现了order接口,因此它可能仍然可以与JDK动态代理一起使用。
 类似资料:
  • 问题内容: 我们已经开始将spring aop用于我们应用程序的各个方面(当前的安全性和缓存)。 我的经理虽然十分了解这种技术的好处,但仍担心该技术对性能的影响。 我的问题是,你是否遇到了使用aop(特别是spring aop)引入的性能问题? 问题答案: 只要你能够控制自己的AOP,我就认为它是有效的。无论如何,我们确实确实存在性能问题,所以通过我们自己的推理,我们无法完全控制;)这主要是因为重

  • 问题内容: 我需要有关Spring AOP的帮助。我有以下代码: application-context.xml application-context-aop.xml 当我尝试在Tomcat上加载应用程序时,出现以下异常: 我在Web层具有与记录我的应用程序相同的配置,并且工作正常,但是当我将AOP放在Service层时,会遇到此异常。 我正在使用Spring MVC,并在web.xml上配置了

  • 我有一个spring soap web服务,我想使用自定义日志记录方面来度量它的性能。对于普通的spring bean来说,这个方面工作得很好,但是对于Endpoint-InvokeInterral方法,这个方面没有被调用。像保护方法一样在Spring有什么限制吗?谢谢你帮我把它弄好? 代码示例: Spring WS终结点: 更新:将访问修饰符更改为public,这是否意味着Spring允许AOP

  • 我创建了一个包含@Transactional注释的方面。正在按预期调用我的建议,但新实体AuditRecord从未保存到数据库中,看起来我的@Transactional注释不起作用。 bean上下文如下: 我的切入点是只拦截接口(服务接口)。服务方法可能是也可能不是事务性的。如果服务方法是事务性的,如果建议因某种原因失败,我希望该事务被回滚。 我的问题是:为什么要忽略事务注释?这是我第一次用Spr

  • 主要内容:Spring AOP 的代理机制,Spring AOP 连接点,Spring AOP 通知类型,Spring AOP 切面类型,一般切面的 AOP 开发,基于 PointcutAdvisor 的 AOP 开发,自动代理Spring AOP 是 Spring 框架的核心模块之一,它使用纯 Java 实现,因此不需要专门的编译过程和类加载器,可以在程序运行期通过代理方式向目标类织入增强代码。 Spring AOP 的代理机制 Spring 在运行期会为目标对象生成一个动态代理对象,并在代理

  • 面试问springaop原理,应怎么回答,感觉回答动态代理(cglib,proxy)不准确,回答springaop源码的话又说不出重点,有没有捞推一推springaop源码阅读,或者这一部分怎么学,阿里嘎多 #晒一晒我的offer# #我发现了面试通关密码# #如何判断面试是否凉了# #如何看待offer收割机的行为#