JAVA自定义注解的AOP和反射实际应用(日志和赋值)

首先我们先了解 AOP切面中execution和annotation的区别,我们这次仅演示annotation的用法
@execution作用:就是指定你要切入的一个地方,比如具体的方法,或者是接口
@annotation作用:项目中的方法,凡是带有被这个annotation修饰的注解,然后这个注解所修饰的方法或是接口都会被拦截!

普通用法,直接写了一个反射方法处理。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BlankAno {
}

@Data
public class AnalysisRows implements Serializable {
    private String id;
    @BlankAno
    private String crefo_no;
    private String company_name;
    private String company_name_en;
    @BlankAno
    private String company_name_old;
    @BlankAno
    private String company_aliasname;
    }
    /**
     * 返回的部分字段置空值
     * @param analysisRows
     * @throws IllegalAccessException
     */
    public void convertBlankField(AnalysisRows analysisRows) throws IllegalAccessException {
        Class<?> clazz = AnalysisRows.class;
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(BlankAno.class)) {
                field.setAccessible(true);
                field.set(analysisRows,"");
            }
        }
    }

下面是Annotation使用AOP切面

/**
 * 自定义注解 日志相关
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Syslog {
     String value() default "操作日志";
     String type() default "业务";
}

当检测到有SysLog则进入切面进行增强逻辑处理

    @Syslog("用户登录")
    @PostMapping("/login")
    @ApiOperation("用户登录")
    public ResponseDto login(@RequestBody User params) {
          xxxx
    }

进入AOP切面增强


/**
 * 自定义注解切面
 */
@Aspect
@Component
public class SysLogAspect {

    @Autowired
    private BaseController baseController;
//注意这里是@annotation 不是@execution
    @Pointcut("@annotation(com.linkedcare.technicalsupport.common.annotation.Syslog)")
    public void logPointCut() {

    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long startTime = System.currentTimeMillis();
        // 执行方法
        Object result = point.proceed();
        long costTime = System.currentTimeMillis() - startTime;
        // 核心代码
        saveSysLog(point,costTime);

        return result;
    }

    private void saveSysLog(ProceedingJoinPoint point, long time) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        String[] parameterNames = signature.getParameterNames();
        Arrays.stream(parameterNames).forEach( x-> System.out.println("参数名"+x));
        //Arrays.stream(signature.getParameterTypes()).forEach( x-> System.out.println("参数类型"+x.getFields()));

      /*  TypeVariable[] typeParameters = signature.getMethod().getTypeParameters();
        Arrays.stream(typeParameters).forEach(x-> System.out.println("111"+x));*/

        Class[] parameterTypes = signature.getParameterTypes();
        for (Class parameterType : parameterTypes) {
            Field[] fields = parameterType.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                System.out.println("2222"+field.getName());

                // 获取不到调用时传递的参数值,查资料也许可以使用cglib动态代理实现

            }
        }

        SysLogEntity sysLog = new SysLogEntity();
        // 获取注解的参数
        Syslog annotation = method.getAnnotation(Syslog.class);
        if (annotation != null) {
            // 注解上的描述
            sysLog.setOperation(annotation.value());
        }
        // 请求的方法名
        String className = point.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className + "." + methodName + "()");
        sysLog.setDelTag(0);

        // 请求的参数
        Object[] args = point.getArgs();
        String params = JSONObject.toJSONString(args);
        if (annotation.value().equals("退出当前账号")) {
             sysLog.setParams(null);
        } else {
            sysLog.setParams(params);
        }

        //获取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        // 获取ip
        sysLog.setIp(IpUtils.getIpAddr(request));
        // 获取操作用户
        //如果是登录就走参数查用户名
        if (annotation.value().equals("登录")) {
        /*    JSONArray objects = JSON.parseArray(params);
            if (objects != null && objects.size() > 0) {
                JSONObject jsonObject = objects.getJSONObject(0);
                if (Objects.nonNull(jsonObject)) {
                    //查询操作者名字
                    if (StringUtils.isNotBlank(jsonObject.getString("userName"))) {
                        sysLog.setUserName(jsonObject.getString("userName"));
                    }
                }
            }*/
            User loginUser = baseController.getLoginUser();
            sysLog.setUserName(loginUser.getUserName());
        } else {
         /*   //用户名
            String userName = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUserName();
            sysLog.setUserName(userName);*/
        }
        //保存日志
    }


}

你可能感兴趣的:(JAVA,反射,java,jvm,面试)