Java中的注解
在java中,注解是一种为程序代码添加元数据(metadata)的方法。Java的注解通常用于提供有关代码的信息,例如配置、代码生成、代码分析等。Java的注解可以应用于类、方法、字段等各种元素。常见的Java注解包括:
@Override
:用于标识方法覆盖父类的方法。@Deprecated
:用于标记已经过时的方法。@SuppressWarnings
:用于抑制编译器警告。@Target
,@Retention
,@Documented
:用于定义自定义注解的元注解。
Spring boot的注解
- Spring boot中的注解是构建在Java注解的基础上,是为了简化Spring应用程序的开发而引入的。
- Spring Boot使用许多注解来简化配置、处理请求映射、定义Bean等任务。除了使用现有的注解外,你还可以自定义注解以满足特定需求。
自定义注解
使用@interface
关键字创建自定义注解。自定义注解可以包含元注解。成员变量、默认值等。示例:
@Target(ElementType.METHOD) // 可以应用于方法
@Retention(RetentionPolicy.RUNTIME) // 在运行时保留
public @interface MyCustomAnnotation {
String value() default "Default Value"; //成员变量
int priority() default 1; //成员变量
}
元注解
可以用于定义其他注解的注解。
@Target
用于指定注解的使用目标,注解的使用范围
ElementType类型 | 描述 |
---|---|
ElementType.TYPE | 标识注解可以用于类、枚举声明、接口(包括注解类型) |
ElementType.CONSTRUCTOR | 标识注解可以用于构造方法 |
ElementType.FIELD | 标识注解可以用于字段(成员变量) |
ElementType.LOCAL_VARIABLE | 标识注解可以用于局部变量 |
ElementType.METHOD | 标识注解可以用于方法 |
ElementType.PACKAGE | 标识注解可以用于包 |
ElementType.PARAMETER | 标识注解可以用于参数 |
ElementType.ANNOTATION_TYPE | 标识注解可以用于注解类型 |
ElementType.RECORD_COMPONENT | since 16 标识注解可以应用于记录组件 |
@Retention
用于指定注解的保留策略,注解的声明周期
RetentionPolicy类型 | 描述 |
---|---|
RetentionPolicy.Source | 注解仅在源代码阶段保留,在编译时被丢弃。这意味着注解不会存储在编译后的类文件中,也不会被反射获取。 |
RetentionPolicy.CLASS | 注解在编译时保留,并存储在类文件中。但在运行时不可获取。这是 Java 默认的保留策略。 |
RetentionPolicy.RUNTIME | 注解在运行时保留,可以通过反射获取。这意味着注解在编译时和运行时都可见,并且可以通过反射在运行时访问注解的信息。 |
@Inherited
用于标识一个注解是否可以被继承。当一个注解被标记为 @Inherited
时,它将被子类继承,从而可以在子类上生效。
需要注意的是,@Inherited
仅对类的继承有效,对于接口、字段、方法等成员元素是不生效的。此外,它只对直接继承的子类有效,不会传递给间接继承的子类。
@Constraint
用于定义自定义约束(constraint)。这个注解通常与其他注解一起使用,以创建自定义的验证规则,用于验证 Java Bean 中的字段或方法参数等。
自定义注解校验Demo
验证数据格式是否正确
创建自定义注解
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {IsMobileValidator.class})
public @interface IsMobile {
boolean require() default true;
String message() default "手机号格式错误";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
实现校验方法
public class IsMobileValidator implements ConstraintValidator<IsMobile, String> {
private boolean require = false;
@Override
public void initialize(IsMobile constraintAnnotation) {
require = constraintAnnotation.require();
}
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
if (require) {
return ValidatorUtil.isMobile(s);
} else {
if (StringUtils.isEmpty(s)) {
return true;
} else {
return ValidatorUtil.isMobile(s);
}
}
}
}
public class ValidatorUtil {
private static final Pattern mobile_pattern = Pattern.compile("1\\d{10}");
public static boolean isMobile(String src) {
if (StringUtils.isEmpty(src)) {
return false;
}
Matcher matcher = mobile_pattern.matcher(src);
return matcher.matches();
}
}
自定义注解-登录注解
创建自定义注解
// 标记了该注解的方法需要登录
@Retention(RUNTIME)
@Target(ElementType.METHOD)
public @interface NeedLogin {
}
spring boot拦截器
@Service
public class NeedLoginInterceptor extends HandlerInterceptorAdapter {
@Autowired
private RedisTemplate redisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
NeedLogin methodAnnotation = handlerMethod.getMethodAnnotation(NeedLogin.class);
//如果没有注解 直接返回
if (methodAnnotation == null) {
return true;
}
// 存在注解 登录校验
Cookie cookie = CookieUtil.getCookie(request, Const.COOKIE_NAME_TOKEN);
String token = null;
if (cookie != null) {
token = cookie.getValue();
}
User user = (User) redisTemplate.opsForValue().get(RedisPrefixKeyUtil.TOKEN + token);
if (cookie == null || token == null || user == null) {
String need = JSONObject.toJSONString(ResultDataDto.operationNeedLogin());
returnJson(response, need);
return false;
}
}
return true;
}
private void returnJson(HttpServletResponse response, String json) {
PrintWriter writer = null;
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=utf-8");
try {
writer = response.getWriter();
writer.print(json);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) {
writer.close();
}
}
}
}