Java自定义注解和使用

1、定义和描述

注解是一种能被添加到java代码中的元数据,类、方法、变量、参数和包都可以用注解来修饰。注解对于它所修饰的代码并没有直接的影响。注解的出现是在jdk1.5,但是在jdk1.5版本使用注解必须继续类的方法的重写,不能用于实现的接口中的方法实现,在jdk1.6环境下对于继续和实现都是用。

2、元注解

2.1、@Target:表示该注解可以用于什么地方,ElementType参数值有:

   CONSTRUCTOR:构造器的声明
   FIELD:域声明(包括enum实例)
   LOCAL_VARIABLE:局部变量声明
   METHOD:方法声明
   PACKAGE:包声明
   PARAMETER:参数声明
   TYPE:类、接口(包括注解类型)或enum声明

2.2、@Retention:表示需要在什么阶段保存该注解信息,RetentionPolicy参数值有:

   SOURCE:注解将被编译器丢弃
   CLASS:注解在class文件中可用,但会被VM丢弃
   RUNTIME:VM将在运行期间保留注解,因此可以通过反射机制读取注解的信息

2.3、@Document:将注解保存在javadoc中

2.4、@Inherited:允许子类继承父类中的注解

3、基本语法

在底层代码实现中,我们自定义的注解都是自动继承java.lang.annotation.Annotation接口,类似于所有的类继承Object类。在自定义注解中,不需要书写构造、属性、方法,只有一种元素,注解类元素。

package com.geostar.geosmarter;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {

    //前缀
    String prefix() default "";

    //直接指定文件位置
    String[] locations() default {};
}

自定义注解还需要注意以下几点:

  1. 修饰符不许使用public,不可省略。
  2. 注解类元素只能是Java基本数据类型、String、Class、枚举、注解以及上述类型的一位数组。
  3. 注解类元素的名称一般使用名词。
  4. ()是一种特殊的写法,不是像方法一样定义参数的地方,()中间一直为空。
  5. default表示默认值,如果没有定义默认值,后续使用该注解时必须给注解类元素赋值。

4、自定义注解的使用

4.1、使用上面创建的自定义注解读取配置文件信息

package com.geostar.geosmarter;


@CustomAnnotation(prefix = "config",locations= {"config.properties"})
public class ConfigProperties {

	private String ip;
	private String port;
	
	public String getIp() {
		return ip;
	}
	public void setIp(String ip) {
		this.ip = ip;
	}
	public String getPort() {
		return port;
	}
	public void setPort(String port) {
		this.port = port;
	}
	
	@Override
	public String toString() {
		return "ConfigProperties [ip=" + ip + ", port=" + port + "]";
	}
	
}

4.2、测试

package com.geostar.geosmarter;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class Test {

    public static void main(String[] args) {
        Class<ConfigProperties> clazz = ConfigProperties.class;
        CustomAnnotation annotation = clazz.getAnnotation(CustomAnnotation.class);
        String[] locations = annotation.locations();
        Map<String,String> map = new HashMap<>();
        for (String location: locations) {
            Properties properties = new Properties();
            try{
                properties.load(Test.class.getClassLoader().getResourceAsStream(location.trim()));
            } catch (IOException e) {
                throw new IllegalStateException("Load properties [" + location + "] error", e);
            }
            for (Map.Entry<Object, Object> entry : properties.entrySet()) {
                String key = entry.getKey().toString();
                String value = entry.getValue() == null ? null : entry.getValue().toString();
                map.put(key, value);
            }
        }
		
        try {
            String prefix = annotation.prefix();
            ConfigProperties configProperties = clazz.newInstance();
            BeanInfo beanInfo = Introspector.getBeanInfo(clazz, Introspector.IGNORE_ALL_BEANINFO);
            PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor pd : pds) {
                String value = map.get(prefix + "." +  pd.getName());
                if (value != null) {
                    Method writeMethod = pd.getWriteMethod();
                    writeMethod.invoke(configProperties, value);
                }
            }
            System.out.println(configProperties);
        } catch (InstantiationException e) {
            throw new IllegalStateException("newInstance [" + clazz + "] error", e);
        } catch (IllegalAccessException e) {
            throw new IllegalStateException("newInstance [" + clazz + "] error", e);
        } catch (IntrospectionException e) {
            throw new IllegalStateException("getBeanInfo [" + clazz + "] error", e);
        } catch (IllegalArgumentException e) {
            throw new IllegalStateException("writeValue [" + clazz + "] error", e);
        } catch (InvocationTargetException e) {
            throw new IllegalStateException("writeValue [" + clazz + "] error", e);
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值