网站的排版,艺腾青岛网站建设,网址转app,如何用手机做网站前言
在Spring AOP#xff08;Aspect-Oriented Programming#xff09;中#xff0c;动态代理是常用的技术之一#xff0c;用于在运行时动态地为目标对象生成代理对象#xff0c;
并拦截其方法调用。Spring AOP 默认使用两种类型的动态代理机制#xff1a;JDK 动态代理和…前言
在Spring AOPAspect-Oriented Programming中动态代理是常用的技术之一用于在运行时动态地为目标对象生成代理对象
并拦截其方法调用。Spring AOP 默认使用两种类型的动态代理机制JDK 动态代理和 CGLIB 代理。
JDK 动态代理
JDK 动态代理是 Java 原生提供的动态代理机制它只能代理接口。如果你的目标对象实现了某个接口Spring AOP 会默认使用 JDK 动态代理。
JDK 动态代理机制通过 java.lang.reflect.Proxy 类来创建代理对象并将方法调用委托给 InvocationHandler 实现。
CGLIB 代理
如果目标对象没有实现接口Spring AOP 会使用 CGLIBCode Generation Library来生成代理对象。CGLIB 是一个强大的库
可以生成目标对象的子类并覆盖其方法以实现代理功能。通过 CGLIBSpring AOP 能够代理没有实现接口的类即具体的类。
默认代理机制的选择
Spring AOP 在选择使用哪种代理机制时遵循以下原则
如果目标对象实现了至少一个接口则默认使用 JDK 动态代理。
如果目标对象没有实现任何接口则默认使用 CGLIB 代理。
配置示例
在大多数情况下你不需要显式地指定使用哪种代理机制因为 Spring 会自动为你选择。但是如果你有特殊需求可以通过配置来强制使用某种代理机制。
一、Spring AOP 注解概述
1.Spring 的 AOP 功能除了在配置文件中配置一大堆的配置比如切入点、表达式、通知等等以外使用注解的方式更为方便快捷特别是 Spring boot 出现以后基本不再使用原先的 beans.xml 等配置文件了而都推荐注解编程
Aspect切面声明标注在类、接口包括注解类型或枚举上。Pointcut 切入点声明即切入到哪些目标类的目标方法。既可以用 execution 切点表达式, 也可以是 annotation 指定拦截拥有指定注解的方法. value 属性指定切入点表达式默认为 用于被通知注解引用这样通知注解只需要关联此切入点声明即可无需再重复写切入点表达式 Before 前置通知, 在目标方法(切入点)执行之前执行。 value 属性绑定通知的切入点表达式可以关联切入点声明也可以直接设置切入点表达式 注意如果在此回调方法中抛出异常则目标方法不会再执行会继续执行后置通知 - 异常通知。 After后置通知, 在目标方法(切入点)执行之后执行AfterReturning 返回通知, 在目标方法(切入点)返回结果之后执行. pointcut 属性绑定通知的切入点表达式优先级高于 value默认为 AfterThrowing 异常通知, 在方法抛出异常之后执行, 意味着跳过返回通知 pointcut 属性绑定通知的切入点表达式优先级高于 value默认为 注意如果目标方法自己 try-catch 了异常而没有继续往外抛则不会进入此回调函数 Around 环绕通知目标方法执行前后分别执行一些代码类似拦截器可以控制目标方法是否继续执行。 通常用于统计方法耗时参数校验等等操作。
2、上面这些 AOP 注解都是位于 aspectjweaver 依赖中对于习惯了 Spring 全家桶编程的人来说并不是需要直接引入 aspectjweaver 依赖因为 spring-boot-starter-aop 组件默认已经引用了 aspectjweaver 来实现 AOP 功能。换句话说 Spring 的 AOP 功能就是依赖的 aspectjweaver
!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop --
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactIdversion2.1.4.RELEASE/version
/dependency
3.AOP 底层是通过 Spring 提供的的动态代理技术实现的在运行期间动态生成代理对象代理对象方法执行时进行增强功能的介入再去调用目标对象的方法从而完成功能的增强。主要使用 JDK 动态代理与 Cglib 动态代理所以如果目标类不是 Spring 组件则无法拦截如果是 类名.方法名 方式调用也无法拦截。
二、Aspect 快速入门
1、Aspect 常见用于记录日志、异常集中处理、权限验证、Web 参数校验、事务处理等等2、要想把一个类变成切面类只需3步1在类上使用 Aspect 注解使之成为切面类2切面类需要交由 Spring 容器管理所以类上还需要有 Service、Repository、Controller、Component 等注解2在切面类中自定义方法接收通知3、AOP 的含义就不再累述了下面直接上示例
/*** 切面类用于处理日志、参数校验等** author songwp* date 2020-04-27*/
Aspect
Component
Slf4j
public class HandleAspect {/*** Pointcut 切入点声明即切入到哪些目标方法。value 属性指定切入点表达式默认为 。* 用于被下面的通知注解引用这样通知注解只需要关联此切入点声明即可无需再重复写切入点表达式* p* 切入点表达式常用格式举例如下* - * com.songwp.aspect.EmpService.*(..))表示 com.songwp.aspect.EmpService 类中的任意方法* - * com.songwp.aspect.*.*(..))表示 com.songwp.aspect 包(不含子包)下任意类中的任意方法* - * com.songwp.aspect..*.*(..))表示 com.songwp.aspect 包及其子包下任意类中的任意方法* /p* value 的 execution 可以有多个使用 || 隔开.*/Pointcut(execution(public * com.songwp.controller.*.*(..)))public void aopPointCut() {}/*** 前置通知目标方法执行之前执行以下方法体的内容。* value绑定通知的切入点表达式。可以关联切入点声明也可以直接设置切入点表达式* br/* * param joinPoint提供对连接点处可用状态和有关它的静态信息的反射访问br/ p* * * Object[] getArgs()返回此连接点处目标方法的参数目标方法无参数时返回空数组* * * Signature getSignature()返回连接点处的签名。* * * Object getTarget()返回目标对象* * * Object getThis()返回当前正在执行的对象* * * StaticPart getStaticPart()返回一个封装此连接点的静态部分的对象。* * * SourceLocation getSourceLocation()返回与连接点对应的源位置* * * String toLongString()返回连接点的扩展字符串表示形式。* * * String toShortString()返回连接点的缩写字符串表示形式。* * * String getKind()返回表示连接点类型的字符串* * * /p*/Before(aopPointCut())public void beforeAdvice() {System.out.println(前置通知执行);}/*** 后置通知目标方法执行之后执行以下方法体的内容不管目标方法是否发生异常。* value绑定通知的切入点表达式。可以关联切入点声明也可以直接设置切入点表达式*/After(aopPointCut())public void afterAdvice() {System.out.println(后置通知执行);}/*** 返回通知目标方法返回后执行以下代码* value 属性绑定通知的切入点表达式。可以关联切入点声明也可以直接设置切入点表达式* pointcut 属性绑定通知的切入点表达式优先级高于 value默认为 * returning 属性通知签名中要将返回值绑定到的参数的名称默认为 ** param joinPoint 提供对连接点处可用状态和有关它的静态信息的反射访问*/AfterReturning(execution(* com.songwp.service.impl.OperateLogServiceImpl.*(..)))public void logAfterReturning(JoinPoint joinPoint) {System.out.println(返回后通知: joinPoint.getSignature().getName());}/*** 异常通知目标方法发生异常的时候执行以下代码此时返回通知不会再触发* value 属性绑定通知的切入点表达式。可以关联切入点声明也可以直接设置切入点表达式* pointcut 属性绑定通知的切入点表达式优先级高于 value默认为 * throwing 属性与方法中的异常参数名称一致** param ex捕获的异常对象名称与 throwing 属性值一致*/AfterThrowing(pointcut execution(* com.songwp.service.impl.OperateLogServiceImpl.*(..)), throwing ex)public void logAfterThrowing(JoinPoint joinPoint, Throwable ex) {System.out.println(异常后通知: joinPoint.getSignature().getName() , Exception: ex);}/*** 环绕通知* 1、Around 的 value 属性绑定通知的切入点表达式。可以关联切入点声明也可以直接设置切入点表达式* 2、Object ProceedingJoinPoint.proceed(Object[] args) 方法继续下一个通知或目标方法调用返回处理结果如果目标方法发生异常则 proceed 会抛异常.* 3、假如目标方法是控制层接口则本方法的异常捕获与否都不会影响目标方法的事务回滚* 4、假如目标方法是控制层接口本方法 try-catch 了异常后没有继续往外抛则全局异常处理 RestControllerAdvice 中不会再触发** param joinPoint* return* throws Throwable*/Around(execution(* com.songwp.service.impl.OperateLogServiceImpl.*(..)))public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {this.checkRequestParam(joinPoint);System.out.println(环绕通知: joinPoint.getSignature().getName());// 继续执行方法Object result joinPoint.proceed();System.out.println(环绕通知: joinPoint.getSignature().getName());return result;}/*** 参数校验防止 SQL 注入** param joinPoint*/private void checkRequestParam(ProceedingJoinPoint joinPoint) {Object[] args joinPoint.getArgs();if (args null || args.length 0) {return;}String params Arrays.toString(joinPoint.getArgs()).toUpperCase();String[] keywords {DELETE , UPDATE , SELECT , INSERT , SET , SUBSTR(, COUNT(, DROP ,TRUNCATE , INTO , DECLARE , EXEC , EXECUTE , AND , OR , --};for (String keyword : keywords) {if (params.contains(keyword)) {log.error(参数存在SQL注入风险其中包含非法字符 {}., keyword);throw new RuntimeException(参数存在SQL注入风险params params);}}}
} 三、Aspect 切面不生效原因
确保切面类被Spring管理在切面类上添加 Service、Repository、Controller、Component 等注解检查路径设置确保切面类被 ComponentScan 注解扫描到。即有没有被Spring容器管理。可以使用 PostConstruct注解测试。检查切面表达式确保切面表达式正确无误能够匹配到目标方法。 特别注意 比如定义了一个 AOP 切面(Pointcut)拦截 ServiceA 中的方法 B当从其他类调用方法 B 时(比如 Controller 层)会正常切入拦截而从本类其他方法中调用方法 B 时无法切入拦截因为此时默认并不是通过代理对象调用的而是直接通过 this 对象来调的。可以参考EnableAspectJAutoProxy注解。
总结AOP的高级特性使得开发者能够以声明式的方式处理复杂的应用场景。通过灵活使用切入点表达式和正则表达式可以在Spring AOP中实现精确的连接点匹配。此外AOP在性能监控、日志记录、事务管理等场景中的应用展示了其在提高代码模块化和可维护性方面的强大能力。 文章转载自: http://www.morning.lmhcy.cn.gov.cn.lmhcy.cn http://www.morning.ktmpw.cn.gov.cn.ktmpw.cn http://www.morning.lgnrl.cn.gov.cn.lgnrl.cn http://www.morning.zstbc.cn.gov.cn.zstbc.cn http://www.morning.dmcqy.cn.gov.cn.dmcqy.cn http://www.morning.slysg.cn.gov.cn.slysg.cn http://www.morning.sooong.com.gov.cn.sooong.com http://www.morning.mqlsf.cn.gov.cn.mqlsf.cn http://www.morning.mmqhq.cn.gov.cn.mmqhq.cn http://www.morning.jqrhz.cn.gov.cn.jqrhz.cn http://www.morning.gmjkn.cn.gov.cn.gmjkn.cn http://www.morning.kcypc.cn.gov.cn.kcypc.cn http://www.morning.xsqbx.cn.gov.cn.xsqbx.cn http://www.morning.phnbd.cn.gov.cn.phnbd.cn http://www.morning.ohmyjiu.com.gov.cn.ohmyjiu.com http://www.morning.jghty.cn.gov.cn.jghty.cn http://www.morning.klcdt.cn.gov.cn.klcdt.cn http://www.morning.ftzll.cn.gov.cn.ftzll.cn http://www.morning.rrbhy.cn.gov.cn.rrbhy.cn http://www.morning.smnxr.cn.gov.cn.smnxr.cn http://www.morning.ntqqm.cn.gov.cn.ntqqm.cn http://www.morning.kghss.cn.gov.cn.kghss.cn http://www.morning.mkccd.cn.gov.cn.mkccd.cn http://www.morning.dwmmf.cn.gov.cn.dwmmf.cn http://www.morning.rdng.cn.gov.cn.rdng.cn http://www.morning.nqxdg.cn.gov.cn.nqxdg.cn http://www.morning.bzlgb.cn.gov.cn.bzlgb.cn http://www.morning.dkqyg.cn.gov.cn.dkqyg.cn http://www.morning.rcdmp.cn.gov.cn.rcdmp.cn http://www.morning.rfmzc.cn.gov.cn.rfmzc.cn http://www.morning.qfgwx.cn.gov.cn.qfgwx.cn http://www.morning.lwrcg.cn.gov.cn.lwrcg.cn http://www.morning.htjwz.cn.gov.cn.htjwz.cn http://www.morning.rkzb.cn.gov.cn.rkzb.cn http://www.morning.nktgj.cn.gov.cn.nktgj.cn http://www.morning.wsrcy.cn.gov.cn.wsrcy.cn http://www.morning.bnjnp.cn.gov.cn.bnjnp.cn http://www.morning.wnjrf.cn.gov.cn.wnjrf.cn http://www.morning.bnxfj.cn.gov.cn.bnxfj.cn http://www.morning.tstkr.cn.gov.cn.tstkr.cn http://www.morning.hhkzl.cn.gov.cn.hhkzl.cn http://www.morning.qgjxt.cn.gov.cn.qgjxt.cn http://www.morning.nktxr.cn.gov.cn.nktxr.cn http://www.morning.qdscb.cn.gov.cn.qdscb.cn http://www.morning.jcwhk.cn.gov.cn.jcwhk.cn http://www.morning.pqcrz.cn.gov.cn.pqcrz.cn http://www.morning.zdxss.cn.gov.cn.zdxss.cn http://www.morning.jsxrm.cn.gov.cn.jsxrm.cn http://www.morning.dpgdj.cn.gov.cn.dpgdj.cn http://www.morning.lwmxk.cn.gov.cn.lwmxk.cn http://www.morning.kncrc.cn.gov.cn.kncrc.cn http://www.morning.sgjw.cn.gov.cn.sgjw.cn http://www.morning.eviap.com.gov.cn.eviap.com http://www.morning.ryzgp.cn.gov.cn.ryzgp.cn http://www.morning.cdrzw.cn.gov.cn.cdrzw.cn http://www.morning.ymyhg.cn.gov.cn.ymyhg.cn http://www.morning.mqnbm.cn.gov.cn.mqnbm.cn http://www.morning.frqtc.cn.gov.cn.frqtc.cn http://www.morning.lqws.cn.gov.cn.lqws.cn http://www.morning.djxnn.cn.gov.cn.djxnn.cn http://www.morning.sooong.com.gov.cn.sooong.com http://www.morning.xnrgb.cn.gov.cn.xnrgb.cn http://www.morning.ldpjm.cn.gov.cn.ldpjm.cn http://www.morning.xfyjn.cn.gov.cn.xfyjn.cn http://www.morning.mtrrf.cn.gov.cn.mtrrf.cn http://www.morning.txgjx.cn.gov.cn.txgjx.cn http://www.morning.nbnq.cn.gov.cn.nbnq.cn http://www.morning.jltmb.cn.gov.cn.jltmb.cn http://www.morning.nicetj.com.gov.cn.nicetj.com http://www.morning.wbxr.cn.gov.cn.wbxr.cn http://www.morning.xrksf.cn.gov.cn.xrksf.cn http://www.morning.ishoufeipin.cn.gov.cn.ishoufeipin.cn http://www.morning.mwmtk.cn.gov.cn.mwmtk.cn http://www.morning.xuejitest.com.gov.cn.xuejitest.com http://www.morning.yhgbd.cn.gov.cn.yhgbd.cn http://www.morning.rwzmz.cn.gov.cn.rwzmz.cn http://www.morning.ggcjf.cn.gov.cn.ggcjf.cn http://www.morning.tlfyb.cn.gov.cn.tlfyb.cn http://www.morning.jmspy.cn.gov.cn.jmspy.cn http://www.morning.psdsk.cn.gov.cn.psdsk.cn