摘要:有多种注入的策略,比如按照装配名称,或者是默认实现了接口或者抽象类的子类实例对象来注入。这个方法中,做了一些简单的判断,如果这个类本身就不是一个抽象类或者不是一个接口,那么这个类就是第一个合适的类。
申明:本文不是讲解Spring如何使用注解,本文只是通过一个简单的实现,来理解Spring是如何注入一个对象的。
用过Spring的同学都知道,Spring利用注解来实现依赖注入,使得各个类之间的耦合性极大的降低了。但是仅仅是使用,并不能理解到Spring内部是怎么实现的。笔者没有看过Spring的源码。只能从自己的角度来谈谈Spring是怎么实现的。感兴趣的同学可以在看过本文之后,深入的了解Spring.
很多时候,我们都有这样的应用场景。比如DAO层,你会先申明一个接口,比如IUserDao,表示用来处理User的一个接口,然后再写一个实现类UserDaoImpl实现了IUserDao中的方法,然后在上层service层中注入。启动之后Spring将自己扫描自动为我们注入实例化的对象,使得我们不用在意各个对象的生命周期。接下来就来聊聊具体是怎么注入的。
假设现在已经有以下的类:
public interface IUserDao { public void setData(String data); public String getData(); } public class UserDaoImpl implements IUserDao{ @Override public void setData(String data) { System.out.println("data is : " + data); } @Override public String getData() { return "just test"; } }
其中FieldInject是笔者模仿写的一个注解,具体定义如下
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FieldInject { //假设有一些变量用于控制策略 }
具体关于注解上面的元注解的含义,可以看另外一篇博客。这里就不展开说明了。
以上就是准备工作了,接下来就是讲解真正的初始化方法了。
假设我们现在有一个类的Class对象,那么我们可以根据这个Class对象找到哪些成员变量是加了指定的注解的。代码如下
//下面开始注入 for(int i=0; i在这段代码中,笔者查询的注解是自己实现的一个FieldInject注解,注解本身并不影响代码的执行。通过判断是否为空可以得出某个成员变量是否加了指定的注解。如果发现成员变量加了注解,就可以为该成员变量注入实例化的对象了。
问题1:怎么知道注入哪个对象?
问题2:怎么注入?
问题2很好解决,如果原来的类中带有setter方法,那么可以使用method.invoke()方法来调用并注入。或者通过field直接注入都可以。那么主要是问题1,怎么找到合适的注入对象。
Spring有多种注入的策略,比如按照装配名称,或者是默认实现了接口或者抽象类的子类实例对象来注入。总之,不同的策略只是选择的不同,我们可以假定使用找到的第一个合适子类的实例对象来注入。//找到某个类的子类【涉及到Spring的选择策略】 private Class findSubClass(String fullClassName){ try { Class target = Class.forName(fullClassName); //不是抽象类,不是接口,那自身就好了。 if(!target.isInterface()){ boolean isAbs = Modifier.isAbstract(target.getModifiers()); if(!isAbs) return target; } int size = clazzList.size(); for(int i=0; ifindSubClass是用来找到某个类的合适子类,类似于Spring中根据某种策略来查找,这里使用了比较简单的方法。找到第一个合适的子类即可。这个方法中,做了一些简单的判断,如果这个类本身就不是一个抽象类或者不是一个接口,那么这个类就是第一个合适的类。如果这个类是一个接口或者一个抽象类,那么就在全局扫描的classList中找到合适的类。找到合适的类之后,下一步就是一个注入了,笔者采用的是给setter方法注入,如果想直接给成员变量赋值也是非常简单的。只要替换掉方法injectMethod,换成下面两句代码即可。
field[i].setAccessible(true); field[i].set(target, obj);injectMethod实现也是比较简单,通过比对Method中的方法,找到合适的setter方法(这里是通过field的名称来判断的),并将实例对象赋值进去即可。以上就是一个简单的注入过程的实现。笔者写的比较匆忙,可能有些细节上经不起推敲。但是如果能为迷惑的初学者提供一个思路也是不错的,这份代码我都上传到github上了,如果想下载进行运行的可以移步我的github。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/66788.html
摘要:使用的好处知乎的回答不用自己组装,拿来就用。统一配置,便于修改。 前言 只有光头才能变强 回顾前面: 给女朋友讲解什么是代理模式 包装模式就是这么简单啦 单例模式你会几种写法? 工厂模式理解了没有? 在刷Spring书籍的时候花了点时间去学习了单例模式和工厂模式,总的来说还是非常值得的! 本来想的是刷完《Spring 实战 (第4版)》和《精通Spring4.x 企业应用开发实战》...
摘要:它的构造器上添加了注解,这表明当创建的时候,会通过这个构造器来进行实例化并且会传入一个可设置给类型的通过自动装配,将一个注入到之中注解不仅能够用在构造器上,还能用在属性的方法上。 Spring配置的可选方案 Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系。当描述bean如何进行装配时,Spring具有非常大的灵活性,它提供了三种主要的装配机制: 在XM...
摘要:关于依赖注入注入的注解提供的注解不仅仅是对象,还有在构造器上,还能用在属性的方法上。与之相反,的限定符能够在所有可选的上进行缩小范围的操作,最终能够达到只有一个满足所规定的限制条件。注解是使用限定符的主要方式。 本文首发于泊浮目的专栏:https://segmentfault.com/blog... Spring致力于提供一种方法管理你的业务对象。在大量Java EE的应用中,随处可...
摘要:入门篇学习总结时间年月日星期三说明本文部分内容均来自慕课网。主要的功能是日志记录,性能统计,安全控制,事务处理,异常处理等等。 《Spring入门篇》学习总结 时间:2017年1月18日星期三说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学示例源码:https://github.com/zccodere/s...个人学习源码:https://git...
摘要:先来看代码吧,一会松哥再慢慢解释关于这一段自动配置,解释如下首先注解表明这是一个配置类。本文的案例,松哥已经上传到上了,地址。我们使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中。Starter 为我们带来了众多的自动化配置,有了这些自动化配置,我们可以不费吹灰之力就能搭建一个生产级开发环境,有的小伙伴会觉得这个 Starter 好神奇呀!其实 Starter 也都...
阅读 3101·2023-04-25 15:02
阅读 2744·2021-11-23 09:51
阅读 2007·2021-09-27 13:47
阅读 1962·2021-09-13 10:33
阅读 907·2019-08-30 15:54
阅读 2624·2019-08-30 15:53
阅读 2830·2019-08-29 13:58
阅读 846·2019-08-29 13:54