spring-aop的使用

AOP的核心概念及术语

  • 切面(Aspect): 指关注点模块化,这个关注点可能会横切多个对象。
    事务管理是企业级Java应用中有关横切关注点的例子。 在Spring AOP
    中,切面可以使用通用类基于模式的方式(schema­based 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的使用

  1. 引入aspectjweaver和spring-aspects 的pom依赖

  2. 开启AOP的注解使用

    <!--因为我们使用的是注解方式的AOP,所以要开启注解AOP功能-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    
  3. 创建切面类,加上@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+"方法结束");
            }
        }
    
    
    }
    
    
posted @ 2021-03-01 23:19  阿灿呀  阅读(337)  评论(0)    收藏  举报