注解简单知识
关键字
自定义注解的关键字是@interface
参数类型
自定义注解的参数类型:八大基础类型、String、枚举、注解,还可以是以上类型对应的数组
如果只有一个成员变量,名字叫value
注解赋值
如果定义了成员变量,必须要给成员变量赋值 @MyAnnotation(value="")
如果只有一个成员变量,且成员变量的名称是value,可以省略value@MyAnnotation("")
如果成员变量给定默认值,可以不用再次赋值
一个注解的内部可以不定义成员变量的(@override)
定义了成员变量的注解叫元数据
没有定义成员变量的注解叫标记
元注解
用于修饰其他注解的注解
@Retention
值是一个枚举类型
用于声明生命周期
SOURCE:生命周期只在源文件中,编译器直接丢弃这种策略的注释,在.class文件中不会保留注解信息
CLASS:在字节码文件中有效,默认
RUNTIME:运行时有效,当运行Java程序时,JVM会保留注释,加载在内存中,程序可以通过反射获取该注释
@TARGET
用于指定被修饰的注解能用于修饰哪些程序元素
包含一个value的成员变量
值
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
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
}
@Document
用于指定被该元注解修饰的注解类将被javadoc工具提取成文档。默认情况下,javadoc时不包括注解的,但是加上了这个注解生成的文档中就带着注解了
Document注解修饰了Deprecated注解,那么 Deprecated注解就会在javadoc提取的时候,提取到API中
@Inherited
被它修饰的注解具有继承性,如果有个类使用了被@Inherited修饰的注解,那么它的子类也将具有该注解
aop实现自定义注解
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
写需要的注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAnnotation {
/** 请求类型 */
String reqType();
/** 接口类型 */
String apiType();
}
定义切面
@Aspect
@Component
public class LogAspect {
@Around("@annotation(logAnnotation)")
public Object around(ProceedingJoinPoint point, LogAnnotation logAnnotation) throws Throwable{
// 类名
String className = point.getTarget().getClass().getName();
// 方法名
String methodName = point.getSignature().getName();
// 开始时间
long startTime = System.currentTimeMillis();
// 执行方法 proceed就是返回值
Object proceed = point.proceed();
// 结束时间
long endTime = System.currentTimeMillis();
// 获取入参
String args = JSON.toJSONString(point.getArgs()[0]);
// 获取注解中apiType的值
String apiType = logAnnotation.apiType();
System.out.println("类名:" + className + ";方法名:" + methodName + ";开始时间:" + startTime + ";结束时间:" + endTime);
System.out.println("入参:" + args + ";返回值:" + proceed + ";注解参数apiType:"+ apiType);
// 获取签名
Signature signature = point.getSignature();
if(signature instanceof MethodSignature){
MethodSignature methodSignature = (MethodSignature) signature;
// 参数名称
String[] properties = methodSignature.getParameterNames();
System.out.println("参数名称:" + Arrays.toString(properties));
// 返回类型
Class<?> methodReturnType = methodSignature.getReturnType();
System.out.println("返回类型:" + methodReturnType);
}
return proceed;
}
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class TestAnnotation {
@Autowired
ServiceImpl service;
@Test
public void test(){
service.jieshao("zhangsan",19);
}
}
class Student{
public Student(String name, Integer age){
this.name = name;
this.age = age;
}
String name;
Integer age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
@Service
class ServiceImpl{
@LogAnnotation(reqType = "请求类型", apiType = "api类型")
public Student jieshao(String name, Integer age){
Student student = new Student(name, age);
return student;
}
}