免费网站个人注册网站seo李守洪排名大师

张小明 2025/12/26 20:01:17
免费网站个人注册,网站seo李守洪排名大师,seo系统培训哪家好,大学生活动策划书模板SpringAOP本笔记整合了 AOP 基础理论、核心概念、进阶用法#xff0c;并结合真实登录日志记录案例#xff0c;采用“由外到内、逐步迭代”的开发思路#xff0c;帮助理解如何从零构建一个健壮的 AOP 切面。AOP Aspect Oriented Programming#xff08;面向切面编程、面向方…SpringAOP本笔记整合了 AOP 基础理论、核心概念、进阶用法并结合真实登录日志记录案例采用“由外到内、逐步迭代”的开发思路帮助理解如何从零构建一个健壮的 AOP 切面。AOPAspect Oriented Programming面向切面编程、面向方面编程可简单理解为面向特定方法编程典型场景部分业务方法运行较慢需统计每个方法的执行耗时优势减少重复代码代码无侵入不修改原有业务逻辑提高开发效率维护方便AOP 基础AOP 快速入门需求统计所有业务层方法的执行耗时步骤导入依赖在pom.xml中引入 Spring AOP 依赖Spring Boot Web 默认包含编写 AOP 程序针对特定方法按需编程// AOP 程序 - RecordTimeAspectAspectComponentpublicclassRecordTimeAspect{Around(execution(* com.itheima.service.impl.*.*(..)))publicObjectrecordTime(ProceedingJoinPointpjp)throwsThrowable{// 1. 记录方法运行的开始时间longbeginSystem.currentTimeMillis();// 2. 执行原始的方法Objectresultpjp.proceed();// 3. 记录方法运行的结束时间计算执行耗时longendSystem.currentTimeMillis();log.info(方法 {} 执行耗时: {}ms,pjp.getSignature(),end-begin);returnresult;}}常见应用场景记录系统操作日志事务管理权限控制性能监控异常统一处理AOP 核心概念概念说明连接点JoinPoint可被 AOP 控制的方法含执行时上下文信息通知Advice重复的共性逻辑最终体现为一个方法切入点Pointcut匹配连接点的条件决定哪些方法会被增强切面Aspect描述“通知”与“切入点”的关系用Aspect声明目标对象Target被通知所应用的对象即原始业务对象AOP 执行流程Spring 使用动态代理技术创建代理对象代理对象在目标方法前后插入通知逻辑实现“头尾原方法”结构AOP 进阶通知类型按执行时机分类类型注解执行时机特点使用频率环绕通知Around目标方法前 后可控制是否执行原方法可获取返回值/异常⭐⭐⭐⭐⭐最常用前置通知Before目标方法执行前无法阻止方法执行⭐⭐后置通知After目标方法执行后无论成功/异常类似 finally⭐⭐返回后通知AfterReturning目标方法成功返回后异常时不执行⭐异常后通知AfterThrowing目标方法抛出异常后仅异常时执行⭐重点Around是唯一能控制原方法是否执行的通知类型对于Around必须使用ProceedingJoinPoint并调用proceed()否则原方法不会执行切点表达式Pointcut Expression作用描述哪些方法需要被增强常见形式1.execution(...)—— 按方法签名匹配语法execution(访问修饰符? 返回值 包名.类名.?方法名(参数) throws 异常?)通配符*匹配单个任意符号如*Service、save*、String参数等..匹配任意层级包或任意数量/类型参数示例// 匹配 service.impl 下所有类的所有方法execution(*com.itheima.service.impl.*.*(..))// 匹配所有以 update 开头的方法execution(*com.itheima..*.*update*(..))2.annotation(...)—— 按注解匹配推荐用于业务标记// 匹配所有标注了 LoginIn 的方法annotation(com.rudyj.anno.LoginIn)✅最佳实践优先使用自定义注解方式解耦且灵活避免过度使用..缩小匹配范围提升性能方法命名规范如login,saveXxx便于表达式匹配切点复用PointcutPointcut(annotation(com.rudyj.anno.LoginIn))publicvoidpt(){}// public 可被其他切面引用Around(pt())publicObjectrecordLogin(ProceedingJoinPointjoinPoint)throwsThrowable{// ...}⚠️注意若在Around中使用了额外参数如LoginIn anno则pt()方法也必须声明对应参数否则报错Unbound pointcut parameter xxx通知执行顺序多个切面匹配同一方法时默认按切面类名的字母顺序执行可用Order(n)显式控制数字越小优先级越高前置阶段Order(1)先于Order(2)后置阶段Order(1)后于Order(2)类似栈Order(5)AspectComponentpublicclassRecordTimeAspect{...}连接点信息获取JoinPoint用于Before/After等通知可获取getArgs()方法参数getSignature()方法签名含类名、方法名getTarget()目标对象ProceedingJoinPointJoinPoint的子类仅用于Around额外提供proceed()执行原方法proceed(Object[])传入新参数执行原方法AOP 实战案例登录日志记录需求记录用户登录行为到数据库包含用户名、是否成功、JWT、耗时等。数据库表结构-- 登录日志表CREATETABLEemp_login_log(idINTUNSIGNEDPRIMARYKEYAUTO_INCREMENTCOMMENTID,usernameVARCHAR(20)COMMENT用户名,passwordVARCHAR(32)COMMENT密码脱敏存储,login_timeDATETIMECOMMENT登录时间,is_successTINYINTUNSIGNEDCOMMENT是否成功, 1:成功, 0:失败,jwtVARCHAR(1000)COMMENTJWT令牌,cost_timeBIGINTUNSIGNEDCOMMENT耗时, 单位:ms)COMMENT登录日志表;实体类DataNoArgsConstructorAllArgsConstructorpublicclassEmpLoginLog{privateIntegerid;privateStringusername;privateStringpassword;// 注意生产环境不应存明文privateLocalDateTimeloginTime;privateShortisSuccess;// 1:成功, 0:失败privateStringjwt;privateLongcostTime;}控制器已存在RestControllerpublicclassLoginController{AutowiredprivateEmpServiceempService;LoginInPostMapping(/login)publicResultlogin(RequestBodyEmpemp){LoginInfologinInfoempService.login(emp);if(loginInfonull){CurrentHolder.setJwt();returnResult.error(用户名或密码错误);}CurrentHolder.setJwt(loginInfo.getToken());returnResult.success(loginInfo);}} 由外到内五步构建登录日志 AOP开发哲学每一步只解决一个问题验证通过后再进入下一步。第 0 步前提准备已有✅ 自定义注解LoginIn已定义✅ Controller 方法已加LoginIn✅EmpLoginLog实体 OperateLoginMapper.insert()已实现✅ 项目能正常启动登录接口可调用 Step 1让 AOP “跑起来” —— 最小可行切面目标确认 AOP 能拦截到/login方法。AspectComponentpublicclassOperateLoginAspect{Pointcut(annotation(com.rudyj.anno.LoginIn))publicvoidpt(){}Around(pt())publicObjectrecordLogin(ProceedingJoinPointjoinPoint)throwsThrowable{System.out.println(✅ AOP 拦截成功方法: joinPoint.getSignature().getName());returnjoinPoint.proceed();// 必须调用 proceed()}}✅验证调用/login看控制台是否打印日志。❌ 若未打印检查Component是否被扫描、Spring Boot 是否启用 AOP默认开启。 Step 2提取方法参数用户名、密码目标从joinPoint.getArgs()中拿到Emp对象。Around(pt())publicObjectrecordLogin(ProceedingJoinPointjoinPoint)throwsThrowable{Stringusernamenull,passwordnull;for(Objectarg:joinPoint.getArgs()){if(arginstanceofEmp){Empemp(Emp)arg;usernameemp.getUsername();passwordemp.getPassword();break;}}System.out.println( 用户名: username);returnjoinPoint.proceed();}✅验证传{ username: tom, password: 123 }看是否打印tom。❌ 若为null检查Emp是否有 getter 方法或参数是否确实是Emp类型。 Step 3计算耗时 捕获返回值目标记录执行时间并确保异常时也能记录。Around(pt())publicObjectrecordLogin(ProceedingJoinPointjoinPoint)throwsThrowable{// 提取参数略longstartSystem.currentTimeMillis();Objectresultnull;try{resultjoinPoint.proceed();}finally{longcostSystem.currentTimeMillis()-start;System.out.println(⏱️ 耗时: costms);}returnresult;}✅验证看控制台是否打印耗时如50ms。finally确保即使登录失败抛异常耗时也能记录。 Step 4判断登录是否成功 提取 JWT目标从ResultLoginInfo中提取 token。Around(pt())publicObjectrecordLogin(ProceedingJoinPointjoinPoint)throwsThrowable{// 提取参数略longstartSystem.currentTimeMillis();Objectresultnull;ShortisSuccess0;Stringjwtnull;try{resultjoinPoint.proceed();if(resultinstanceofResult){Result?res(Result?)result;// 根据实际 Result 结构调整判断逻辑if(res.getCode()!nullres.getCode()200){isSuccess1;if(res.getData()instanceofLoginInfo){jwt((LoginInfo)res.getData()).getToken();}}}returnresult;}finally{longcostSystem.currentTimeMillis()-start;System.out.println(✅ 成功: (isSuccess1), JWT: jwt);}}✅验证成功登录 → 打印true和 token错误密码 → 打印false和null⚠️ 注意根据你项目的Result实际结构code/msg调整成功判断逻辑。 Step 5保存日志到数据库 安全加固目标构建EmpLoginLog并插入同时避免记录明文密码。AutowiredprivateOperateLoginMapperoperateLoginMapper;Around(pt())publicObjectrecordLogin(ProceedingJoinPointjoinPoint)throwsThrowable{// 1. 提取参数Stringusernamenull;for(Objectarg:joinPoint.getArgs()){if(arginstanceofEmp){Empemp(Emp)arg;usernameemp.getUsername();break;}}// 2. 初始化日志字段LocalDateTimeloginTimeLocalDateTime.now();longstartSystem.currentTimeMillis();Objectresultnull;ShortisSuccess0;Stringjwtnull;// 3. 执行原方法并解析结果try{resultjoinPoint.proceed();if(resultinstanceofResult){Result?res(Result?)result;if(res.getCode()!nullres.getCode()200){isSuccess1;if(res.getData()instanceofLoginInfo){jwt((LoginInfo)res.getData()).getToken();}}}returnresult;}catch(Exceptione){throwe;// 重新抛出异常保证原逻辑不变}finally{// 4. 构建日志实体关键密码脱敏EmpLoginLoglogEntrynewEmpLoginLog();logEntry.setUsername(username);logEntry.setPassword(******);// ⚠️ 绝不记录明文密码logEntry.setLoginTime(loginTime);logEntry.setIsSuccess(isSuccess);logEntry.setJwt(jwt);logEntry.setCostTime(System.currentTimeMillis()-start);// 5. 保存日志失败不影响主流程try{operateLoginMapper.insert(logEntry);}catch(Exceptionex){log.error(❌ 保存登录日志失败,ex);}}}✅最终验证成功登录 → 查数据库is_success1jwt非空失败登录 →is_success0jwtnullpassword字段为******非明文补充说明查漏补缺1. 关于ThreadLocal与 AOP 的关系你在LoginController中使用了CurrentHolder.setJwt(...)这是完全独立于 AOP 的逻辑AOP不需要也不应该操作CurrentHolderThreadLocal的清理应由Filter 或 Interceptor在请求结束后完成// TokenFilter 示例try{chain.doFilter(request,response);}finally{CurrentHolder.remove();// 防止内存泄漏}2. 安全警告永远不要记录明文密码即使是开发/测试环境也应养成习惯如果业务确实需要记录“密码特征”如哈希值应在 Service 层处理而非 AOP3. 切点参数绑定错误回顾若使用Pointcut(annotation(loginIn))publicvoidpt(LoginInloginIn){}Around(pt(loginIn))publicObjectaround(ProceedingJoinPointpjp,LoginInloginIn){...}→ 必须保证pt()方法参数名与Around中一致否则编译报错Unbound pointcut parameter4. 异常处理原则AOP 中捕获异常后必须 re-throw否则会吞掉异常导致前端收不到错误信息日志保存等辅助操作应单独 try-catch避免影响主流程5. 性能建议AOP 逻辑应尽量轻量如异步写日志若日志量大可考虑使用消息队列解耦
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

