java annotation simple usage demo

Use annotations, simple simulation spring ioc container. Annotation by injection to a subject attribute values.

Project structure

annotation packet, for storing custom annotations

Component NOTE Indicates the class for a component class, and declare the name

package priv.haidnor.annotation;

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

/**
 * 组件
 */
@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Component {
    String name();
}

Value for annotation to the class of property assignment

package priv.haidnor.annotation;

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

/**
 * 字段值
 */
@Target(value = ElementType.FIELD)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Value {
    String value();
}

ioc package

package priv.haidnor.ioc;

import priv.haidnor.annotation.Component;
import priv.haidnor.annotation.Value;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

public class ApplicationContext {

    /**
     * IOC 控制反转容器,在加载类的时候创建 HashMap , 并存入指定对象
     */
    private static Map<String, Object> ioc;

    static {
        try {
            // 初始化 IOC 容器
            ioc = new HashMap<String, Object>();

            // 反射获得 Class 对象
            Class<?> clazz = Class.forName("priv.haidnor.pojo.Person");

            // 获取指定注解
            Component componentClass = clazz.getAnnotation(Component.class);

            // 获取指定注解的值
            String key = componentClass.name();

            // 通过反射创建对象
            Object object = clazz.newInstance();
            ioc.put(key, object);

            // 获取 Java Bean 所有的字段
            Field[] fields = clazz.getDeclaredFields();

            for (Field field : fields) {
                // 字段类型
                Class<?> type = field.getType();

                // 根据字段名生成 set 方法
                String filedName = field.getName();
                String methodName = produceSetMethodName(filedName);

                // 获得 Value 注解
                Value valueAnnotation = field.getAnnotation(Value.class);

                // 获得注解的值
                String theValue = valueAnnotation.value();

                // 构造 Method 对象
                Method method = clazz.getDeclaredMethod(methodName, field.getType());

                // 将注解参数转换类型
                Object value = typeConversion(field.getType(), theValue);

                // 执行 set 方法
                method.invoke(object, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 类型转换。将 String 字符串转换为指定数据类型类型的值
     * @param typeClass 字段类型
     * @param value 注解值
     * @return 字符串转换为指定数据类型类型的值
     */
    private static Object typeConversion(Class<?> typeClass, String value) {
        if (typeClass == int.class || typeClass == Integer.class) {
            if (value == null) {
                return 0;
            }
            return Integer.valueOf(value);
        } else if (typeClass == short.class) {
            if (value == null) {
                return 0;
            }
            return Short.valueOf(value);
        } else if (typeClass == byte.class) {
            if (value == null) {
                return 0;
            }
            return Short.valueOf(value);
        } else if (typeClass == double.class) {
            if (value == null) {
                return 0;
            }
            return Double.valueOf(value);
        } else if (typeClass == long.class) {
            if (value == null) {
                return 0;
            }
            return Long.valueOf(value);
        } else if (typeClass == String.class) {
            if (value == null) {
                return "";
            }
            return value;
        } else if (typeClass == Boolean.class) {
            if (value == null) {
                return false;
            }
            return Boolean.valueOf(value);
        } else if (typeClass == BigDecimal.class) {
            if (value == null) {
                return new BigDecimal(0);
            }
            return new BigDecimal(value + "");
        } else {
            return typeClass.cast(value);
        }
    }

    /**
     * 拼接字符串,生成 set 方法名
     * @param filedName 字段名
     * @return set方法名,例如传入"name",则返回"setName"
     */
    private static String produceSetMethodName(String filedName) {
        return "set" + filedName.substring(0, 1).toUpperCase() + filedName.substring(1);
    }

    /**
     * 从容器中获得指定对象
     * @param name 对象名称
     * @return IOC 容器中的对象
     */
    public static Object getBean(String name) {
        return ioc.get(name);
    }

}

pojo follicles

package priv.haidnor.pojo;

import priv.haidnor.annotation.Component;
import priv.haidnor.annotation.Value;

@Component(name = "man")
public class Person {

    @Value("张三")
    private String name;

    @Value("男")
    private String gender;

    @Value("中国")
    private String country;

    @Value("23")
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", country='" + country + '\'' +
                ", age=" + age +
                '}';
    }
}

Test category

import priv.haidnor.ioc.ApplicationContext;
import priv.haidnor.pojo.Person;

/**
 * 测试类
 */
public class Demo {
    public static void main(String[] args) {
        Person person = (Person) ApplicationContext.getBean("man");
        System.out.println(person);
    }
}

After running the program, the console output target information, you can see out from the ioc container object has successfully been assigned comment

Remark

Built-in notes

@Override: the definition java.lang.Override This comment applies only to rhetorical approach represents a method declaration is intended
to rewrite another method declaration in a superclass.

@Deprecated: java.lang.Deprecated definition, then this annotation can be used rhetorical methods, properties, classes, not showing
encourages programmers such elements, usually because it is dangerous or there is a better choice.

@SuppressWarnings: definition java.lang.SuppressWarnings in, to suppress warning messages during compilation.
Port before two different comments, you need to add a parameter to the proper use of these parameters are already good definition,
we selectively use just fine.

  • @SuppressWarnings ("all")
  • @SuppressWarnings ("unchecked")
  • @SuppressWarnings (value={"unchecked","deprecation"})
  • and many more……

4 yuan notes

Meta-annotation role is responsible for other notes annotations, Java defines four standard meta-annotation types, provided they are used as a description of other annotation types.
These types of classes and they support package in java.lang.annotation It can be found

@Target: used to describe the use of annotations (i.e.: Scope, annotations are described may be used in any place)

@Target(value = {ElementType.TYPE,ElementType.CONSTRUCTOR})
@Target(value = ElementType.TYPE)
@Target(ElementType.TYPE)

类,接口(包括注释类型)或枚举声明
    TYPE

字段声明(包括枚举常量)
    FIELD

方法声明
    METHOD

形式参数声明
    PARAMETER

构造声明
    CONSTRUCTOR

局部变量声明
    LOCAL_VARIABLE

注解类型声明
    ANNOTATION_TYPE

包声明
    PACKAGE

类型参数声明  @since 1.8
    TYPE_PARAMETER

使用类型 @since 1.8
    TYPE_USE

@Retention: expressed the need to save the annotation information on what level, it is used to describe the life cycle of notes (SOURCE <CLASS <RUNTIME)

@Retention(value = RetentionPolicy.CLASS)
@Retention(RetentionPolicy.CLASS)

注解将被编译阶段丢弃
    SOURCE
注解将由编译器记录在类文件中,但VM不必在运行时保留它们。这是默认行为。
    CLASS
注解由编译器记录在类文件中,并在运行时由VM保留,因此可以通过反射方式读取它们
    RUNTIME

@Document: indicates that the annotation will be included in the javadoc

@lnherited: Description subclass can inherit the parent class notes

Guess you like

Origin www.cnblogs.com/Haidnor/p/12241555.html