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