照虎画猫写自己的Spring——自定义注解 (2)

这时候只需要在FairyServiceImpl类中的setFairyDao方法上加上注解JackieAutowired即可

public FairyDao getFairyDao() {         System.out.println("===getFairyDao===: " + fairyDao1.toString());         return fairyDao1;     }     @JackieAutowired     public void setFairyDao(FairyDao fairyDao1) {         System.out.println("===setFairyDao===: " + fairyDao1.toString());         this.fairyDao1 = fairyDao1;     }

配置文件声明如下

<beans>     <bean>     </bean>     <bean>     </bean> </beans>

这时候,我们不再需要在FairyServiceImpl中声明property属性,也不用声明ref指向fairyDao了,因为JackieAutowired已经能够处理他们之间的依赖关系并进行注入了。

运行结果

照虎画猫写自己的Spring——自定义注解

使用在属性上的注解处理 private void annotationInject() {         for (String beanName : instanceBeans.keySet()) {             Object bean = instanceBeans.get(beanName);             if (bean != null) {                 try {                     BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());                     PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();                     Field[] fields = bean.getClass().getDeclaredFields();                     for (Field field : fields) {                         if (field.isAnnotationPresent(JackieAutowired.class)) {                             JackieAutowired jackieAutowired = field.getAnnotation(JackieAutowired.class);                             Object value = null;                             if (jackieAutowired != null && StringUtils.isNotEmpty(jackieAutowired.name())) {                                 value = instanceBeans.get(jackieAutowired.name());                             } else {                                 value = instanceBeans.get(field.getName());                                 if (value == null) {                                     for (String key : instanceBeans.keySet()) {                                         if (field.getType().isAssignableFrom(instanceBeans.get(key).getClass())) {                                             value = instanceBeans.get(key);                                             break;                                         }                                     }                                 }                             }                             field.setAccessible(true);                             try {                                 field.set(bean, value);                             } catch (Exception e) {                                 LOG.error("invoke field.set failed", e);                             }                         }                     }                 } catch (Exception e) {                     LOG.error("invoke getBean failed", e);                 }             }         }     }

通过反射拿到Bean的所有字段Field数组

和上面类似,通过field.isAnnotationPresent(JackieAutowired.class)判断相应的字段上是否有JackieAutowired注解

找到JackieAutowired注解后,读取其name属性,如果有值,则进入上下文map中查找相应的bean实例

如果没有配置name属性,则通过属性的名称进入上下文map中根据名称和类型进行遍历,找到相应的bean实例

* 通过反射的方式注入实例化后的Bean,完成依赖注入

添加JackieAutowired注解

这时候添加的位置在属性上

@JackieAutowired private FairyDao fairyDao

其他配置同上一种情况,最终运行结果正常。

至此,Fairy实现了基于JackieAutowired注解的依赖注入。
项目地址https://github.com/DMinerJackie/fairy

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

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