一,注解概述
-
注解类型
-
标准注解,
- 如:@Override (虽然当重写方法时,不添加该注解也不会报错,但是加上后会进行编译检查,更方便代码理解),@Deprecated 已过时警告注解
-
元注解
-
@Retention 注解存在的生命周期。
-
RetentionPolicy.SOURCE 注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
-
RetentionPolicy.CLASS 注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期; 如:Lombok 下的注解,@Data,@Gette (用于动态生成 get,set等方法)
-
RetentionPolicy.RUNTIME 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;这种很常见,运行时通过反射进行注解捕获处理 如:spring 下的 @RequestMapping @RestController
-
-
@Target() 声明注解可以标注的位置
public enum ElementType { /** Class, interface (including annotation type), or enum declaration * 标注在类、接口、枚举类 */ TYPE, /** Field declaration (includes enum constants) 标注在properties属性 如:@Native */ FIELD, /** Method declaration 标注在方法 如:spring @GetMapping */ METHOD, /** Formal parameter declaration 标注在形参 如:spring @RequestParam */ PARAMETER, /** Constructor declaration 构造函数 */ CONSTRUCTOR, /** Local variable declaration 方法中的本地变量 */ LOCAL_VARIABLE, /** Annotation type declaration 应用于其他注解的元注解 */ ANNOTATION_TYPE, /** Package declaration 包 */ PACKAGE, /** * Type parameter declaration * * @since 1.8 */ TYPE_PARAMETER, /** * Use of a type * * @since 1.8 */ TYPE_USE }
-
-
自定义注解
-
二,自定义注解
package com.vipthink.ann.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author ligen
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyField {
String value() default "字段";
String description();
int length();
}
自定义注解的简单使用
package com.vipthink.ann.annotation;
import java.lang.reflect.Field;
/**
* @description:
* @author: regan
* @create: 下午5:25 2021/5/18
**/
public class MyFieldTest {
@MyField(length = 10, description = "用户名")
private String username = "aaaa";
@MyField(length = 11,description = "年龄")
private Long age = 1222L;
/**
* 自定义注解
*/
@org.junit.Test
public void testMyField() {
Class myFieldTestClass = MyFieldTest.class;
for (Field f : myFieldTestClass.getDeclaredFields()) {
// 判断这个字段是否有MyField注解
if (f.isAnnotationPresent(MyField.class)) {
MyField annotation = f.getAnnotation(MyField.class);
System.out.println("字段:[" + f.getName() + "], 描述:[" + annotation.description() + "], 长度:[" + annotation.length() + "]");
}
}
}
}
三,注解的使用场景 之 – 登录验证 / 拦截器模式
- 自定义注解
package com.example.demo.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 登录鉴权
*
* @author ligen
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginRequired {
}
- spring 拦截器模式 – Interceptor
package com.example.demo.interceptor;
import com.example.demo.annotation.LoginRequired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @description: mvc 配置类
* @author: regan
* @create: 下午2:07 2021/6/3
**/
@Configuration
public class BootWebMvcConfigure implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AccessInterceptor()).addPathPatterns("/**");
}
/**
* 拦截器逻辑
*/
public class AccessInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("进入拦截器了");
HandlerMethod handlerMethod = (HandlerMethod) handler;
LoginRequired loginRequired = handlerMethod.getMethod().getAnnotation(LoginRequired.class);
if (loginRequired == null) {
return true;
}
// 有LoginRequired注解说明需要登录,提示用户登录
response.setContentType("application/json; charset=utf-8");
response.getWriter().print("你访问的资源需要登录");
return false;
}
}
}
四, 注解使用场景之 – 日志 | aop模式
- 日志注解
package com.example.demo.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- @author ligen
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLog {
}
2. aop 切面
```java
package com.example.demo.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* @description:
* @author: regan
* @create: 下午2:43 2021/6/3
**/
@Aspect
@Component
public class MyLogAspect {
/**
* 切入点定义
*/
@Pointcut("@annotation(com.example.demo.annotation.MyLog)")
public void logPointCut() {
}
/**
* 环绕模式
*
* @param join
*/
@Around("logPointCut()")
public Object doAround(ProceedingJoinPoint join) throws Throwable {
//获取方法名称
String methodName = join.getSignature().getName();
//获取入参
Object[] param = join.getArgs();
StringBuilder sb = new StringBuilder();
for (Object o : param) {
sb.append(o).append(";");
}
System.out.println("进入[" + methodName + "]方法,参数为:" + sb.toString());
// 继续执行方法
Object proceed = join.proceed();
System.out.println(methodName + "方法执行结束");
return proceed;
}
}
五,常用注解 及spring注解处理器分析
-
spring 常用注解
- SpringBootApplication spring 启动文件注解
- ComponentScan 包扫描注解
- Resource jdk自带
- Autowired 自动装配首先时按照类型进行装配,若在IOC容器中发现了多个相同类型的组件,那么就按照 属性名称来进行装配 当有多个实现类时,推荐用Resource
- Component 作用就是将类注入到spring容器中
- Controller 控制器
- Service 业务逻辑组件类
- Repository Dao标注
- Scope 定义Bean 作用域
- PostMapping
- GetMapping
- ConfigurationProperties 标注为配置类bean
-
Lombok (编译型)
- Data 提供 Get Set 方法注入
- Accessors 目的是修改getter和setter方法的内容
- AllArgsConstructor 全参构造方法
- RequiredArgsConstructor 带参构造
- NoArgsConstructor 无参构造
- ToString
- EqualsAndHashCode
- Builder 建造者模式
-
Swagger 注解
- Api 作用与类 表示标识这个类是swagger的资源 【对应 Controller.class】
- ApiOperation 用与 方法的标识 表示一个http请求的操作 【对应 Controller.method
- ApiParam 用于方法,参数,字段说明; 表示对参数的添加元数据(说明或是否必填等)
- ApiModel 用于类 表示对类进行说明,用于参数用实体类接收 【对应 POJO类 DTO类等】
- ApiModelProperty 用于方法,字段 表示对model属性的说明或者数据操作更改 【对应 POJO类 下的属性】
- ApiIgnore 用于类,方法,方法参数 表示这个方法或者类被忽略