当前位置: 首页 > news >正文

电子商务网站cms手机app开发 网站建设

电子商务网站cms,手机app开发 网站建设,重庆网站备案查询系统,南安seo教程前言#xff1a; 整合之前#xff0c;我们要明白aop是什么#xff0c;为什么要用aop#xff0c;aop能帮我们做什么。 答#xff1a;AOP是面向切面编程#xff08;Aspect-Oriented Programming#xff09;的简称#xff0c;它是一种编程思想#xff0c;旨在在面向对象…前言 整合之前我们要明白aop是什么为什么要用aopaop能帮我们做什么。 答AOP是面向切面编程Aspect-Oriented Programming的简称它是一种编程思想旨在在面向对象编程OOP的基础上进行功能模块的解耦和隔离。在传统的业务处理代码中通常需要进行事务处理、日志记录等操作这些操作会分散到各个方法中增加了开发和维护的难度。AOP通过预编译方式和运行期动态代理实现在不修改源代码的情况下将分散在各个方法中的重复代码提取出来然后在程序编译或运行时再将这些提取出来的代码应用到需要执行的地方。 因此AOP能够帮我们做以下事情 降低业务逻辑的耦合性提高程序的可重用型和开发效率。对业务逻辑的各个部分进行隔离便于模块化管理。提取公共功能减少重复代码提高代码的可维护性和可读性。提供一种新的编程视角和工具使开发人员可以专注于业务逻辑的实现而不用过多关注其他功能的实现。 AOP能够提高开发效率和代码质量降低维护成本。 一、AOP介绍 1、名词介绍 1切面Aspect切入点和通知的集合 2连接点Joinpoint目标对象中可以被增强的所有方法 3通知Advice增强的代码逻辑分为前置后置最终异常环绕 4切入点Pointcut目标对象中经过匹配最终增强的方法 5引入Introduction动态的为某个类增加和减少方法 6目标对象Target Object被代理的对象 7AOP代理对象AOP ProxyAOP框架创建的代理对象用于实现切面调用方法 8织入Weaving将通知应用到切入点的过程 2、注解介绍 1EnableAspectJautoProxy 用于springboot启动类代表开启注解aop功能支持                 proxyTargetClass 是否强制使用CGlib的动态代理默认false                 exposeProxy 是否通过aop框架暴露该代理对象aopContext能够访问 2Aspect 用于标注切面类 3Pointcut 用于标识切入点                 value 切入点表达式 4 Before 前置通知 5AfterReturning 后置通知 6AfterThrowing 异常通知 7After 最终通知 8Around 环绕通知环绕通知代表了一个完整的流程因此环绕通知和上面的四个通知任选其一使用 3、切入点表达式 1execution - 根据表达式匹配使用最多 execution([修饰符] 返回类型 [包名.类名].方法名(参数列表) [异常]) 支持的通配符有 *匹配所有。..匹配多级包或者多个参数。表示类以及子类 2within - 匹配方法所在的包或者类 3this - 用于向通知方法中传入代理对象的引用 4target - 用于向通知方法中传入目标对象的引用 5args - 用于向通知方法中传入参数并且匹配参数个数 6args - 和args都是匹配参数但是args要求传入切入点的参数必须标注指定注解且不能是SOURCE源码注解比如Lombok的 7within - 匹配加了某个注解的类中的所有方法 8target - 与within类似但是要求标注到类上的注解必须为RUNTIME的 9annotation - 匹配加了某个注解的方法 10bean 通过spring容器中的beName匹配 可以使用通配符*来标识以什么开头以什么结尾 二、整合AOP实现实现日志操作 1、引入依赖 !-- springboot aop -- dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId /dependency dependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion2.0.32/version /dependency 2、类 package com.mgx.demo.common.enums;import lombok.AllArgsConstructor; import lombok.Getter;/*** author mgx*/ AllArgsConstructor Getter public enum CharacterEnum {/*** 特殊字符*///空白BLANK()//空格, SPACE( )//换行, NEWLINE(\n)//enter换行, ENTER(\r)//左斜杠, SLASH(/)//双左斜杠, DOUBLE_SLASH(//)//反斜杠, BACKSLASH(\\)//单引号, QUOTES()//双引号, DOUBLE_QUOTES(\)//撇号, APOSTROPHE()//艾特符, AT()//井号, HASHTAG(#)//dollar符, DOLLAR($)//百分号, PERCENT(%)//异或运算符 数字相同返回0否则为1, XOR(^)//and符, AND()//星号, ASTERISK(*)//等于号, EQUAL()//下划线, UNDERSCORE(_)//点, DOT(.)//句号, C_DOT(。)//逗号, COMMA(,)//中文逗号, C_COMMA()//管道符, PIPE(|)//双管道符, DOUBLE_PIPE(||)//问号, Q_MARK(?)//叹号, E_MARK(!)//加号, PLUS()//连字号、短横杠、减号, HYPHEN(-)//小于符, LT()//大于符, GT()//冒号, COLON(:)//分号, SEMICOLON(;)//中文分号, C_SEMICOLON()//左圆括号 round, L_R_BRACKETS(()//右圆括号, R_R_BRACKETS())//左右圆括号, R_BRACKETS(())//左方括号 square, L_S_BRACKETS([)//右方括号, R_S_BRACKETS(])//左右方括号, S_BRACKETS([])//左大括号 curly, L_C_BRACKETS({)//右大括号, R_C_BRACKETS({)//左右大括号, C_BRACKETS({});private final String character;public String value() {return character;}}package com.mgx.demo.utils;import com.alibaba.fastjson.JSON; import com.mgx.demo.common.enums.CharacterEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.Objects;/*** author mgx*/ Slf4j public class LogUtil {/*** 接口请求日志** param param 接口获取参数*/public static void param(Object... param) {RequestAttributes ra RequestContextHolder.getRequestAttributes();ServletRequestAttributes sra (ServletRequestAttributes) ra;if (Objects.nonNull(sra)) {HttpServletRequest request sra.getRequest();String url request.getRequestURL().toString();log.info(请求\n地址{}\n参数{}, url, Objects.isNull(param) ? CharacterEnum.BLANK.value() : Arrays.toString(param));}}/*** 接口请求日志** param param 封装后的参数若数据结构较复杂请考虑json转化string耗时及性能*/public static void paramObject(Object param) {RequestAttributes ra RequestContextHolder.getRequestAttributes();ServletRequestAttributes sra (ServletRequestAttributes) ra;if (Objects.nonNull(sra)) {HttpServletRequest request sra.getRequest();String url request.getRequestURL().toString();log.info(请求\n地址{}\n参数{}, url, Objects.isNull(param) ? CharacterEnum.BLANK.value() : JSON.toJSONString(param));}}public static void logRequest(HttpServletRequest request) {log.info(请求\n地址{}\n方法{}\nIP{}, request.getRequestURL().toString(), request.getMethod(), request.getRemoteAddr());}} package com.mgx.demo.config.aop;import com.alibaba.fastjson.JSON;import com.mgx.demo.annotation.LogRequestParam; import com.mgx.demo.utils.LogUtil; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component;/*** 自动打印日志*/ Aspect Component public class WebLogAspect {private static final Logger logger LoggerFactory.getLogger(WebLogAspect.class);Pointcut(execution(public * com.mgx.demo.controller.*.*(..)))public void webLog() {}AfterReturning(returning ret, pointcut webLog())public void doAfterReturning(Object ret) {// 处理完请求返回内容logger.info(RESPONSE : {}, JSON.toJSONString(ret));}Before(annotation(logRequestParam) || within(logRequestParam))public void doRequestParamLog(JoinPoint joinPoint, LogRequestParam logRequestParam) {// 获取方法参数Object[] args joinPoint.getArgs();if (args ! null) {if (args.length 1) {LogUtil.paramObject(args[0]);} else {LogUtil.param(args);}}}}package com.mgx.demo.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/*** author mgx*/ Target({ElementType.TYPE, ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) public interface LogRequestParam { }?xml version1.0 encodingUTF-8? configurationspringProperty scopecontext namelogPath sourceproject.log.config defaultValue${user.home}/springboot-mgx/logs/property nameLOG_HOME value${logPath}/!-- %m输出的信息, %p日志级别, %t线程名, %d日期, %c类的全名, %i索引 --!-- appender是configuration的子节点,是负责写日志的组件 --appender nameCONSOLE classch.qos.logback.core.ConsoleAppenderencoder!--pattern${CONSOLE_LOG_PATTERN}/pattern --pattern%date{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) (%file:%line\)- %m%n/pattern!-- 控制台也要使用utf-8不要使用gbk --charsetUTF-8/charset/encoder/appender!-- RollingFileAppender:滚动记录文件先将日志记录到指定文件当符合某个条件时将日志记录到其他文件 --!-- 1.先按日期存日志日期变了将前一天的日志文件名重命名为xxx%日期%索引新的日志仍然是sys.log --!-- 2.如果日期没有变化但是当前日志文件的大小超过1kb时对当前日志进行分割 重名名 --appender nameALL classch.qos.logback.core.rolling.RollingFileAppenderFile${LOG_HOME}/sys.log/File!-- rollingPolicy:当发生滚动时决定 RollingFileAppender 的行为涉及文件移动和重命名。 --!-- TimeBasedRollingPolicy 最常用的滚动策略它根据时间来制定滚动策略既负责滚动也负责出发滚动 --rollingPolicy classch.qos.logback.core.rolling.TimeBasedRollingPolicy!-- 活动文件的名字会根据fileNamePattern的值每隔一段时间改变一次 --!-- 文件名pileLog/2020/10/10/sys.2020-10-10_13.log --fileNamePattern${LOG_HOME}/%d{yyyy-MM/dd/HH}/sys.%i.log/fileNamePatterntimeBasedFileNamingAndTriggeringPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedFNATP!-- maxFileSize:这是活动文件的大小默认值是10MB --maxFileSize30MB/maxFileSize/timeBasedFileNamingAndTriggeringPolicy/rollingPolicyencoder!-- pattern节点用来设置日志的输入格式 --pattern%d %p (%file:%line\)- %m%n/pattern!-- 记录日志的编码 --charsetUTF-8/charset !-- 此处设置字符集 --/encoder/appender!--ERROR--appender nameERROR classch.qos.logback.core.rolling.RollingFileAppenderfilter classch.qos.logback.classic.filter.LevelFilterlevelERROR/levelonMatchACCEPT/onMatchonMismatchDENY/onMismatch/filterfile${LOG_HOME}/sys.error.log/fileappendtrue/appendrollingPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicyfileNamePattern${LOG_HOME}/%d{yyyy-MM/dd/HH}/sys.error.%i.log/fileNamePatternmaxFileSize30MB/maxFileSize/rollingPolicyencoderPattern%d %p (%file:%line\)- %m%n/PatterncharsetUTF-8/charset/encoder/appendercontextListener classch.qos.logback.classic.jul.LevelChangePropagatorresetJULtrue/resetJUL/contextListener!-- 控制台日志输出级别 --root levelinfoappender-ref refCONSOLE/appender-ref refALL/appender-ref refERROR//root!-- 指定项目中某个包当有日志操作行为时的日志记录级别 --!-- com.dmyc为根包也就是只要是发生在这个根包下面的所有日志操作行为的权限都是DEBUG --!-- 级别依次为【从高到低】FATAL ERROR WARN INFO DEBUG TRACE --logger namecom.mgx.demo.controller levelDEBUG/logger namecom.mgx.demo.mapper levelDEBUG/logger namespringfox levelERROR//configuration application 需要打印日志的地方在类上加上自定义注解 3、测试
http://www.dnsts.com.cn/news/165376.html