可以用什么做网站登录页面重点实验室网站建设的意义

第一章:生物识别安全升级的紧迫性随着数字身份验证需求的激增,传统密码机制已难以应对日益复杂的网络威胁。生物识别技术凭借其唯一性和便捷性,成为身份认证的重要手段。然而,指纹、面部识别等原始实现方式正面临伪造攻击、数据泄…

张小明 2025/12/26 20:01:15 网站建设

数据分析师事务所宁波seo在线优化方案

昨天给大家拆解了母婴好物的爆款AI图文带货账号,许多小伙伴私信问像这类的AI礼盒产品展示图,是怎么生成的。 其实制作非常简单,只需一张产品实拍图,直接丢给AI生图工具,加上提示词,就可以快速生产精致的商品…

张小明 2025/12/26 20:00:41 网站建设

深圳注册公司核名查询站长工具seo综合查询下载安装

Dify平台的健身训练计划定制合理性分析 在智能健康服务快速演进的今天,用户不再满足于“千人一面”的标准化训练模板。他们希望获得真正贴合自身体能、目标与限制条件的个性化指导——比如一个膝盖受过伤的上班族,如何在每天只有45分钟的情况下安全有效地…

张小明 2025/12/26 20:00:09 网站建设

唐山网站制作企业烟台网站排名优化

学术机构如何利用 Anything-LLM 管理课题资料与研究成果? 在高校和科研实验室里,知识的积累往往伴随着混乱:博士生毕业离校前留下几十个命名不清的文件夹;新入学的硕士生花上几周才搞明白课题组过去五年到底做了什么;申…

张小明 2025/12/26 19:59:03 网站建设

trs网站建设平台济南网站seo哪家公司好

StarRocks索引架构深度解析:构建毫秒级响应的大数据查询引擎 【免费下载链接】starrocks StarRocks是一个开源的分布式数据分析引擎,用于处理大规模数据查询和分析。 - 功能:分布式数据分析;大规模数据查询;数据分析&a…

张小明 2025/12/26 19:58:29 网站建设

长春网站建设吉网传媒实力牜免费的网站app软件

Linux 用户、组管理与文件权限设置全解析 1. 用户组管理 在 Linux 系统中,对用户组的操作十分重要。删除用户组可使用 groupdel 命令,该命令仅需一个组名作为参数。例如,要删除名为 gingko 的用户组,可执行以下命令: groupdel gingko在众多默认用户组中, wheel …

张小明 2025/12/26 19:57:56 网站建设