1.利用AOP在运行时切面处理的 日志注解
1)定义注解
@Target(value= {ElementType.TYPE, ElementType.METHOD})
@Retention(value= RetentionPolicy.RUNTIME)
public @interface Log {
/** 方法名 */
AspectEnum methodName() default AspectEnum.insert;
/** 操作名称 */
String operateName();
}
2)AOP在运行时切面处理
@Slf4j
@Aspect
@Component
public class LogAspect {
@Autowired
private RedisClient redisClient;
@Reference
private GlobalUsersServiceApi globalUsersServiceApi;
@Reference
private GlobalOperateLogServiceApi globalOperateLogServiceApi;
//运行时拦截掉这个方法,做切面处理
@Pointcut("@annotation(com.xxx.annotation.Log)")
public void methodPointcut() {
}
//切面处理方法
@Before("methodPointcut()")
public void before(JoinPoint joinPoint) {
try{
//从获取RequestAttributes中获取HttpServletRequest的信息
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = (HttpServletRequest) requestAttributes.
resolveReference(RequestAttributes.REFERENCE_REQUEST);
//获取存入缓存的用户信息
String userId = (String) redisClient
.get(String.format("%s:%s", CookieUtil.getUserCookieValue(request), RedisConstants.GLOBAL_SESSION_KEY));
GlobalUsers globalUser = globalUsersServiceApi.getGlobalUser(userId);
//基于formData方式提交
String requestParam = getRequestParam(request.getParameterMap());
if(StringUtils.isBlank(requestParam)){
//基于json方式提交
requestParam = JsonUtil.toFastJsonString(joinPoint.getArgs());
}
//记录操作日志
GlobalOperateLog globalOperateLog = new GlobalOperateLog()
.setId(UuidUtils.getOptimizedUUID()).setUserId(userId)
.setCreateTime(new Date()).setRemoteHost(request.getRemoteHost())
.setRemoteAddr(AddressUtils.getIpAddr(request)).setOperateName(globalUser.getCRealname())
.setOperateType(globalUser.getCUsertype());
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Log annotation = method.getAnnotation(Log.class);
String operateName = annotation.operateName();
StringBuilder stringBuilder = new StringBuilder().append("用户(")
.append(globalUser.getCUsername()).append(")正在通过条件为:")
.append(requestParam).append(operateName);
String action = stringBuilder.toString();
globalOperateLog.setContent(action);
globalOperateLogServiceApi.saveGlobalOperateLog(globalOperateLog);
}catch (Exception e){
log.error("aop add log error,{}", e.getMessage());
}
}
/**
* @param map 获取请求参数
* @return String
*/
private String getRequestParam(Map<String, String[]> map) {
JSONObject jsonObject = new JSONObject();
if(null != map && map.size() == 0){
return null;
}
for (String key : map.keySet()) {
jsonObject.put(key, map.get(key));
}
return jsonObject.toJSONString();
}
3)在接口上使用
@Log(methodName = AspectEnum.select, operateName = "查询认证企业信息")
public ResponseResult deleteCompany(String companyId, String userId) {
GlobalCompany globalCompany = globalCompanyMapper.selectById(companyId);
}
2.自定义 包扫描注解
1)定义注解
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(CallerScannerRegistrar.class)
public @interface CallerScan {
/**
* alias for basePackages
*
* @return
*/
String[] value() default {};
}
2)动态创建自定义bean到spring容器里
public class CallerScannerRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
AnnotationAttributes annotationAttributes = AnnotationAttributes
.fromMap(importingClassMetadata.getAnnotationAttributes(CallerScan.class.getName()));
Set<String> sets = Stream.of(annotationAttributes.getStringArray("value"))
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
String[] basePackages = sets.toArray(new String[0]);
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry,
false);
scanner.setBeanNameGenerator(new CallBeanNameGenerator());
scanner.addIncludeFilter(new AnnotationTypeFilter(Caller.class));
scanner.scan(basePackages);
}
}
3)使用
@CallerScan("com.xxx.app")
public class App {
public static void main(String[] args) throws Exception {
SpringApplication.run(App.class, args);
}
}