自定义注解说明
这里是引用
使用@interface自定义注解,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。
@interface用来声明一个注解,其中的每一个类,方法,属性等实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。
定义注解格式:public @interface 注解名 {定义体}
定义注解类型元素时需要注意如下几点:
这里是引用
1.访问修饰符必须为public,不写默认为public;
2.该元素的类型只能是基本数据类型、String、Class、枚举类型、注解类型以及上述类型的一位数组;
3.该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为value(后面使用会带来便利操作);
4.()不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法;
5.default代表默认值,值必须和第2点定义的类型一致;
6.如果没有默认值,代表后续使用注解时必须给该类型元素赋值。
自定义注解的使用场景
1.类属性自动赋值。
2.验证对象属性完整性。
3.代替配置文件功能,像spring基于注解的配置。
4.可以生成文档,像java代码注释中的@see,@param等
**
代码案列:
**
1.作用在类上注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@ApiOperation(value = "作用在类上注解", notes = "作用在类上注解")
public @interface FiledAnnotation {
String value() default "GetFiledAnnotation";
}
2.作用在方法上注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@ApiOperation(value = "作用在方法上注解", notes = "作用在方法上注解")
public @interface MethodAnnotation {
String name() default "MethodAnnotation";
String url() default "https://www.cnblogs.com";
}
3.作用在属性上注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@ApiOperation(value = "作用在属性上注解", notes = "作用在属性上注解")
public @interface PropertyAnnotation {
String value() default "Is-TypeAnnotation";
}
4.自定义注解的使用类
@PropertyAnnotation(value = "doWork")
@ApiOperation(value = "自定义注解的使用类", notes = "自定义注解的使用类")
public class Worker {
@FiledAnnotation(value = "优快云博客")
private String myfield = "";
@MethodAnnotation()
public String getDefaultInfo() {
return "do the getDefaultInfo method";
}
@MethodAnnotation(name = "百度", url = "www.baidu.com")
public String getDefineInfo() {
return "do the getDefineInfo method";
}
}
5.自定义注解测试类
public class WorkerTestMain {
public static void main(String[] args) throws Exception {
Class cls = Class.forName("com.weshare.asset.aps.cmq.CustomComment.Worker");
Method[] method = cls.getMethods();
boolean flag = cls.isAnnotationPresent(PropertyAnnotation.class);
if (flag) {
PropertyAnnotation typeAnno = (PropertyAnnotation) cls.getAnnotation(PropertyAnnotation.class);
System.out.println("@TypeAnnotation值:" + typeAnno.value());
}
List<Method> list = new ArrayList<Method>();
for (int i = 0; i < method.length; i++) {
list.add(method[i]);
}
for (Method m : list) {
MethodAnnotation methodAnno = m.getAnnotation(MethodAnnotation.class);
if (methodAnno == null)
continue;
System.out.println("方法名称:" + m.getName());
System.out.println("方法上注解name = " + methodAnno.name());
System.out.println("方法上注解url = " + methodAnno.url());
}
List<Field> fieldList = new ArrayList<Field>();
for (Field f : cls.getDeclaredFields()) {// 访问所有字段
FiledAnnotation filedAno = f.getAnnotation(FiledAnnotation.class);
System.out.println("属性名称:" + f.getName());
System.out.println("属性注解值FiledAnnotation = " + filedAno.value());
}
}
}
最后在网上看到一个关于利用自定义注解打印接口调用时长日志的方法演示案列感觉很实用
这里是引用:下面代码引用自 https://www.cnblogs.com/moonandstar08/p/5975156.html
#创建ServiceLog类用来自定义注解
@Retention(RetentionPolicy.Runtime)
@Target(ElementType.METHOD)
public @interface ServiceLog {
}
#定义ServiceLogAspect类用来定义日志打印信息
@Component
@Aspect
public class ServiceLogAspect {
public ThreadLocal<Long> local = new ThreadLocal<Long>();
@Pointcut("@annotation(com.test.XXX.ServiceLong)")
public void pointCut() {
}
@Before("pointCut()")
public void before(JoinPoint point) {
String methodName = point.getTarget().getClass().getName()+"."+point.getSignature().getName();
local.set(System.currentTimeMillis());
}
@After("pointCut()")
public void after(JoinPoint point) {
long start = local.get();
String methodName = point.getTarget().getClass().getName()+"."+point.getSignature().getName();
System.out.println(System.currentTimeMillis()-start));
}
@AfterThrowing(pointcut="pointCut()",throwing="error")
public void throwing(JoinPoint point,Throwable error) {
System.out.println("error");
}
}