时间:2021-05-02
依赖注入介绍
先回顾下依赖注入的概念:
我们常提起的依赖注入(dependency injection)和控制反转(inversion of control)是同一个概念。具体含义是:当某个角色(可能是一个java实例,调用者)需要另一个角色(另一个java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者 实例的工作通常由spring容器来完成,然后注入调用者,因此也称为依赖注入。
其实简单的说,依赖注入起到的作用就是讲对象之间的依赖关系从原先的代码中解耦出来,通过配置文件或注解等方式加上spring框架的处理让我们对依赖关系灵活集中的进行管理。
依赖注入框架
依赖注入框架并不神秘,其实它是非常简单的东西。不要去看spring的依赖注入源码,因为你只要一去看就意味着你再也写不敢下手自己撸了,它的功能因为过于强大,所以设计也过于复杂,普通程序员一眼看去只能望洋兴叹。
我也并没有去细致阅读spring源码。即便如此也只用了半天的时间便自己撸了一个基本满足标准依赖注入规范「jsr-330」的小框架iockids。这个小框架只有一个主类injector,大约200行代码,它具备以下功能。
我们看一个稍微复杂一点的使用示例
? 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 import javax.inject.inject; import javax.inject.named; import javax.inject.singleton; import iockids.injector; @singleton class root { @inject @named("a") node a; @inject @named("b") node b; @override public string tostring() { return string.format("root(%s, %s)", a.name(), b.name()); } } interface node { string name(); } @singleton @named("a") class nodea implements node { @inject leaf leaf; @inject @named("b") node b; @override public string name() { if (b == null) return string.format("nodea(%s)", leaf); else return string.format("nodeawithb(%s)", leaf); } } @singleton @named("b") class nodeb implements node { leaf leaf; @inject @named("a") node a; @inject public nodeb(leaf leaf) { this.leaf = leaf; } @override public string name() { if (a == null) return string.format("nodeb(%s)", leaf); else return string.format("nodebwitha(%s)", leaf); } } class leaf { @inject root root; int index; static int sequence; public leaf() { index = sequence++; } public string tostring() { if (root == null) return "leaf" + index; else return "leafwithroot" + index; } } public class demo { public static void main(string[] args) { var injector = new injector(); injector.registerqualifiedclass(node.class, nodea.class); injector.registerqualifiedclass(node.class, nodeb.class); var root = injector.getinstance(root.class); system.out.println(root); } }上面这份代码用到了iockids提供的所有功能。
为了便于理解上述代码,我画了依赖图
上面的代码输出如下
? 1 root(nodeawithb(leafwithroot0), nodebwitha(leafwithroot1))从这个输出中,我们也可以大致想象出依赖结构。
iockids提供了丰富的注入错误异常报告,防止用户注入配置出错。
比如我们将上面的nodea和nodeb的名称都配置成一样的a,就会曝出下面的错误堆栈
? 1 2 3 4 iockids.injectexception: duplicated qualifier javax.inject.named with the same class iockids.demo.node at iockids.injector.registerqualifiedclass(injector.java:87) at iockids.injector.registerqualifiedclass(injector.java:70) at iockids.demo.demo.main(demo.java:106)如果我们将nodeb的构造器随意加一个参数
? 1 2 3 4 @inject public nodeb(leaf leaf, int k) { this.leaf = leaf; }运行时就会抛出下面的错误
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 iockids.injectexception: no accessible constructor for injection class int at iockids.injector.createnew(injector.java:120) at iockids.injector.createnew(injector.java:94) at iockids.injector.createfromparameter(injector.java:167) at iockids.injector.createfromconstructor(injector.java:145) at iockids.injector.createnew(injector.java:123) at iockids.injector.createfromqualified(injector.java:216) at iockids.injector.createfromfield(injector.java:173) at iockids.injector.injectmembers(injector.java:233) at iockids.injector.createnew(injector.java:136) at iockids.injector.createfromqualified(injector.java:216) at iockids.injector.createfromfield(injector.java:173) at iockids.injector.injectmembers(injector.java:233) at iockids.injector.createnew(injector.java:136) at iockids.injector.createnew(injector.java:94) at iockids.injector.getinstance(injector.java:245) at iockids.demo.demo.main(demo.java:107)项目开源地址:https://github.com/pyloque/iockids
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:https://mp.weixin.qq.com/s/R14Xaq2iSUbVphdVtRiyjg
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
1、ASP.NETCore中的依赖注入此示例展示了框架级依赖注入如何在ASP.NETCore中工作。其简单但功能强大,足以完成大部分的依赖注入工作。框架级依赖注
一、spring依赖注入使用方式@Autowired是spring框架提供的实现依赖注入的注解,主要支持在set方法,field,构造函数中完成bean注入,注
依赖注入是指对象之间关系的控制权由应用代码中转到外部容器。Spring框架主要提供了Set注入和构造注入两种依赖注入方式。1:Set注入指的就是在接受注入的类中
spring是一个开源框架,功能主要是依赖注入和控制反转。依赖注入有三种形式1、构造注入(bytype)2、setter注入3、接口注入(byname)而控制反
详解Java注解的实现与使用方法Java注解是java5版本发布的,其作用就是节省配置文件,增强代码可读性。在如今各种框架及开发中非常常见,特此说明一下。如何创