Spring - AOP - 介绍
1. Spring 框架的 AOP
Spring 框架的一个关键组件是面向切面的编程 (AOP)框架。面向切面的编程需要把程序逻辑分解成不同的部分称为所谓的关注点。跨一个应用程序的多个点的功能被称为横切关注点 ,这些横切关注点在概念上独立于应用程序的业务逻辑。在软件开发过程中有各种各样的很好的切面的例子,如日志记录、审计、声明式事务、安全性和缓存等。 在 OOP 中,关键单元模块度是类,而在 AOP 中单元模块度是切面。依赖注入帮助你对应用程序对象相互解耦合,AOP 可以帮助你从它们所影响的对象中对横切关注点解耦。AOP 像是编程语言的触发物,如 Perl,.NET,Java 或者其他语言。 Spring AOP 模块提供拦截器来拦截一个应用程序,例如,当执行一个方法时,你可以在方法执行之前或之后添加额外的功能。
2. AOP 术语
在我们开始使用 AOP 工作之前,让我们熟悉一下 AOP 概念和术语。这些术语并不特定于 Spring,而是与 AOP 有关的。
项 描述 Aspect 一个模块具有一组提供横切需求的 APIs。例如,一个日志模块为了记录日志将被 AOP 方面调用。应用程序可以拥有任意数量的方面,这取决于需求。 Join point 在你的应用程序中它代表一个点,你可以在插件 AOP 方面。你也能说,它是在实际的应用程序中,其中一个操作将使用 Spring AOP 框架。 Advice 这是实际行动之前或之后执行的方法。这是在程序执行期间通过 Spring AOP 框架实际被调用的代码。 Pointcut 这是一组一个或多个连接点,通知应该被执行。你可以使用表达式或模式指定切入点正如我们将在 AOP 的例子中看到的。 Introduction 引用允许你添加新方法或属性到现有的类中。 Target object 被一个或者多个方面所通知的对象,这个对象永远是一个被代理对象。也称为被通知对象。 Weaving Weaving 把方面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。这些可以在编译时,类加载时和运行时完成。
3. 通知的类型
Spring 方面可以使用下面提到的五种通知工作:
通知 描述 前置通知 在一个方法执行之前,执行通知。 后置通知 在一个方法执行之后,不考虑其结果,执行通知。 返回后通知 在一个方法执行之后,只有在方法成功完成时,才能执行通知。 抛出异常后通知 在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。 环绕通知 在建议方法调用之前和之后,执行通知。
4. AOP 入门使用
4.1. pom
< dependencies>
< dependency>
< groupId> org.springframework</ groupId>
< artifactId> spring-context</ artifactId>
< version> 6.1.10</ version>
</ dependency>
< dependency>
< groupId> org.aspectj</ groupId>
< artifactId> aspectjweaver</ artifactId>
< version> 1.9.22.1</ version>
</ dependency>
</ dependencies>
4.2. SrpingConfig
@Configuration
@ComponentScan ( basePackages = "com.springaop" )
@EnableAspectJAutoProxy
public class SpringConfig {
}
4.3. UserService
@Service
public class UserService {
public void addUser ( ) {
System . out. println ( "addUser" ) ;
}
public void deleteUser ( ) {
System . out. println ( "deleteUser" ) ;
}
public void updateUser ( ) {
System . out. println ( "updateUser" ) ;
}
public void selectUser ( ) {
System . out. println ( "selectUser" ) ;
}
}
4.4. UserAspect
@Component
@Aspect
public class UserAspect {
@Around ( "execution(* com.springaop.service.UserService.*(..))" )
public void log ( ProceedingJoinPoint joinPoint) {
long begin = System . currentTimeMillis ( ) ;
try {
joinPoint. proceed ( ) ;
} catch ( Throwable e) {
System . out. println ( "异常:" + e. getMessage ( ) ) ;
}
long end = System . currentTimeMillis ( ) ;
System . out. println ( "耗时:" + ( end - begin) + "ms" ) ;
}
}
4.5. Main
public class Main {
public static void main ( String [ ] args) {
ApplicationContext context = new AnnotationConfigApplicationContext ( SpringConfig . class ) ;
UserService userService = context. getBean ( UserService . class ) ;
userService. addUser ( ) ;
}
}
4.6. 程序输出:
addUser
耗时:0 ms