在Spring 中使用@Aspect 控制自定义注解的操作
Spring中使用@Aspect控制自定义注解
看这篇介绍@Aspect
1.定义系统日志注解类
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public@interfaceSysLog{ Stringvalue()default""; }
2.定义切面处理类
packagecom.kxs.common.aspect; importcom.google.gson.Gson; importcom.kxs.common.annotation.SysLog; importcom.kxs.common.utils.HttpContextUtils; importcom.kxs.common.utils.IPUtils; importcom.kxs.modules.sys.entity.SysLogEntity; importcom.kxs.modules.sys.entity.SysUserEntity; importcom.kxs.modules.sys.service.SysLogService; importorg.apache.shiro.SecurityUtils; importorg.aspectj.lang.ProceedingJoinPoint; importorg.aspectj.lang.annotation.Around; importorg.aspectj.lang.annotation.Aspect; importorg.aspectj.lang.annotation.Pointcut; importorg.aspectj.lang.reflect.MethodSignature; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.stereotype.Component; importjavax.servlet.http.HttpServletRequest; importjava.lang.reflect.Method; importjava.util.Date; /** *系统日志,切面处理类 * *@author *@email *@date */ @Aspect @Component publicclassSysLogAspect{ @Autowired privateSysLogServicesysLogService; @Pointcut("@annotation(com.kxs.common.annotation.SysLog)")//指向自定义注解路径 publicvoidlogPointCut(){ } /** *切面记录系统日志 *@parampoint *@return *@throwsThrowable */ @Around("logPointCut()")// publicObjectaround(ProceedingJoinPointpoint)throwsThrowable{ longbeginTime=System.currentTimeMillis(); //执行方法 Objectresult=point.proceed(); //执行时长(毫秒) longtime=System.currentTimeMillis()-beginTime; //保存日志 saveSysLog(point,time); returnresult; } //保存日志 privatevoidsaveSysLog(ProceedingJoinPointjoinPoint,longtime){ MethodSignaturesignature=(MethodSignature)joinPoint.getSignature(); Methodmethod=signature.getMethod(); SysLogEntitysysLog=newSysLogEntity(); SysLogsyslog=method.getAnnotation(SysLog.class); if(syslog!=null){ //注解上的描述 sysLog.setOperation(syslog.value()); } //请求的方法名 StringclassName=joinPoint.getTarget().getClass().getName(); StringmethodName=signature.getName(); sysLog.setMethod(className+"."+methodName+"()"); //请求的参数 Object[]args=joinPoint.getArgs(); try{ Stringparams=newGson().toJson(args[0]); sysLog.setParams(params); }catch(Exceptione){ } //获取request HttpServletRequestrequest=HttpContextUtils.getHttpServletRequest(); //设置IP地址 sysLog.setIp(IPUtils.getIpAddr(request)); //用户名 Stringusername=((SysUserEntity)SecurityUtils.getSubject().getPrincipal()).getUsername(); sysLog.setUsername(username); sysLog.setTime(time); sysLog.setCreateDate(newDate()); //保存系统日志 sysLogService.save(sysLog); } }
补充:为什么添加了@Aspect还要加@Component
官方文档中有写:
YoumayregisteraspectclassesasregularbeansinyourSpringXMLconfiguration,orautodetectthemthroughclasspathscanning-justlikeanyotherSpring-managedbean.However,notethatthe@Aspectannotationisnotsufficientforautodetectionintheclasspath:Forthatpurpose,youneedtoaddaseparate@Componentannotation(oralternativelyacustomstereotypeannotationthatqualifies,aspertherulesofSpring'scomponentscanner).
翻译:
您可以在SpringXML配置中注册aspect类,或者通过类路径扫描自动检测它们,就像任何其他Spring管理bean一样。但是,请注意,@aspect注释对于在类路径中自动检测是不够的:为了达到这个目的,您需要添加一个单独的@component注解(或者根据Spring的组件扫描器的规则来定义一个定制的原型注解)。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。