注釈、簡単なシミュレーション春のIoCコンテナを使用してください。対象の属性値への注射による注釈。
プロジェクト構造
カスタム注釈を格納するための注釈パケット、
コンポーネントNOTEは、コンポーネントクラスのクラスを示し、そして名を宣言します
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();
}
プロパティの割り当てのクラスへのアノテーションの値
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 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 包
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 +
'}';
}
}
テストカテゴリ
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);
}
}
プログラムを実行した後、コンソール出力先情報は、あなたが正常にコメントを割り当てられているIoCコンテナオブジェクトから見ることができます
リマーク
内蔵ノート
@Override:このコメントは唯一の修辞的なアプローチに適用される定義java.lang.Overrideは、メソッドの宣言が意図されて表し
スーパークラス内の別のメソッド宣言を書き換えます。
@deprecated:java.lang.Deprecated定義し、この注釈が表示されない、修辞的なメソッド、プロパティ、クラスを使用することができますが
、それは危険であるか、より良い選択肢があるため、通常は、プログラマにそのような要素を奨励しています。
@SuppressWarnings:定義java.lang.SuppressWarningsで、コンパイル時の抑制の警告メッセージに
ポート二つの異なるコメントの前に、あなたは、これらのパラメータの適切な使用にパラメータを追加する必要があり、すでに良い定義されています、
私たちは、選択だけで罰金を使用します。
- @SuppressWarnings( "すべて")
- @SuppressWarnings( "未チェック")
- @SuppressWarnings(値= { "未チェック"、 "廃止"})
- などなど......
4元のメモ
メタアノテーションの役割は、他のノート注釈を担当し、Javaは4つの標準メタ注釈型を定義し、それらが他の注釈型の記述として使用されている提供。
クラスのこれらのタイプを、彼らはjava.lang.annotationのパッケージをサポートそれは見つけることができます
@target:注釈の使用説明するために使用される(注釈が記載されている、すなわち:スコープは、任意の場所で使用されてもよいです)
@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:どのようなレベルでの注釈情報を保存する必要性を表明し、ノートのライフサイクルを記述するために使用される(SOURCE <CLASS <RUNTIME)
@Retention(value = RetentionPolicy.CLASS)
@Retention(RetentionPolicy.CLASS)
注解将被编译阶段丢弃
SOURCE
注解将由编译器记录在类文件中,但VM不必在运行时保留它们。这是默认行为。
CLASS
注解由编译器记录在类文件中,并在运行时由VM保留,因此可以通过反射方式读取它们
RUNTIME
@Document:注釈がjavadocの中に含まれることを示します
@lnherited:説明サブクラスは親クラスのノートを継承することができます