浅谈AspectJ框架

目录

AspectJ框架

AspectJ常见通知类型

AspectJ 的切入点表达式(掌握)

AspectJ的前置通知@Before

前置方式通知注释的实现

 前置通知方式参数jionpoint解析

AspectJ框架切换JDK动态代理和CGLib动态代理


AspectJ框架

浅谈AspectJ框架_第1张图片

 AspectJ 是一个面向切面的框架,他定义了 AOP 的一些语法,有一个专门的字节码生成器来生成遵守 java 规范的 class 文件。

查看源图像

 AspectJ 的通知类型不仅包括我们之前了解过的四种通知:前置通知、后置通知、环绕通知和异常通知,而且还多出一种最终通知即无论程序是否正常执行,最终通知的代码会得到执行。

原因就是切入点表达式,切入点表达式可以标识切面织入到哪些类的那些方法当中,就不需要像我们之前利用 spring 实现 AOP 那样各种配置只要把切面的实现配置好了,再把这个切入点表达式写好就可以了。

AspectJ常见通知类型


  AspectJ 中常用的通知有四种类型:

浅谈AspectJ框架_第2张图片

浅谈AspectJ框架_第3张图片

浅谈AspectJ框架_第4张图片

浅谈AspectJ框架_第5张图片
  1)前置通知@Before
  2)后置通知@AfterReturning
  3)环绕通知@Around
  4)最终通知@After
  5)定义切入点@Pointcut(了解)

AspectJ 的切入点表达式(掌握)


  规范的公式:
  execution(访问权限 方法返回值 方法声明(参数) 异常类型)
  简化后的公式:
  execution( 方法返回值 方法声明(参数) )

  用到的符号:
  *   代码任意个任意的字符(通配符)
  ..  如果出现在方法的参数中,则代表任意参数
      如果出现在路径中,则代表本路径及其所有的子路径

  示例:
  execution(public * *(..)) :任意的公共方法
  execution(* set*(..)):任何一个以“set”开始的方法
  execution(* com.xyz.service.impl.*.*(..)):任意的返回值类型,在com.xyz.service.impl包下的任意类的任意方法的任意参数
  execution(* com.xyz.service..*.*(..)):任意的返回值类型 ,在com.xyz.service及其子包下的任意类的任意方法的任意参数  
                                           com.xyz.service.a.b.*.*(..)  com.xyz.service.*.*(..)
  execution(* *..service.*.*(..)):service之前可以有任意的子包
  execution(* *.service.*.*(..)):service之前只有一个包


AspectJ的前置通知@Before


  在目标方法执行前切入切面功能.在切面方法中不可以获得目标方法的返回值,只能得到目标方法的签名。

  实现的步骤:
  添加依赖
   
      org.springframework
      spring-aspects
      5.2.5.RELEASE 
   

  1)创建业务接口
  2)创建业务实现
  3)创建切面类,实现切面方法
  4)在applicationContext.xml文件中进行切面绑定

浅谈AspectJ框架_第6张图片

 

  项目案例:
  @Aspect  //交给AspectJ的框架去识别切面类
@Component
public class MyAspect {
    /**
     * 所有切面的功能都是由切面方法来实现的
     * 可以将各种切面都在此类中进行开发
     *
     * 前置通知的切面方法的规范
     * 1)访问权限是public
     * 2)方法的返回值是void
     * 3)方法名称自定义
     * 4)方法没有参数,如果有也只能是JoinPoint类型
     * 5)必须使用@Before注解来声明切入的时机是前切功能和切入点
     *   参数:value  指定切入点表达式
     *
     * 业务方法
     * public String doSome(String name, int age)
     */
    @Before(value = "execution(public String com.bjpowernode.s01.SomeServiceImpl.*(String,int))")
    public void myBefore(){
        System.out.println("切面方法中的前置通知功能实现............");
    }

    @Before(value = "execution(public * com.bjpowernode.s01.SomeServiceImpl.*(..))")
    public void myBefore(){
        System.out.println("切面方法中的前置通知功能实现............");
    }

    @Before(value = "execution( * com.bjpowernode.s01.*.*(..))")
    public void myBefore(JoinPoint jp){
        System.out.println("切面方法中的前置通知功能实现............");
        System.out.println("目标方法的签名:"+jp.getSignature());
        System.out.println("目标方法的参数:"+ Arrays.toString(jp.getArgs()));
    }
    @Before(value = "execution( * com.bjpowernode.s01..*(..))")
    public void myBefore(){
        System.out.println("切面方法中的前置通知功能实现............");
    }

    @Before(value = "execution( * *(..))")
    public void myBefore(){
        System.out.println("切面方法中的前置通知功能实现............");
    }
}

前置方式通知注释的实现

浅谈AspectJ框架_第7张图片

浅谈AspectJ框架_第8张图片 浅谈AspectJ框架_第9张图片

 前置通知方式参数jionpoint解析

 浅谈AspectJ框架_第10张图片

 

AspectJ框架切换JDK动态代理和CGLib动态代理

浅谈AspectJ框架_第11张图片

 

      ===>默认是JDK动态代理,取时必须使用接口类型
      ==>设置为CGLib子类代理,可以使用接口和实现类接


    记住:使用接口来接,永远不出错。

 

你可能感兴趣的:(Spring,servlet,java,jvm)