spring aop 实现 Spring AOP与AspectJ AOP的区别:依赖性及织入方式详解?
AOP和 AOP都是面向切面编程(AOP)的实现方式,但它们在实现和使用上有一些区别。下面我会详细说明它们之间的主要区别:
1.依赖性:
· AOP: AOP是框架的一部分,因此它集成在应用程序中,并依赖于容器。 AOP不需要特殊的编译器或工具,因为它是基于Java代理的运行时代理实现。
· AOP: AOP是一个独立的AOP框架,不依赖于或任何其他框架。它有自己的编译器(ajc)和语法,可以在编译时或运行时织入切面。
2.织入方式:
· AOP: AOP使用代理模式在目标对象和切面之间创建代理对象。这意味着 AOP只支持方法级别的切面,而且只能拦截管理的bean。
· AOP: AOP支持更广泛的织入方式,包括方法级别、字段级别和构造函数级别的切面。它可以在编译时或运行时织入切面,因此更加灵活。
3.性能:
· AOP:由于使用代理模式, AOP的性能通常比较高效,但对于复杂的切面和大规模的应用程序,性能可能会有所下降。
· AOP: AOP在性能上通常更加高效,因为它可以在编译时进行织入,减少了运行时的开销。这使得它适用于大型和高性能的应用程序。
4.语法和表达能力:
· AOP: AOP使用基于注解或 XML 配置的方式来定义切面,语法相对简单,适用于一般的切面需求。但它的表达能力有限,不支持复杂的切点表达式。
· AOP: AOP使用更为丰富和复杂的切面表达式语言,支持更多的切点表达式,可以处理复杂的切面需求。它还提供了更多的切面类型,如引入和多个切面的组合。
5.适用场景:
· AOP:适用于轻量级应用程序,或者对AOP要求不是特别复杂的场景。如果应用程序已经使用了 框架, AOP可能是更好的选择。
· AOP:适用于需要更高级、更复杂的切面需求的大型应用程序。它可以处理更复杂的织入需求,并提供更多的灵活性。
接下来笔者将演示如何在 AOP和 AOP中创建和使用切面。在这两种情况下,我们将创建一个简单的日志切面,用于记录方法的执行时间。
AOP示例:
首先,我们需要创建一个配置文件来启用 AOP:
接下来,创建一个目标类:
package com.example;
public class MyService {
public void doSomething() {
System.out.println("Doing something...");
}
}
然后,创建一个切面类:
package com.example;public class LogAspect { public void logBefore() { long startTime = System.currentTimeMillis(); System.out.println("Method execution started at: " + startTime); } }
最后,创建一个应用程序主类:
package com.example;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyService myService = (MyService) context.getBean("myService");
myService.doSomething();
}
}
当运行类时,中的方法将在的方法执行之前被调用,记录方法的开始时间。
AOP示例:
使用 AOP,我们可以不需要容器,并且切面表达式更为灵活。首先,创建一个普通的Java项目。
然后,创建一个目标类,与上面的示例相同。
接下来,创建一个切面类:
package com.example;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class LogAspect {
@Before("execution(* com.example.MyService.*(..))")
public void logBefore() {
long startTime = System.currentTimeMillis();
System.out.println("Method execution started at: " + startTime);
}
}
在 AOP中,我们使用@注解来标记一个切面,并使用@注解来定义在方法执行前执行的通知。
最后,创建一个应用程序主类:
package com.example;
public class MainApp {
public static void main(String[] args) {
MyService myService = new MyService();
myService.doSomething();
}
}
当运行类时,中的方法将在的方法执行之前被调用,记录方法的开始时间。
这两个示例分别演示了如何在 AOP和 AOP中创建和使用切面,以记录方法的执行时间。注意,在 AOP示例中,我们无需容器,而且切面表达式更为灵活。
总之, AOP是一种更轻量级的AOP解决方案,适用于大多数常见的AOP需求,而 AOP更加强大和灵活,适用于复杂的AOP需求和大型应用程序。选择哪种取决于项目的具体需求和复杂性。在某些情况下,它们也可以结合使用,以充分利用它们的优势。

























