今天我们就来说说Spring中的切面Aspect,这是Spring的一大优势。面向切面编程往往可以让我们的开发更加解耦,大大减少代码量。同时让我们更专注于业务模块的开发,将那些与业务无关的东西抽离出来,方便后期的维护和迭代。我在视频中观看了电源节点的视频。我把这篇博客整理成一个笔记。以后复习的时候再看,分享给有需要的朋友。视频资源:https://www.bilibili.com/video...相关概念1.看点:首先要理解“切”字,需要把物体想象成立方体,而传统的物体——定向思维成为思维。类定义完成后(封装)。每次实例化一个对象,给类定义中的成员变量赋值,就相当于定义了一个立方体。定义完成后,就等待使用和回收了。面向切面编程是指对于我们封装好的一个类,我们可以在编译时或者运行时对其进行切割,切割立方体,在原有方法中添加(编织)一些新的代码,对原有方法进行增强处理代码。那些增强部分的代码称为方面,比如下面代码示例中的通用日志处理代码,常见的有事务处理、授权认证等。2.切入点(PointCut):要在哪些类中使用哪些方法增强和截断,指的是增强的方法。也就是剪什么。3.连接点(JoinPoint):知道切哪些方法后,剩下的就是什么时候切,在原方法的哪个执行阶段添加额外的代码,这就是连接点。比如方法调用前、方法调用后、异常发生时等。4.忠告:忠告融入方法及其改进方式。定义了一个方面的具体实现。那么这里涉及到一个问题,空间(从哪里切)和时间(什么时候切,什么时候加代码),我们已经知道空间就是定义在入口点的方法,什么时候切,就是连接点概念。5.目标对象:一个或多个方面通知的对象为目标对象。6、AOP代理对象(AOPProxyObject):AOP代理是AOP框架生成的对象,是目标对象的代理对象。代理对象可以在目标对象的基础上调用相应连接点上的通知。7.编织:将aspect切割成目标方法,增强目标方法的过程称为编织。AOP必须依赖org.springframework.bootspring-boot-starter-aop日志实体类包com.space.aspect.bo;importlombok.Data;/***Syslogbo*/@DatapublicclassSysLogBO{privateStringclassName;私有字符串方法名;私有字符串参数;私人长执行时间;私人字符串备注;privateStringcreateDate;}logservicepackagecom.space.aspect.service;importcom.space.aspect.bo.SysLogBO;importlombok.extern.slf4j.Slf4j;importorg.springframework.stereotype.Service;@Slf4j@Service公共类SysLogService{publicbooleansave(SysLogBOsysLogBO){//这里没有具体实现log.info(sysLogBO.getParams());返回真;}}定义日志注解包com.space.aspect.anno;importjava.lang.annotation.*;/***定义系统日志注解*/@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@接口SysLog{字符串值()default"";}声明切面,完成日志记录以上4点我们的准备工作已经完成接下来是重点包com.space.aspect.aspect;importcom.google.gson.Gson;importcom.space.aspect.anno.SysLog;importcom.space.aspect.bo.SysLogBO;importcom.space。aspect.service.SysLogService;导入org.aspectj.lang.ProceedingJoinPoint;导入org.aspectj.lang.annotation.Around;导入org.aspectj.lang.annotation.Aspect;导入org.aspectj.lang.annotation.Pointcut;导入org.aspectj.lang.reflect.MethodSignature;导入org.springframework.beans.factory.annotation.Autowired;导入org.springframework.stereotype.Component;导入java.lang.reflect.Method;导入java.text.SimpleDateFormat;导入java。util.ArrayList;importjava.util.Date;importjava.util.List;/***Systemlogaspect*/@Aspect//使用@Aspect注解声明一个切面@ComponentpublicclassSysLogAspect{@AutowiredprivateSysLogServicesysLogService;/***这里我们使用注解的形式*当然我们也可以直接通过切入点表达式指定要拦截的包,要拦截的类和方法*切入点表达式:execution(...)***execution(public**(..))任何公共方法*execution(*set*(..))所有以set开头的方法*execution(*com.LoggerApply.*(..))com.LoggerApply类中的所有方法*execution(*com.annotation.*.*(..))com.annotation包下所有类的所有方法*execution(*com.annotation..*.*(..))com.annotation包下所有类的所有方法和子包method*execution(*com.annotation..*.*(String,?,Long))com.annotation包和子包下的所有类都有三个参数,第一个参数是String类型,第二个参数是任意类型,第三个参数是Long的一个方法type*execution(@annotation(com.lingyejun.annotation.Lingyejun))*/@Pointcut("@annotation(com.space.aspect.anno.SysLog)")publicvoidlogPointCut(){}/***环绕通知@Around,当然你也可以使用@Before(pre-notification)@After(post-notification)*@parampoint*@return*@throwsThrowable*/@Around("logPointCut()")publicObjectaround(ProceedingJoinPointpoint)throwsThrowable{longbeginTime=System.currentTimeMillis();对象结果=point.proceed();longtime=System.currentTimeMillis()-开始时间;avesLotry{g(点,时间);}catch(Exceptione){}返回结果;}/***保存日志*/privatevoidsaveLog(ProceedingJoinPointjoinPoint,longtime){MethodSignaturesignature=(MethodSignature)joinPoint.getSignature();方法method=signature.getMethod();SysLogBOsysLogBO=newSysLogBO();sysLogBO.setExeuTime(时间);SimpleDateFormatdateFormat=newSimpleDateFormat("yyyy-MM-ddhh:mm:ss");sysLogBO.setCreateDate(dateFormat.format(newDate()));SysLogsysLog=method.getAnnotation(SysLog.class);if(sysLog!=null){//注解上的描述sysLogBO.setRemark(sysLog.value());}//请求的类名、方法名StringclassName=joinPoint.getTarget().getClass().getName();StringmethodName=signature.getName();sysLogBO.setClassName(类名);sysLogBO.setMethodName(methodName);//请求的参数Object[]args=joinPoint.getArgs();try{Listlist=newArrayList();for(Objecto:args){列表。添加(新Gson()。systoJson(o));列表.toString());}catch(Exceptione){}sysLogService.save(sysLogBO);}}测试包com.space.aspect.controller;importcom.space.aspect.anno.SysLog;importorg.springframework。web.bind.annotation.GetMapping;导入org.springframework.web.bind.annotation.RequestParam;导入org.springframework.web.bind.annotation.RestController;@RestControllerpublicclassTestController{@SysLog("测试")@GetMapping("/test")publicStringtest(@RequestParam("name")Stringname){returnname;}}这样,我们就成功实现了使用Aspect来实现切面日志记录