022.自定义注解

版权声明:本文为博主原创文章,允许转载,请标明出处。 https://blog.csdn.net/qwdafedv/article/details/84313998

注解是Jdk1.5新增新技术。很多框架为了简化代码,都会提供有些注解。
可以理解为插件,是代码级别的插件,在类的方法上写:@XXX,就是在代码上插入了一个插件。
注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。


定义

Java文件中叫做Annotation,用@interface表示。


元注解

@interface上面按需要注解上一些东西,
包括 @Retention@Target@Document@Inherited四种。


注解的保留策略

// 注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.SOURCE)   
// 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
@Retention(RetentionPolicy.CLASS)     
// 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Retention(RetentionPolicy.RUNTIME)  

注解的作用目标

// 接口、类、枚举、注解
@Target(ElementType.TYPE)                      
// 字段、枚举的常量
@Target(ElementType.FIELD)                     
// 方法
@Target(ElementType.METHOD)                 
 // 方法参数
@Target(ElementType.PARAMETER)           
// 构造函数
@Target(ElementType.CONSTRUCTOR)       
// 局部变量
@Target(ElementType.LOCAL_VARIABLE)   
 // 注解
@Target(ElementType.ANNOTATION_TYPE)
// 包
@Target(ElementType.PACKAGE)               

注解包含在javadoc中

@Documented

注解可以被继承

@Inherited

通过注解进行校验

demo1
package cn.qbz.thread.day1121;

import java.lang.annotation.*;

@Documented
@Inherited
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserAnnotation {
    int min() default 0;

    int max() default 120;

    boolean isNotNull() default true;
}

package cn.qbz.thread.day1121;

public class User {
    @UserAnnotation(isNotNull = true)
    private String name;
    @UserAnnotation(min = 18, max = 50)
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

package cn.qbz.thread.day1121;

import java.lang.reflect.Field;

public class UserCheck {

    public static boolean check(User user) throws Exception {

        if (user == null) {
            System.out.println("user is null.");
            return false;
        }

        Field[] fields = User.class.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            UserAnnotation userAnnotation = field.getAnnotation(UserAnnotation.class);
            String name = field.getName();
            Object value = field.get(user);
            int min = userAnnotation.min();
            int max = userAnnotation.max();
            boolean isNull = userAnnotation.isNotNull();

            if (isNull) {
                if (value == null) {
                    throw new Exception(name + " is null.");
                }
                int length = value.toString().length();
                if (length < min) {
                    throw new Exception(name + " length min is " + min);
                }
                if (length > max) {
                    throw new Exception(name + " length max is " + max);
                }
            }
        }
        return true;
    }
}

package cn.qbz.thread.day1121;

public class AnnotationTest {
    public static void main(String[] args) throws Exception {
        User user = new User();
        user.setAge(3);
        user.setName("sdfaf");

        UserCheck.check(user);
    }

}

demo2
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
package com.antzb.chaos.annotations;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.antzb.chaos.constant.ConstantKey;
import com.antzb.chaos.utils.CommonUtil;
import org.springframework.util.StringUtils;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: qubianzhong
 * @Date: 18-4-12 下午1:38
 */
@Documented
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ProjectUpdateTemplate.OrderByValidator.class)
public @interface ProjectUpdateTemplate {

    String message() default "[任务步骤格式有误!]";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    class OrderByValidator implements ConstraintValidator<ProjectUpdateTemplate, JSONObject> {
        @Override
        public void initialize(ProjectUpdateTemplate projectUpdateTemplate) {
        }

        @Override
        public boolean isValid(JSONObject template, ConstraintValidatorContext context) {
            context.disableDefaultConstraintViolation();
            boolean isRight = true;
            String errorMessage = "";
            if (template != null && template.size() > 0) {
                for (String key : template.keySet()) {
                    JSONObject element = template.getJSONObject(key);
                    if (element == null) {
                        isRight = false;
                        errorMessage = "任务步骤序号异常!必须为:1,2,3,4的字符串.";
                        break;
                    }
                }
            } else {
                isRight = false;
                errorMessage = "任务步骤不能为空";
            }
            context.buildConstraintViolationWithTemplate(errorMessage).addConstraintViolation();
            return isRight;
        }
    }
}

public class ProjectUpdateTemplateReq {
    @NotNull
    private Integer projectInfoId;
    @ProjectUpdateTemplate
    private JSONObject stepTemplate;

    public Integer getProjectInfoId() {
        return projectInfoId;
    }

    public void setProjectInfoId(Integer projectInfoId) {
        this.projectInfoId = projectInfoId;
    }

    public JSONObject getStepTemplate() {
        return stepTemplate;
    }

    public void setStepTemplate(JSONObject stepTemplate) {
        this.stepTemplate = stepTemplate;
    }
}

    @PostMapping
    public ResultMessage updateProjectOfTemplate(@Valid @RequestBody ProjectUpdateTemplateReq projectUpdateTemplateReq) {
     
     }
demo3
package com.rongyi.smart.web.checker.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckLogin {
}

package com.antzb.chaos.www.aspect;

import com.antzb.chaos.annotations.CheckLogin;
import com.antzb.chaos.constant.ConstantKey;
import com.antzb.chaos.www.util.JwtTokenUtil;
import io.jsonwebtoken.Claims;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;

/**
 * @Author: qubianzhong
 * @Date: 18-5-4 上午10:01
 */
@Component
@Aspect
public class CheckLoginAspect {
    @Pointcut("@annotation(checkLogin)")
    public void checkLoginPointCut(CheckLogin checkLogin) {
    }

    @Before("checkLoginPointCut(checkLogin)")
    public void doBefore(JoinPoint joinPoint, CheckLogin checkLogin) {
        String message = "请扫码登录后重新访问!";
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = sra.getRequest();

        request.setAttribute(ConstantKey.HTTPSERVLETREQUEST_ATTRIBUTES_CHECKLOGIN, true);

        String token = request.getHeader(ConstantKey.JWT_HEADER_KEY);
        if (token == null) {
            throw new SecurityException(message);
        }
        Claims claims = JwtTokenUtil.getClaimsFromToken(token.replace(ConstantKey.JWT_TOKENHEAD_KEY, ""));
        if (claims == null) {
            throw new SecurityException(message);
        }
        Object userName = claims.get(JwtTokenUtil.CLAIM_KEY_USERNAME);
        Object userId = claims.get(JwtTokenUtil.CLAIM_KEY_USERID);

        Timestamp expirationTime = new Timestamp(claims.getExpiration().getTime());
        if (userId == null
                || userName == null
                || expirationTime == null
                || expirationTime.before(new Timestamp(System.currentTimeMillis()))) {
            throw new SecurityException(message);
        }
    }

    @After("checkLoginPointCut(checkLogin)")
    public void doAfter(CheckLogin checkLogin) {
    }
}

    @GetMapping("/task/list")
    @CheckLogin
    public ResultMessage queryProjectTaskList() {
        ResultMessage resultMessage = new ResultMessage();
        //......
        return resultMessage;
    }

猜你喜欢

转载自blog.csdn.net/qwdafedv/article/details/84313998