1、實現依賴注入 java
1.一、.一個問題:在@Controller中定義Service成員變量,而後在Controller的Action方法中調用Service成員變量的方法,如何實現Service成員變量呢?能夠經過@Inject註解來實現Controller中的Service實例化。code
1.二、一種方式:經過BeanHelper獲取全部BeanMap(記錄了類與對象的映射關係)。而後遍歷這個映射關係,分別取出Bean類與Bean實例,進而經過反射獲取類中的成員變量。繼續遍歷這些成員變量,在循環中判斷當前成員變量是否帶有@Inject註解,如果帶有該註解,則從BeanMap中根據Bean類取出Bean實例。最後經過Reflection#setFiled方法來修改當前成員變量的值。對象
1.三、編寫IocHelper.java類來完成這件事情。編寫好了IocHelper.java這個依賴注入的類,經過誰來加載呢?在何時加載呢?其實當IocHelper.java這個類被加載的時候,就會加載它的靜態代碼塊。因此咱們能夠找一個統一的地方來加載IocHelper.java這個類。get
package org.smart4j.framework.helper; import java.lang.reflect.Field; import java.util.Map; import org.smart4j.framework.annotation.Inject; import org.smart4j.framework.util.ArrayUtil; import org.smart4j.framework.util.ReflectionUtil; /** * 依賴注入助手類 * @author TS * */ public class IocHelper { static{ //獲取全部的Map映射 Map<Class<?>,Object> beanMap = BeanHelper.getBeanMap(); //遍歷BeanMap for ( Map.Entry<Class<?>, Object> entry : beanMap.entrySet() ) { Class<?> beanClass = entry.getKey(); Object beanInstance = entry.getValue(); //獲取一個Bean定義的全部成員變量 Field[] beanFields = beanClass.getDeclaredFields(); if( ArrayUtil.isNotEmpty(beanFields) ){ //不爲空 //遍歷成員變量 for ( Field beanField : beanFields ) { if( beanField.isAnnotationPresent( Inject.class ) ){ //判斷是否包含@Inject註解 Class<?> beanFieldClass = beanField.getType(); //獲取包含屬性的Class對象 Object beanFieldInstance = beanMap.get(beanFieldClass); //經過獲取的Class對象獲取Class對象的實例 if( beanFieldInstance != null ){ //經過反射初始化BeanField的值 ReflectionUtil.setField( beanInstance, beanField, beanFieldInstance ); } } } } } } }
1.四、此時IocHelper.java管理的對象都是單例的,IocHelper.java底層仍是從BeanHelper中獲取BeanMap的。而BeanMap中的對象都是事先建立好並放入這個Bean容器的,所以因此對象都是單例的。io
---------------------------------------summarize(總結):至此基於上層Bean容器實現了Ioc依賴注入的功能,就能夠經過@Inject註解來實現依賴注入了。-----------------------------------------class