spring

    科技2025-04-13  18

    文章目录

    aop环境配置什么是aopaop能干什么aop如何实现aop中的几个概念spring的aop实现基于aspectj注解基于xml的配置 切入点表达式

    帮助你理解springAOP如何控制事务的 SpringBoot 利用 AOP 记录日志

    aop环境配置

    使用AOP编程,除了原来Spring导入的包以外还需要导入的包: aopalliance-1.0.jarAspectjrt-xx.jarAspectjweaver-xx.jarcglib-nodep-2.1_3.jarspring-aop.jar 开启注解支持 <aop:aspectj-autoproxy proxy-target-class="true"/>

    什么是aop

    Aspect Oriented Programming面向切面编程,是对oop面向对象编程的一种补充完善。 日志,执行效率监测功能相对于付款核心功能,是辅助性的功能,把这些功能称为切面。在代理层面,切面就是一个独立存在的类。切面类中的方法称为通知方法。

    aop能干什么

    做统一事务管理做统一日志管理做统一异常管理

    aop如何实现

    动态代理。

    aop中的几个概念

    aspect:切面,是一个类,类中是非核心的辅助功能代码实现。advice:通知,是aspect类中的方法。分为前置通知,返回通知,最终通知,异常通知weave:织入,通过动态代理模把通知方法式插入到。​joinpoint:连接点,是一个方法,其实是核心业务方法。target:目标对象,连接点方法所在的对象。Pointcut(切入点):所谓切入点是指我们要对那些joinpoint进行拦截的定义。

    ​总结:通过动态代理把aspect中的advice方法weave到target的joinpoint方法的周围。

    spring的aop实现

    基于aspectj注解

    在元数据配置中,开启aspectj注解识别。写service层的服务对象(aop中的目标对象),加服务方法(aop的连接点方法)。写切面类,写通知方法。 @Component//成为一个bean对象 @Aspect//成为一个切面bean对象 public class Aspect1 { //切入点表达式 //execution(返回值类型 包名.类名.方法名(形参)) @Pointcut("execution(* com.javasm.service.*.*(..))") public void servicePointcut(){} //前置通知方法,可以得到连接点的信息(方法,实参) @Before("servicePointcut()") public void beforeAdvice(JoinPoint jp){ Object[] args = jp.getArgs(); Object target = jp.getTarget(); String name = jp.getSignature().getName(); System.out.println("beforeAdvice:joinpoint info:"+target+"-"+name+"-"+ Arrays.toString(args)); } //返回通知方法,可以得到连接点的信息(方法,实参),还可以得到连接点的返回值。 @AfterReturning(pointcut = "servicePointcut()",returning = "b") public void afterReturnAdvice(JoinPoint jp,Object b){ System.out.println("afterReturnAdvice,return info:"+b); } //异常通知方法。可以得到连接点的信息(方法,实参),还可以得到异常信息 @AfterThrowing(pointcut = "servicePointcut()",throwing = "e") public void afterThrowAdvice(JoinPoint jp,Exception e){ System.out.println("afterThrowAdvice,error info:"+e.getMessage()); } //最终通知方法。可以得到连接点的信息(方法,实参) @After("servicePointcut()") public void afterAdvice(JoinPoint jp){ System.out.println("afterAdvice"); } // 环绕通知,必须有返回值,必须有形参 // (可以实现以上四种通知类型)比如事务通知 @Around("servicePointcut()") public Object aroundAdvice(ProceedingJoinPoint jp){ Object[] args = jp.getArgs(); Object target = jp.getTarget(); String name = jp.getSignature().getName(); Object result = null; try { System.out.println("前置通知"); result = jp.proceed();//method.invoke System.out.println("返回通知: "+result); } catch (Throwable e) { System.out.println("异常:"+e.getMessage()); }finally { System.out.println("最终:"); } return result; } }

    基于xml的配置

    1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:context="http://www.springframework.org/schema/context" 4 xmlns:p="http://www.springframework.org/schema/p" 5 xmlns:util="http://www.springframework.org/schema/util" 6 xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> 8 9 <!--目标对象 孩子类--> 10 <bean id="child" class="com.oukele.learning.aop0.Child"/> 11 12 <!--切面类--> 13 <bean id="mom" class="com.oukele.learning.aop0.Mom"/> 14 <!--面向切面编程--> 15 <aop:config> 16 <!--定义切面--> 17 <aop:aspect ref="mom"> 18 <!--定义切点--> 19 <aop:pointcut id="action" expression="execution(* *.*(..))"/> 20 <!-- 声明前置通知 (在切点方法被执行前调用)--> 21 <aop:before method="buy" pointcut-ref="action"/> 22 <!-- 声明后置通知 (在切点方法被执行后调用)--> 23 <aop:after method="clear" pointcut-ref="action"/> 24 </aop:aspect> 25 </aop:config> 26 27 28 </beans>

    切入点表达式

    expression-匹配方法执行的连接点,是Spring最主要的切入点。除了类型模式、名字模式和参数模式以外,其余的都是可选的,*为任意通配符 expression=execution(* com.javasm.*.service.*.*(..))” 表示作用在com.javasm.service包及子包下所有的类的所有方法上 expression=execution(* com.javasm.service.*.*(java.lang.String,..))” 表示作用在com.javasm.service包及子包下所有的类的第一个参数为String类型的方法上 expression=execution(java.lang.String com.javasm.service.*.*(..))” 表示作用在com.javasm.service包及子包下所有的类的返回值类型为String的方法上 expression=execution(!java.lang.String com.javasm.service.*.*(..))” 表示作用在com.javasm.service包及子包下所有的类的返回值类型不是String的所有方法上 expression=execution(* set**(..))” 表示作用在任意以set开始的方法上
    Processed: 0.011, SQL: 8