浅谈AspectJ框架

本文深入探讨AspectJ框架,包括其通知类型:前置、后置、环绕和最终通知,并详细解析切入点表达式的使用。通过示例说明如何在实际项目中配置和实现切面,同时讨论了在不同情况下如何选择JDK动态代理和CGLib动态代理。
摘要由CSDN通过智能技术生成

目录

AspectJ框架

AspectJ常见通知类型

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

AspectJ的前置通知@Before

前置方式通知注释的实现

 前置通知方式参数jionpoint解析

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


AspectJ框架

查看源图像

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

查看源图像

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

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

AspectJ常见通知类型


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


  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


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

  实现的步骤:
  添加依赖
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.2.5.RELEASE</version> 
    </dependency>
  1)创建业务接口
  2)创建业务实现
  3)创建切面类,实现切面方法
  4)在applicationContext.xml文件中进行切面绑定

 

  项目案例:
  @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("切面方法中的前置通知功能实现............");
    }
}

前置方式通知注释的实现

 

 前置通知方式参数jionpoint解析

 

 

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

 

    <aop:aspectj-autoproxy ></aop:aspectj-autoproxy>  ===>默认是JDK动态代理,取时必须使用接口类型
    <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>  ==>设置为CGLib子类代理,可以使用接口和实现类接


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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值