Skip to content

Latest commit

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

java-annotation

java代码中自定义注解的实现

元注解

元注解是java中注解的注解。所有注解的实现都需要使用元注解。

元注解包含如下集中:

  • @Documented

    会将注释包含到javaDoc中

  • @Retention

    传入参数RetentionPolicy表示需要在什么级别保存该注解信息

    RetentionPolicy枚举值如下:

    • SOURCE: 注解信息只保存在源代码中,编译时会被编译器丢弃
    • CLASS: 注解信息在.class文件中可见,但会被 VM丢弃。此项为默认项
    • RUNTIME: VM在运行时也会保留这些信息,因此可以通过反射读取到
  • @Target

    传入参数ElementType定义注解可在使用的位置

    ElementType 枚举如下:

    枚举值解释
    CONSTRUCT构造器的声明
    LOCAL_VARIABLE局部变量声明
    FIELD字段声明
    METHOD方法声明
    PACKAGE包声明
    PARAMETER参数声明
    TYPE类、接口(包括注解类型)或枚举声明
  • @Inherited

    允许子类继承父类中的注释

自定义注解

自定义类注解RecordVisit

@Documented// 设定为RUNTIME时生效@Retention(RetentionPolicy.RUNTIME)
// 声明为Class级别的注解@Target(value = ElementType.TYPE)
public @interface RecordVisit {
Stringvisit() default"服务器被访问了一次";
}

使用如下:

@RecordVisitpublicclassUserServiceImplimplementsUserService{
@OverridepublicUserregister(Useruser) {
user.setId(newRandom().nextInt());
returnuser;
}
}
测试
  1. 定义代理工厂

    publicclassProxyFactory {
    privateObjecttarget;
    publicProxyFactory(Objecttarget){
    this.target = target;
    }
    /** 生成代理对象*/publicObjectgetProxyInstance(){
    returnProxy.newProxyInstance(target.getClass().getClassLoader(),
    target.getClass().getInterfaces(),
    (proxy, method, args) -> {
    // 拦截目标类,检查注解使用情况valid(target);
    returnmethod.invoke(target,args);
    }
    );
    }
    private <T> voidvalid(Tt){
    Annotation[] annotations = t.getClass().getAnnotations();
    for(Annotationan :annotations){
    AnnotationCheck.check(an);
    }
    }
    }
  2. 定义注解处理类

    publicclassAnnotationCheck {
    privatestaticMap<String,Integer> map;
    static {
    map = newHashMap<>();
    map.put("RecordVisit",0);
    }
    publicstaticvoidcheck(Annotationannotation){
    StringsimpleName = annotation.annotationType().getSimpleName();
    switch (map.get(simpleName)){
    case0:
    // 检测到注解被使用时,do somethingSystem.out.println("服务器访问次数 + 1");
    break;
    default:
    break;
    }
    }
    }
  3. 使用jdk动态代理调用服务

    publicstaticvoidmain(String[] args) {
    UserServicetarget = newUserServiceImpl();
    // 创建代理UserServiceproxy = (UserService) newProxyFactory(target).getProxyInstance();
    Useruser = newUser("天天");
    // 账号注册user = proxy.register(user);
    System.out.println(user);
    }
  4. 输出结果

    服务器访问次数 +1
    User{id=-952421621, name='天天', password='null', status='null'}

注解的说明

java中的annotation图解

About

java annotation demo

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages