spring-aop的使用
AOP的核心概念及术语
- 切面(Aspect): 指关注点模块化,这个关注点可能会横切多个对象。
事务管理是企业级Java应用中有关横切关注点的例子。 在Spring AOP
中,切面可以使用通用类基于模式的方式(schemabased approach)或
者在普通类中以@Aspect注解 - 连接点(Join point): 在程序执行过程中某个特定的点,例如某个方
法调用的时间点或者处理异常的时间点。在Spring AOP中,一个连接点总
是代表一个方法的执行。 - 通知(Advice): 在切面的某个特定的连接点上执行的动作。通知有多
种类型,包括“around”, “before” and “after”等等。通知的类型将在后面的
章节进行讨论。 许多AOP框架,包括Spring在内,都是以拦截器做通知模
型的,并维护着一个以连接点为中心的拦截器链。 - 切点(Pointcut): 匹配连接点的断言。通知和切点表达式相关联,并
在满足这个切点的连接点上运行(例如,当执行某个特定名称的方法
时)。切点表达式如何和连接点匹配是AOP的核心:Spring默认使用
AspectJ切点语义。 - 引入(Introduction): 声明额外的方法或者某个类型的字段。Spring
允许引入新的接口(以及一个对应的实现)到任何被通知的对象上。例
如,可以使用引入来使bean实现 IsModified接口, 以便简化缓存机制(在
AspectJ社区,引入也被称为内部类型声明(inter))。 - 目标对象(Target object): 被一个或者多个切面所通知的对象。也被
称作被通知(advised)对象。既然Spring AOP是通过运行时代理实现
的,那么这个对象永远是一个被代理(proxied)的对象。 - AOP代理(AOP proxy):AOP框架创建的对象,用来实现切面契约
(aspect contract)(包括通知方法执行等功能)。在Spring中,AOP代
理可以是JDK动态代理或CGLIB代理。 - 织入(Weaving): 把切面连接到其它的应用程序类型或者对象上,并
创建一个被被通知的对象的过程。这个过程可以在编译时(例如使用
AspectJ编译器)、类加载时或运行时中完成。 Spring和其他纯Java AOP
框架一样,是在运行时完成织入的。
AOP的底层原理
JDK动态代理和cjlib动态代理,当被代理类实现了接口,采用jdk动态代理方式;当被代理类没有实现接口,采用cjlib动态代理
AOP的使用
-
引入aspectjweaver和spring-aspects 的pom依赖
-
开启AOP的注解使用
<!--因为我们使用的是注解方式的AOP,所以要开启注解AOP功能--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> -
创建切面类,加上@Aspect注解,声明其是切面;加上@Component,将其注入IOC容器里,交给spring管理
package com.jiang.aspectj; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; import java.util.Arrays; /** * @author JQC * @date 2021/3/1-22:22 */ @Aspect @Component public class UserAspectj { // 引用切点表达式 @Pointcut("execution(* com.jiang.service..*.*(..))") public void pointcut(){} @Before("pointcut()") public static void before(){ System.out.println("方法前。。。。"); } @After("@annotation(jdk.nashorn.internal.runtime.logging.Logger)") public static void after(){ System.out.println("方法后。。。。"); } // 环绕通知 @Around("pointcut()") public static void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { Object[] args = proceedingJoinPoint.getArgs(); String name = proceedingJoinPoint.getSignature().getName(); try { System.out.println("环绕通知:"+name+"开始,参数为:"+ Arrays.asList(args)); Object proceed = proceedingJoinPoint.proceed(args); System.out.println("环绕返回通知:"+name+"方法返回 :"+proceed); }catch (Exception e){ System.out.println("环绕异常通知:"+name+"异常信息 :"+e); }finally { System.out.println("环绕后置通知"+name+"方法结束"); } } }
我成功因为我志在成功
浙公网安备 33010602011771号