手写框架流程,附上了获取bean和创建bean的代码,为附上加载配置文件,生成bean定义的代码
一.准备环境
1.导入依赖
2.写xml配置文件
3.编写测试代码
二.写框架
1.加载并解析配置文件
涉及到Bedifinition
2.创建Bean实例
判断单例缓存Map中是否存在需要的实例
存在
返回单例实例
不存在
创建实例
获取Bedifinition,判断是否为null
null,return null
判断是单例还是多例
单例
创建实例
创建bean的实例
注入属性
是否有初始化方法
有
- 执行方法 通过反射
无
是否有后置处理方法
有
- 通过aop处理
加入缓存Map
返回实例对象
多例
创建实例
返回实例对象
创建bean实例简化代码,只实现核心部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| private Map<String, BeanDefinition> beanDefinitions = new HashMap<>(); // 单例缓存 Map<String, Object> beans = new HashMap<String, Object>();
@Override public void registerBeanDefinition(String beanName, BeanDefinition bd) { beanDefinitions.put(beanName, bd); }
@Override public BeanDefinition getBeanDefinition(String beanName) { return beanDefinitions.get(beanName); }
// @Override public Object getBean2(String name) { // 从单例缓存获取实例对象 Object object = beans.get(name); // 有实例对象时返回实现对象 if (object != null) { return object; } // 没有实例对象,创建实例对象 // 获取Bedifinition,类的定义 BeanDefinition beanDefinition = getBeanDefinition(name); // 没有类的定义时返回实例null if (beanDefinition == null) { return null; } // 获取单例多例属性,判断多例还是单例 String scope = beanDefinition.getScope(); if ("singleton".equals(scope)) { // 单例: // 一、创建实例 Object bean = creaBean2(name, beanDefinition); // 二、加入单例缓存 beans.put(name, bean); // 三、返回单例实例 return bean; } else if ("prototype".equals(scope)) { // 多例: // 一、创建实例 // 二、返回实例 return creaBean2(name, beanDefinition); } return object; }
private Object creaBean2(String name, BeanDefinition beanDefinition) { // 1.创建bean的实例 // 1.1获取类的类型 String clazzName = beanDefinition.getClazzName(); // 1.2创建 Class<?> type = null; try { type = Class.forName(clazzName); } catch (ClassNotFoundException e) { e.printStackTrace(); } Object bean = ReflectUtils.createObject(type); // 2.注入属性 List<PropertyValue> propertyValues = beanDefinition.getPropertyValues(); for (PropertyValue propertyValue : propertyValues) { // 类属性名称 String name2 = propertyValue.getName(); // 类属性值 分两种,普通类型value和引用类型ref propertity中的value标签中的内容 Object value = propertyValue.getValue(); Object valueToUse = null; // 判断普通类型or引用类型 if (value instanceof TypedStringValue) {// 判断是否为普通类型 TypedStringValue typedStringValue = (TypedStringValue) value; String stringValue = typedStringValue.getValue(); Class<?> targetType = typedStringValue.getTargetType(); // 只匹配了两种Integer和String if (targetType == Integer.class) { // 确定了value的类型为Integer,注入属性 name2:属性名称:age;valueToUse:属性值:18 valueToUse = Integer.parseInt(stringValue); } else if (targetType == String.class) { valueToUse = stringValue; } } else if (value instanceof RuntimeBeanReference) {// 判断是否为引用类型 RuntimeBeanReference runtimeBeanReference = (RuntimeBeanReference) value; String ref = runtimeBeanReference.getRef(); // TODO 容易引起循环依赖问题 // 获取引用类型的属性,并注入。获取引用类型时,需要把引用类型Course中的属性name和age先注入到Course中 valueToUse = getBean2(ref); } // 设置属性 ReflectUtils.setProperty(bean, name2, valueToUse); } // 3.处理初始化方法 String initMethod = beanDefinition.getInitMethod(); if ("init".equals(initMethod)) { ReflectUtils.invokeMethod(bean, initMethod); } // 4.处理后置方法 aop return bean; }
|