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;
}
}定义代理工厂
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); } } }
定义注解处理类
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; } } }
使用jdk动态代理调用服务
publicstaticvoidmain(String[] args) { UserServicetarget = newUserServiceImpl(); // 创建代理UserServiceproxy = (UserService) newProxyFactory(target).getProxyInstance(); Useruser = newUser("天天"); // 账号注册user = proxy.register(user); System.out.println(user); }
输出结果
服务器访问次数 +1 User{id=-952421621, name='天天', password='null', status='null'}
