[AngularJS面面观] 17. 依赖注入 --- 注解的定义与实现

本文深入探讨AngularJS中的依赖注入机制,重点关注注解(Annotation)的角色。注解用于提供元数据,帮助注入器找到并管理被托管的对象。文章详细介绍了注解的三种实现方式:直接提供属性、基于数组的注解和源代码解析。每种方式都有其特点和适用场景,其中源代码解析方式虽然方便但可能因混淆处理而失效。了解注解的工作原理对于理解AngularJS的依赖注入至关重要。
摘要由CSDN通过智能技术生成

本篇文章继续介绍angular用以实现依赖注入的关键元素之一 - 注解(Annotation)。

在前几篇文章中,我们已经分析和讨论了有关angular依赖注入的几个方面:

  1. angular如何处理模块的声明和获取
  2. angular注入器的概念和它是如何加载模块以及执行模块定义的任务
  3. angular注入器如何管理被托管的对象

既然我们定义的服务和数据都已经被angular注入器托管在其内部的缓存中了,接下来应该如何使用它呢?写过angular应用的同学们应该都写过下面这类代码:

var testApp = angular.module('test', []);

testApp.controller('testController', function($scope, $rootScope) {
   
  // ......
});

我们直接在testContoller的函数中定义了两个服务,$scope以及$rootScope,然后就能够在应用的业务逻辑中使用这两项服务了,不需要自己将它们创建出来,也不需要做什么特别的准备工作,一切都显的水到渠成。但是!程序开发并不是变魔法,看似不可思议的事情背后总是有支撑它发生的逻辑。我们都知道这个逻辑就是依赖注入,而依赖注入的关键在于注入器,所以问题就演变成了注入器是如何找到对应的被托管的对象的呢?

答案是通过注解(Annotation)。所谓注解,它的本质就是给源代码添加一些元数据。有Java开发经验的同学想必都见过@Override@Deprecated以及@SuppressWarnings这类常用注解吧。它们的意义分别是表明某个方法覆盖了/实现了父类型(可以是父类,也可以是接口)上的同名方法;表明某个方法已经废弃了,不推荐再使用;抑制编译器产生警告信息。因为这类信息十分必要,但是又不好直接以传统意义上的源代码的形式体现出来,所以才设计出了注解这种数据类型。

那么切换到angular的上下文中,又是如何来实现注解的呢?这个注解需要解决什么问题呢?这就是本篇文章需要分析和讨论的主题。

我们已经知道定义的各种服务的函数实际上并不由我们自己来调用,而是交给angular框架提供的注入器进行调用,在调用的过程中首先我们需要知道注入器在哪个阶段会需要使用到注解提供的信息。其实在上一篇文章中在介绍注入器实例化托管对象的过程中可能发生循环依赖异常时就已经有一些线索了,这些线索就隐藏在异常的调用栈之中,我们来看看:

angular.js:13920 Error: [$injector:cdep] Circular dependency found: service1 <- service2 <- service1
http://errors.angularjs.org/1.5.8/$injector/cdep?p0=service1%20%3C-%20service2%20%3C-%20service1
    at angular.js:68
    at getService (angular.js:4656)
    at injectionArgs (angular.js:4688)
    at Object.instantiate (angular.js:4730)
    at Object.<anonymous> (angular.js:4573)
    at Object.invoke (angular.js:4718)
    at Object.enforcedReturnValue [as $get] (angular.js:4557)
    at Object.invoke (angular.js:4718)
    at angular.js:4517
    at getService (angular.js:4664)

可以看到在几个调用点: Object.instantiate -> injectionArgs -> getService

毫无疑问,从字面意思上就能够理解这里发生了什么。首先注入器会尝试实例化一个被托管的对象,在实例化的过程中由于该对象也存在依赖关系,需要首先解析这些依赖关系,得到依赖关系之后,才能够调用getService完成真正的实例化操作。而解析依赖关系实际上就是我们所关注的注解的生成过程。那么在清楚了注解的应用场景后,让我们看看injectionArgs这个函数的逻辑是怎样的:

function injectionArgs(fn, locals, serviceName) {
   
  var args = [],
      // 获取注解信息
      $inject = cre
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值