相关文章:

  • 杭州煜灿网络科技有限公司网站开发股票推荐怎么做网站
  • 北京建设信源网站 怎么打不开网站的备案信息域名不一样
  • 婚纱摄影的网站怎么做岗网站制作
  • 张家界公司网站建设网站建设三方合同范本
  • 深圳哪做网站做网站收广告费
  • 建设手机银行网站网站百度收录是什么意思
  • 精通网站开发书籍世界建设企业网站
  • SEO案例网站建设上海企业网站建设费用
  • wordpress 文章回收站在线作图软件有哪些
  • 长治网站建设公司我要做电商怎么做
  • 设计师图片素材网站海安网站开发
  • 外贸seo网站建站贵州省建设厅公示网站
  • 网站设计方案书ppt百度推广登陆平台登录
  • 贵州旅游网站建设策划书旅游网站建设流程
  • 注册网站要多久怎么做网站在里面填字
  • 网站后台管理系统 asp免费视频模板网站
  • 做装饰公司网站6动漫设计是什么
  • 县级网站建设培训会桐梓网站开发
  • 网站开发生命周期模型如何学习网站开发编程
  • 大气金融网站企业展厅公司
  • 网站系统cms整站排名服务
  • 游戏卡充值可以做网站吗做商城网站的项目背景图片
  • 给网站怎么做tag标签淘宝详情页设计模板
  • 中小学网站建设探讨佳作哪个公司做网站比较好
  • 瑞安市公用建设局网站西安志成网站建设公司
  • 济南网站制作多少钱企业网站建设服务哪家好
  • wordpress西部优化网站搭建
  • android 网站模板建设银行企业网银网站无法打开
  • 高明网站制作安阳吧百度贴吧
  • 无锡网站推广经理wordpress允许作者上传媒体