最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Java注解模擬spring ioc容器過程解析

 更新時(shí)間:2020年07月07日 11:23:54   投稿:yaominghui  
這篇文章主要介紹了使用Java注解模擬spring ioc容器過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

使用注解,簡單模擬spring ioc容器。通過注解給對象屬性注入值。

項(xiàng)目結(jié)構(gòu)

annotation 包,用于存放自定義注解

Component 注解表示該類為組件類,并需要聲明名字

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 注解用于給類的屬性賦值

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 控制反轉(zhuǎn)容器,在加載類的時(shí)候創(chuàng)建 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();

			// 通過反射創(chuàng)建對象
			Object object = clazz.newInstance();
			ioc.put(key, object);

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

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

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

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

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

				// 構(gòu)造 Method 對象
				Method method = clazz.getDeclaredMethod(methodName, field.getType());

				// 將注解參數(shù)轉(zhuǎn)換類型
				Object value = typeConversion(field.getType(), theValue);

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

	/**
	 * 類型轉(zhuǎn)換。將 String 字符串轉(zhuǎn)換為指定數(shù)據(jù)類型類型的值
	 * @param typeClass 字段類型
	 * @param value 注解值
	 * @return 字符串轉(zhuǎn)換為指定數(shù)據(jù)類型類型的值
	 */
	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);
	}
}

運(yùn)行程序后,控制臺(tái)輸出對象信息,可以看到從ioc容器中拿出的對象已經(jīng)成功被注解賦值

備注

內(nèi)置注解

@Override:定義在java.lang.Override中,此注釋只適用于修辭方法,表示一個(gè)方法聲明打算重寫超類中的另一個(gè)方法聲明.

@Deprecated:定義在java.lang.Deprecated中,此注釋可以用于修辭方法,屬性,類,表示不鼓勵(lì)程序員使用這樣的元素,通常是因?yàn)樗芪kU(xiǎn)或者存在更好的選擇.

@SuppressWarnings:定義在java.lang.SuppressWarnings中,用來抑制編譯時(shí)的警告信息.口與前兩個(gè)注釋有所不同,你需要添加一個(gè)參數(shù)才能正確使用,這些參數(shù)都是已經(jīng)定義好了的,我們選擇性的使用就好了.

  • @SuppressWarnings ("all")
  • @SuppressWarnings ("unchecked")
  • @SuppressWarnings (value={"unchecked","deprecation"})
  • 等等……

4個(gè)元注解

元注解的作用就是負(fù)責(zé)注解其他注解,Java定義了4個(gè)標(biāo)準(zhǔn)的meta-annotation類型,他們被用來提供對其他annotation類型作說明.
這些類型和它們所支持的類在java.lang.annotation包中可以找到

@Target:用于描述注解的使用范圍(即:作用域,被描述的注解可以用在什么地方)

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

類,接口(包括注釋類型)或枚舉聲明
  TYPE

字段聲明(包括枚舉常量)
  FIELD

方法聲明
  METHOD

形式參數(shù)聲明
  PARAMETER

構(gòu)造聲明
  CONSTRUCTOR

局部變量聲明
  LOCAL_VARIABLE

注解類型聲明
  ANNOTATION_TYPE

包聲明
  PACKAGE

類型參數(shù)聲明 @since 1.8
  TYPE_PARAMETER

使用類型 @since 1.8
  TYPE_USE

@Retention:表示需要在什么級(jí)別保存該注釋信息,用于描述注解的生命周期 (SOURCE<CLASS<RUNTIME)

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

注解將被編譯階段丟棄
  SOURCE
注解將由編譯器記錄在類文件中,但VM不必在運(yùn)行時(shí)保留它們。這是默認(rèn)行為。
  CLASS
注解由編譯器記錄在類文件中,并在運(yùn)行時(shí)由VM保留,因此可以通過反射方式讀取它們
  RUNTIME

@Document:說明該注解將被包含在javadoc中

@lnherited:說明子類可以繼承父類中的該注解

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • java+opencv實(shí)現(xiàn)人臉識(shí)別功能

    java+opencv實(shí)現(xiàn)人臉識(shí)別功能

    這篇文章主要介紹了java+opencv實(shí)現(xiàn)人臉識(shí)別功能,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • SpringBoot2.x版本中,使用SpringSession踩的坑及解決

    SpringBoot2.x版本中,使用SpringSession踩的坑及解決

    這篇文章主要介紹了SpringBoot2.x版本中,使用SpringSession踩的坑及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 詳解Java深拷貝,淺拷貝和Cloneable接口

    詳解Java深拷貝,淺拷貝和Cloneable接口

    這篇文章主要為大家詳細(xì)介紹了Java中Cloneable接口以及深拷貝與淺拷貝的相關(guān)知識(shí),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-08-08
  • 堆排序原理及算法代碼詳解

    堆排序原理及算法代碼詳解

    這篇文章主要介紹了堆排序算法的講解及Java版實(shí)現(xiàn),堆排序基于堆這種數(shù)據(jù)結(jié)構(gòu),在本文中對堆的概念也有補(bǔ)充介紹,需要的朋友可以參考下
    2021-08-08
  • Kotlin與Java 泛型缺陷和應(yīng)用場景詳解

    Kotlin與Java 泛型缺陷和應(yīng)用場景詳解

    這篇文章主要為大家介紹了Kotlin與Java 泛型缺陷和應(yīng)用場景詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Spring Boot事務(wù)配置操作

    Spring Boot事務(wù)配置操作

    這篇文章主要介紹了Spring Boot事務(wù)配置操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • java的內(nèi)部類和外部類用法講解

    java的內(nèi)部類和外部類用法講解

    本文詳細(xì)講解了java的內(nèi)部類和外部類用法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • PowerJob的OmsLogHandler工作流程源碼解析

    PowerJob的OmsLogHandler工作流程源碼解析

    這篇文章主要為大家介紹了PowerJob的OmsLogHandler工作流程源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Tomcat?8.5?+mysql?5.7+jdk1.8開發(fā)JavaSE的金牌榜小項(xiàng)目

    Tomcat?8.5?+mysql?5.7+jdk1.8開發(fā)JavaSE的金牌榜小項(xiàng)目

    這篇文章主要介紹了Tomcat?8.5?+mysql?5.7+jdk1.8開發(fā)JavaSE的金牌榜小項(xiàng)目,本文通過圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • SpringBoot+Security 發(fā)送短信驗(yàn)證碼的實(shí)現(xiàn)

    SpringBoot+Security 發(fā)送短信驗(yàn)證碼的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot+Security 發(fā)送短信驗(yàn)證碼的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05

最新評論

玛曲县| 若尔盖县| 南陵县| 屏山县| 高尔夫| 庄河市| 焉耆| 海盐县| 大方县| 漾濞| 汶川县| 平远县| 九江县| 巴林左旗| 玉龙| 新乡市| 北川| 旺苍县| 卓尼县| 台州市| 青田县| 如皋市| 涟源市| 汉源县| 彰化县| 芜湖市| 乐亭县| 买车| 连云港市| 宝应县| 武冈市| 鄱阳县| 前郭尔| 武鸣县| 潮州市| 盖州市| 富源县| 通海县| 长子县| 彰武县| 湘潭市|