照虎画猫写自己的Spring——依赖注入 (2)

在FairyApplicationContext中添加实现依赖注入功能的函数,主要思路就是对某个需要依赖注入的主体(这里的FairyService),找到要依赖注入的类(这里的FairyDao),借助反射机制,通过setter方法将FairyDao注入到FairyService中。

injectObject()

private void injectObject() { for (BeanDefinition beanDefinition : beanDefinitions) { Object bean = instanceBeans.get(beanDefinition.getId()); if (bean != null) { try { BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass()); /** * 通过BeanInfo来获取属性的描述器(PropertyDescriptor) * 通过这个属性描述器就可以获取某个属性对应的getter/setter方法 * 然后我们就可以通过反射机制来调用这些方法。 */ PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for (PropertyDefinition propertyDefinition : beanDefinition.getPropertyDefinitions()) { for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { // 用户定义的bean属性与java内省后的bean属性名称相同时 if (StringUtils.equals(propertyDescriptor.getName(), propertyDefinition.getName())) { // 获取setter方法 Method setter = propertyDescriptor.getWriteMethod(); if (setter != null) { Object value = null; if (StringUtils.isNotEmpty(propertyDefinition.getRef())) { // 根据bean的名称在instanceBeans中获取指定的对象值 value = instanceBeans.get(propertyDefinition.getRef()); } else { value = ConvertUtils.convert(propertyDefinition.getValue(), propertyDescriptor.getPropertyType()); } // //保证setter方法可以访问私有 setter.setAccessible(true); try { // 把引用对象注入到属性 setter.invoke(bean, value); } catch (Exception e) { LOG.error("invoke setter.invoke failed", e); } } break; } } } } catch (Exception e) { LOG.error("invoke getBean failed", e); } } } }

用到了Java内省获取Bean各个属性的setter和getter方法

使用了反射调用setter方法,将其注入FairyService类中

测试

编写测试代码

/** * bean依赖注入 */ FairyApplicationContext autowiredApplicationContext = new FairyApplicationContext("application-context-inject.xml"); FairyService fairyService = (FairyService) autowiredApplicationContext.getBean("fairyService"); fairyService.greet(); fairyService.lighting();

得到结果

===setFairyDao===: com.jackie.fairy.bean.impl.FairyDaoImpl@6615435c Hi, I am fairy ----------Hi, I am light fairy. Exactly, blue color light fairy----------

其中第一行打印结果是在通过反射执行setter.invoke(bean, value);时触发打印的。

至此,我们为Fairy实现了依赖注入的功能,项目地址
https://github.com/DMinerJackie/fairy

项目结构

照虎画猫写自己的Spring——依赖注入

Fairy项目改动盘点

添加FairyApplicationContext(String configLocation)构造函数,默认加载的配置文件是xml格式

添加Json配置文件解析器,可以解析Json格式的配置文件并加载bean

重构测试Bean,将接口FairyBean改为FairyDao,并新增FairyService接口及实现类,方便本文的用例测试

升级XmlReaderUtil,支持Bean的自标签Property的解析

添加依赖注入函数,用户实现依赖注入功能

添加PropertyDefinition模型,用于存储property属性值

如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!如果您想持续关注我的文章,请扫描二维码,关注JackieZheng的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。

照虎画猫写自己的Spring——依赖注入

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspwdp.html