spring-aop

即面向切面编程 在oop的基础上横切 加入一些非核心代码

对于aop中动态代理的实现形式:JDK,cglib

  • JDK原生的实现方式,需要被代理的目标类必须实现接口。因为这个技术要求代理对象和目标对象实现同样的接口(兄弟两个拜把子模式)
  • cglib:通过继承被代理的目标类(认干爹模式)实现代理,所以不需要目标类实现接口
    使用AOP技术:在ioc容器中存放的是代理组件
    如果目标类有接口,必须使用接口类型接收IoC容器中代理组件
    如果目标类没有接口 ,正常使用代理类来接收IoC容器中代理组件

切面类使用步骤如下

  1. 定义 方法 存储增强代码 具体定义几个 由插入位置决定
  2. 使用注解配置 指定插入 目标方法的位置
    * 前置 @Before
    * 返回 @AfterReturning
    * 异常 @AfterThrowing
    * 后置 @After
    * 环绕 @Around
  3. 配置切点表达式 【选中插入的方法 切点 指明切入哪里】
  4. 补全注解
    * 加入 ioc 容器 @Component
    * 配置切面 @Aspect =切点 + 增强的部分
  5. 开启 @Aspect 注解 的支持 在配置类加入注解

//四.配置切面
@Aspect 
@Component
@Order(10) //设置切面优先级  数越小 优先级越高
public class LogAdvice {

    // 二.使用注解配置 指定插入 目标方法的位置 (前置增强)
    @Before("execution(* com..impl.*.*(..))") //三.配置切点表达式 (声明在哪些方法中生效)
    //一.定义方法
    public void before(JoinPoint joinPoint) {
        System.out.println("开始了");
       /*
      joinPoint.getSignature().getName();获取方法名
        int modifiers = joinPoint.getSignature().getModifiers();访问修饰符
        Modifier.toString(modifiers); 访问修饰符  数字转字符串
        joinPoint.getTarget().getClass().getSimpleName();  获得对象 -->类对象 --> 简单类名
        joinPoint.getArgs(); 参数列表
*/
    }

    //后置增强
    @AfterReturning(value = "execution(* com..impl.*.*(..))",returning ="result")  //返回的结果
    // 如果想要 获得 返回结果
    // 1.在方法中 加参数    (Object result) 接收返回结果
    // 2.在注解中加入returning 属性( returning ="result" 指定用那个形参 来接收 返回结果)
    public void returnResult(Object result) {
    }

    //最后增强
    @After("execution(* com..impl.*.*(..))")
    public void after() {
        System.out.println("结束了");
    }

    //异常增强
    @AfterThrowing(value = "execution(* com..impl.*.*(..))",throwing = "throwable")   //异常信息
    public void err(Throwable throwable) {
        System.out.println("出错了");
    }
}

开启 @Aspect 注解 的支持 在配置类加入注解

@Configuration
@ComponentScan("com.wind")
@EnableAspectJAutoProxy  // 5. 开启 @Aspect 注解 的支持
public class JavaConfig {
}

切点表达式注意事项

在多个方法中书写同一个 切点表达式 为了简化操作 统一管理
创建一个存储切点的类

  • 单独维护切点表达式
  • 其他类如何引用 : @通知/增强类型("com.wind.pointcut.PointCut.pointCut1()") 类的全限定符号.方法名()

切点表达式语法

@Component
public class PointCut {
//    任何 访问权限符和返回类型中com下的-->任意包-->任意类-->任意方法-->任意参数
    @Pointcut("execution(* com..*.*(..))")
    public void pointCut1(){}
}

环绕通知的使用

@Component
@Aspect
@Order(20) //设置切面优先级  数越小 优先级越高
public class AroundAdvice {
    /**
     * 环绕通知 需要在 通知中,定义 目标方法 的执行
     * @param joinPoint 目标方法   (获取目标方法信息)
     * @return 目标方法的返回值
     */
    //声明  环绕通知 注解
    @Around("com.wind.pointcut.PointCut.pointCut1()")  //引入切点
    public Object executionMethod(ProceedingJoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        Object result=null;
        try {
//            填入 目标方法 执行前的操作   == @Before
            System.out.println("开启事务");
            result = joinPoint.proceed(args);//执行目标方法
//            填入 目标方法 执行后 的操作  == @AfterReturning
            System.out.println("提交事务");
        } catch (Throwable e) {
//            这里异常要抛出
            System.out.println("回滚事务");
            throw new RuntimeException(e);
        }finally {
        }
//        返回的结果
        return result;
    }
}
posted @   微风抚秀发  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示