java笔记_12_自定义注解

1、@interface

用于声明注解,参数只用八种基本数据类型和四种数据类型(基本类型 byte,short,char,int,long,float,double,boolean 八种基本数据类型 和 String,Enum,Class,annotations ),如果只有一个参数成员,最好把参数名称设为"value"

2、@Target
说明了Annotation所修饰的对象范围,取值(ElementType)有:
CONSTRUCTOR(用于描述构造器)
FIELD(用于描述域,作用于属性)
LOCAL_VARIABLE(用于描述局部变量)
METHOD(用于描述方法,作用于方法)
PACKAGE(用于描述包)
PARAMETER(用于描述参数)
TYPE(用于描述类、接口(包括注解类型) 或enum声明,作用于类)

3、@Retention

设置注解的生命周期
RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃
RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期
RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在

4、@Document

用于描述其它类型的 annotation 应该被作为被标注的程序成员的公共API,因此可以被例如 javadoc 此类的工具文档化。Documented 是一个标记注解,没有成员。

表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)。

5、@Inhrited

是一个标记注解,@Inherited 阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited 修饰的 annotation类型 被用于一个 class,则这个 annotation 将被用于该class的子类。

复制代码
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApprovalTaskRecord {

    /**
     * 方法描述:权限点
     * 参数类型 参数名() 默认值
     */
    String permission() default "";

    /**
     * 方法描述:微服务名@微服务方法名
     * 参数类型 参数名() 默认值
     */
    String interfacePath() default "";
}
复制代码
自定义注解使用:
@ApprovalTaskRecord(permission = "111",interfacePath = "222")
@ApiOperation("新增")
@PostMapping("/insert")
public ResultResp<ParamResp> insert(@RequestBody @Validated InsertReq req){
    ParamResp data = paramService.insert(req);
    return ResultResp.success(data);
}

方法实现:

复制代码
// aop

@Slf4j
@Aspect
@Component
public class ApprovalTaskLogAspect {

    @Autowired
    ApprovalTaskLogService approvalTaskLogService;

    @Pointcut("@annotation(com.apexsoft.crm.ams.annotation.ApprovalTaskRecord)")
    public void record() {
    }

    /**
     * 环绕增强,相当于 MethodInterceptor
     */
    @Around("record() && @annotation(approvalTaskRecord)")
    public Object doAround(ProceedingJoinPoint joinPoint, ApprovalTaskRecord approvalTaskRecord) throws Throwable {
        Object res = null;

        try {
            if (approvalStatus(approvalTaskRecord) == false) {
                // 执行原有方法
                res = joinPoint.proceed();
            } else {
                // 拦截,执行自定义写日志方法,原有方法不执行;如果要执行,加上res = joinPoint.proceed()方法调用;
                addApprovalTaskLog(joinPoint, approvalTaskRecord);
            }
        } catch (Exception e) {
            log.error("ApprovalTaskLogAspect 操作落库失败:" + e.getMessage());
        }
        return res;
    }

    /**
     * 判断是否需要审批
     * @param
     * @return
     */
    private Boolean approvalStatus (ApprovalTaskRecord approvalTaskRecord) {
        JSONObject paramJson = new JSONObject();
        paramJson.put("operatePrivilege", approvalTaskRecord.permission());
        String approvalStatus = approvalTaskLogService.selApprovalStatus(paramJson);
        if (approvalStatus!= null && "1".equals(approvalStatus)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 方法执行前,增加日志
     *
     * @param joinPoint
     * @param approvalTaskRecord
     */
    private void addApprovalTaskLog(JoinPoint joinPoint, ApprovalTaskRecord approvalTaskRecord) {
        JSONObject paramJson = new JSONObject();
        // 获取入参数据,在方法执行前没有出参数据
     Object[] paramValues = joinPoint.getArgs();
        String params = "";
        if (paramValues != null && paramValues.length > 0) {
            for (Object o : paramValues){
                if(!Objects.isNull(o)){
                    try {
                        String jsonObj = JSON.toJSONString(o);
                        params += jsonObj + " ";
                    } catch (Exception e) {

                    }
                }
            }
        }
        paramJson.put("requestBody", params); // {"id":1,"name":"123123"} 
     // 获取注解中传入的数据
        paramJson.put("operatePrivilege", approvalTaskRecord.permission()); // 111
        paramJson.put("interfacePath", approvalTaskRecord.interfacePath()); // 222

        log.info("对象approvalTaskLogModel:" + paramJson);
     // 调用写日志方法
        approvalTaskLogService.approvalTaskLog(paramJson);
    }
}
复制代码

 


参考:

https://blog.csdn.net/qq_38617531/article/details/125719481

https://mp.weixin.qq.com/s?__biz=MzA5MzI3NjE2MA==&mid=2650238479&idx=1&sn=cef582b5c5a15853f391d013a0747a9d&chksm=88639f60bf1416761f9da62e7b59c0d2f892d1b6f6e85a809f963dca593cffdcb14a9e171ddb&scene=27


posted @   LuLuYaa  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示