先回顾下依赖注入的概念:
我们常提起的依赖注入(依赖注入)和控制反转(控制反转)是同一个概念,具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在春天里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者实例的工作通常由春容器来完成,然后注入调用者,因此也称为依赖注入。
其实简单的说,依赖注入起到的作用就是讲对象之间的依赖关系从原先的代码中解耦出来,通过配置文件或注解等方式加弹簧上框架的处理让我们对依赖关系灵活集中的进行管理。
依赖注入框架并不神秘,其实它是非常简单的东西。不要去看春天的依赖注入源码,因为你只要一去看就意味着你再也写不敢下手自己撸了,它的功能因为过于强大,所以设计也过于复杂,普通程序员一眼看去只能望洋兴叹。
我也并没有去细致阅读春源码。即便如此也只用了半天的时间便自己撸了一个基本满足标准依赖注入规范“jsr - 330”的小框架iockids。这个小框架只有一个主类喷射器,大约200行代码,它具备以下功能。
-
<李>单例/非单例注入李>
<李>构造器注入李>
<李>字段注入李>
<李>循环依赖注入李>
<李>预选赛注入李>
进口javax.inject.Inject; 进口javax.inject.Named; 进口javax.inject.Singleton; 进口iockids.Injector; @ singleton 类根{ @ inject @ named (“”) 节点; @ inject @ named (“b”) 节点b; @Override 公共字符串toString () { 返回字符串。格式(“根(%,% s)”、a.name () b.name ()); } } 接口节点{ 字符串名称(); } @ singleton @ named (“”) 类NodeA实现节点{ @ inject 叶的叶子; @ inject @ named (“b”) 节点b; @Override 公共字符串名称(){ if (b==null) 返回String.format (“nodeA (% s)”叶); 其他的 返回String.format (“nodeAWithB (% s)”叶); } } @ singleton @ named (“b”) 类NodeB实现节点{ 叶的叶子; @ inject @ named (“”) 节点; @ inject 公共NodeB(叶片叶){ 这一点。叶=叶; } @Override 公共字符串名称(){ 如果(==null) 返回String.format (“nodeB (% s)”叶); 其他的 返回String.format (“nodeBWithA (% s)”叶); } } 类叶{ @ inject 根的根; int指数; 静态整数序列; 公共叶(){ 指数=+ +序列; } 公共字符串toString () { 如果(root==null) 返回“叶子”+指数; 其他的 返回“leafwithroot”+指数; } } 公开课演示{ 公共静态void main (String [] args) { var喷射器=new喷射器(); injector.registerQualifiedClass(节点。类,NodeA.class); injector.registerQualifiedClass(节点。类,NodeB.class); var根=injector.getInstance (Root.class); System.out.println(根); } }
上面这份代码用到了iockids提供的所有功能。
-
<李>根/NodeA NodeB类是单例类李>
<李>叶类是非单例类李>
<李>它们都使用了字段注入李>
<李> NodeB使用了构造器注入李>
<李> NodeA和NodeB还使用了限定符名称注入李>
<李>叶类中有根类型的字段,这便是循环依赖李>
<李> NodeA中有NodeB字段,NodeB中有NodeA字段,这也是循环依赖李>
为了便于理解上述代码,我画了依赖图
根(nodeAWithB (leafwithroot0) nodeBWithA (leafwithroot1))
从这个输出中,我们也可以大致想象出依赖结构。
iockids提供了丰富的注入错误异常报告,防止用户注入配置出错。
比如我们将上面的NodeA和NodeB的名称都配置成一样的,就会曝出下面的错误堆栈
iockids。InjectException: javax.inject重复限定符。名叫iockids.demo.Node相同的类 iockids.Injector.registerQualifiedClass (Injector.java: 87) iockids.Injector.registerQualifiedClass (Injector.java: 70) iockids.demo.Demo.main (Demo.java: 106)200行Java代码如何实现依赖注入框架详解