实现一个简易版本的IOC
描述:简单的IOC其实就是一个map,key是对象名字,value是对象的实例,Spring容器初始化的时候会将配置文件或注解信息转换成BeanDefinition对象存储在集合中,然后遍历集合通过反射实例化Bean,实例化后的Bean会放入到名为singletonObjects的Map中,当调用getBean的时候会从singletonObjects对象中取出对应的Bean实例。
过程:
1.容器初始的时候加载BeanFactor
2.bean工厂初始化的时候创建BeanDefinitionRegistry生成singletonObjects(单例缓存对象)对象和加载文件资源生成beanDefinitionMap,将配置文件的数据维护进BeanDefinition
3.spring采用懒加载机制,只有当使用bean的时候才会创建Bean,使用Bean的时候会先去缓存中获取,如果缓存中不存在则使用反射创建根据类的Class对象实例化对象
备注:
1.beanDefinitionRegistry管理和存储Bean的定义信息
2.BeanDefinition中维护bean的类型、作用域、依赖项和初始化参数等信息
1.项目结构

1.配置文件bean.properties(简单处理定义成key:values)
student:ioc.Student
teacher:ioc.Teacher
2.定义BeanDefinition对象,BeanDefinition中维护bean的类型、作用域、依赖项和初始化参数等信息
import lombok.Data; @Data public class BeanDefinition { private String beanName; private Class beanClass; }
3.读取配置文件内容到beanDefinitionMap,beanDefinitionRegistry管理和存储Bean的定义信息
import java.io.InputStream; import java.util.*; public class ResourceLoader { public Map<String,BeanDefinition> getResource(){ //定义beanDefinitionMap Map<String,BeanDefinition> beanDefinitionMap = new HashMap<>(16); Properties properties = new Properties(); try { //读取配置文件 InputStream inputStream = ResourceLoader.class.getResourceAsStream("/beans.properties"); properties.load(inputStream); Set<String> strings = properties.stringPropertyNames(); Iterator<String> iterator = strings.iterator(); while (iterator.hasNext()){ String key = iterator.next(); String className = properties.getProperty(key); Class clazz = Class.forName(className); BeanDefinition beanDefinition = new BeanDefinition(); beanDefinition.setBeanName(key); beanDefinition.setBeanClass(clazz); //beanDefinitionMap中添加对应BeanDefinition对象 beanDefinitionMap.put(key,beanDefinition); } inputStream.close(); } catch (Exception e) { e.printStackTrace(); } return beanDefinitionMap; } }
4.处理BeanDefinitionRegistry生成单例缓存singletonObjects,BeanDefinitionRegistry负责维护bean对象,包括存储、创建、获取、删除
import java.util.HashMap; import java.util.Map; public class BeanDefinitionRegistry { //单例Bean缓存 private Map<String, Object> singletonObjects = new HashMap<>(32); /** * 获取单例Bean * * @param beanName bean名称 * @return */ public Object getSingletonBean(String beanName) { return singletonObjects.get(beanName); } /** * 注册单例bean * * @param beanName * @param bean */ public void registerSingletonBean(String beanName, Object bean) { if (singletonObjects.containsKey(beanName)) { return; } singletonObjects.put(beanName, bean); } /** * 移除bean对象 * @param beanName */ public void removeSingletonBean(String beanName){ singletonObjects.remove(beanName); } }
5.定义Bean工厂BeanFactory,容器初始的时候加载BeanFactor
import java.util.HashMap; import java.util.Map; public class BeanFactory { Map<String,BeanDefinition> beanDefinitionMap = new HashMap<>(16); private BeanDefinitionRegistry beanDefinitionRegistry; //bean工厂初始化的时候创建beanDefinitionRegistry对象和加载文件资源 public BeanFactory(){ //创建beanDefinitionRegistry对象 beanDefinitionRegistry = new BeanDefinitionRegistry(); //加载资源文件 beanDefinitionMap = new ResourceLoader().getResource(); } //获取bean的方法 public Object getBean(String beanName){ Object bean = beanDefinitionRegistry.getSingletonBean(beanName); if(bean != null){ return bean; } return createBean(beanDefinitionMap.get(beanName)); } //创建bean的方法,懒加载 private Object createBean(BeanDefinition beanDefinition){ try { //实例化bena Object bean = beanDefinition.getBeanClass().newInstance(); //将实例化的bean放入到缓存中 String beanName = beanDefinition.getBeanName(); beanDefinitionRegistry.registerSingletonBean(beanName,bean); return bean; } catch (Exception e) { e.printStackTrace(); } return null; } }
6.数据验证
public class MainTest { public static void main(String[] args) { BeanFactory beanFactory = new BeanFactory(); Student student = (Student)beanFactory.getBean("student"); student.setName("张三"); student.setAge(18); System.out.println(student); Teacher teacher = (Teacher)beanFactory.getBean("teacher"); teacher.setName("李老师"); teacher.setAge(36); System.out.println(teacher); } }


浙公网安备 33010602011771号