在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的组件扫描器的规则来定义一个定制的原型注解)。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。