Java7技术系列:try-with-resource
Java7技术系列:int与二进制的转换优化
Java7技术系列:MultiCatchException
Java7技术系列:NIO.2异步IO
Java7技术系列:DI依赖注入
Java7技术系列:Queue
Java7技术系列:Java并发

1 依赖注入介绍

javax.inject:这个包指明了获取对象的一种方式,与传统的构造方法、工厂模式和服务器定位模式等相比,这种方式的可重用性、可测试性和可维护性都得到了极大提升。这种方式称为依赖注入,对于大多数非小型应用程序都很有帮助。

javax.inject 包里包括一个 Provider<T> 接口和5个注解类型(@Inject、@Qualifier、@Named、@Scope和@Singleton)

2 @Inject

@Inject 注解可以出现在三种类成员之前,表示该成员需要注入依赖项。按运行时的处理顺序,这三种类型是:

  • 构造器

  • 方法

  • 属性

在构造器上使用@Inject 时,其参数在运行时由配置好的Ioc容器提供。

规范中规定向构造器或方法中注入的依赖项为0个或多个,所以在没有参数的构造器或方法中添加注解是合法的。

注意:因为JRE无法决定构造器注入的优先级,所以规范中规定类中只能有一个构造器用@Inject注解。

构造器注入Header和Content

@Inject public MurmurMessage(Header header, Content content) {this.header = header;this.content = content;
}

注意:使用注入的方法不能声明为抽象方法,也不能声明其自身的类型参数。

方法注入

@Inject public void setContent(Content content) {this.content = content;
}

向构造器中注入的通常是类中必须的依赖项,而对于非必需的依赖项,通常是在set方法上注入。

比如已经给出了默认值的属性就是非必需的依赖项。该实践已经成了惯例。

在属性上注入虽然简单直接,但最好不好用。因为会让单元测试更加困难。

@Inject private MurmurMessage murmurMessage;

3 @Qualifier

支持JSR-330(标准注解规范)的框架要用注解 @Qualifier 限定要注入的对象。比如在Ioc容器中有两个类型相同的对象,需要把它们区分开。

创建一个@Qualifier实现必须遵循如下规则:

  • 必须标记为@Qualifier和@Rentetion(RUNTIME),以确保该限定注解在运行时一直有效。

  • 通常还应该击伤@Documented注解,这样该实现就能加入到API的公共javadoc中。

  • 可以有属性。

  • @Target注解可以限定其使用范围:比如将其使用范围限定为属性,而不是限定为属性的默认值和方法中的参数。

给音乐库框架提供限定符@MusicGenre

@Documented
@Rentention(RUNTIME)
public @interface MusicGenre {Genre genre() default Genre TRANCE;public enum GENRE { CLASSICAL, METAL, ROCK, TRANCE }
}
public class MetalRecordAlbums {@Inject @MusicGenre(GENRE.METAL) Genre genre;
}

4 @Named

JSR-330规范中要求所有Ioc容器都要提供一个默认的@Qualifier注解:@Named

@Named 是一个特别的@Qualifier注解,借助@Named可以用名字标明要注入的对象,与@Inject一起使用,符合指定名称并且类型正确的对象会被注入。

public class MurmurMessage {@Inject @Named("murmur") private MurmurMessage murmurMessage;@Inject @Named("broadcast") private MurmurMessage broadcastMesssage;
}

5 @Scope

@Scope 注解用于定义注入器(即IoC容器)对注入对象的重用方式。JSR-330规范中明确了如下几种默认行为:

  • 如果没有声明任何@Scope注解接口的实现,注入器应该创建注入对象并且仅使用该对象一次。

  • 如果声明了@Scope注解接口的实现,那么注入对象的生命周期由所声明的@Scope注解实现决定。

  • 如果注入对象在@Scope实现中要由多个线程使用,则需要保证注入对象的线程安全性。

  • 如果某个类上声明了多个@Scope注解,或声明了不受支持的@Scope注解,IoC容器应该抛出异常

6 @Singleton

@Singleton 注解接口在DI框架中应用广泛,在需要注入一个不会改变的对象时,就要用到@Singleton。

大多数DI框架都将@Singleton作为注入对象的默认生命周期,无需显式声明,框架会认为你向注入一个单例对象。

public MurmurMessage {@Inject @Singleton MessageHeader defaultHeader; // 显式声明为单例对象(切实有效的静态数值)
}

7 Provider接口

想对由DI框架注入代码中的对象拥有更多的控制权,可以要求DI框架将Provider接口实现注入该类,控制对象的好处在于:

  • 可以获取该对象的多个实例

  • 可以延迟获取该对象(延迟加载)

  • 可以打破循环依赖

  • 可以定义作用域,能在比整个被加载的应用小的作用域中查找对象
    该接口仅有一个 T get()方法,返回一个构造好的注入对象(T)

class MurmurMessage {@Inject MurmurMessage(Provider<Message> messageProvider) {Message meg1 = messageProvider.get();if (someGlobalCondition) {// 如果直接注入Message,则无法获取另外一个Message实例Message copyOfMsg1 = messageProvider.get(); // 获取第二个Message对象}}
}

Java7技术系列:DI依赖注入相关推荐

  1. (八)Spring之IOC控制反转、DI依赖注入介绍和使用(详解)

    文章目录 前言 Spring Spring IOC 简介 Bean IOC 概述 IOC 本质理解 Spring IOC 应用 IOC xml装配 IOC 依赖注入 IOC Bean的作用域 IoC ...

  2. 拥抱.NET Core系列:依赖注入(2)

    上一篇"拥抱.NET Core系列:依赖注入(1)大体介绍了服务注册.获取和生命周期,这一篇来做一些补充.由于内容跨度大(.NET Core.ASP.NET Core),所以文章并不是非常的 ...

  3. 什么是IOC(控制反转)、DI(依赖注入)举个形象的例子通俗易懂

    更多免费教学文章请关注这里 学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清 ...

  4. 什么是IOC(控制反转)、DI(依赖注入)

    原文地址(摘要了部分内容):https://blog.csdn.net/qq_22654611/article/details/52606960/ 学习过Spring框架的人一定都会听过Spring的 ...

  5. 详解spring的IOC控制反转和DI依赖注入

    转载 详解spring的IOC控制反转和DI依赖注入 2018-06-05 15:45:34 jiuqijack 阅读数 2945 文章标签: spring IOC控制反转 DI依赖注入 更多 分类专 ...

  6. 三大框架之spring框架+IoC控制反转、DI依赖注入

    三大框架:业务层框架Spring+IoC+DI 往期文章:jsp与cookie.重定向与RESTFul架构支持 下一章节: 持久层框架MyBatis 初识Spring框架 MyBatis 入门http ...

  7. .net程序开发IOC控制反转和DI依赖注入详解

    大部分应用程序都是这样编写的:编译时依赖关系顺着运行时执行的方向流动,从而生成一个直接依赖项关系图. 也就是说,如果类 A 调用类 B 的方法,类 B 调用 C 类的方法,则在编译时,类 A 将取决于 ...

  8. Spring DI依赖注入讲解

    DI:dependency injection 依赖注入 在spring框架负责创建Bean对象时,动态将依赖对象注入到Bean组件. public class UserServiceImpl imp ...

  9. Spring DI(依赖注入)

    DI依赖注入 IoC(Inversion Of Control)控制翻转,Spring反向控制应用程序所需要使用的外部资源 DI(Dependency Injection)依赖注入,应用程序运行依赖的 ...

最新文章

  1. java类的注释模板_IDEA添加Java类注释模版的方法
  2. R语言sink函数保存文件实战
  3. 【建站系列教程】4、还不知道SEO你就OUT了
  4. 16.Hadoop架构再探讨第2部分
  5. 允许java运行不安全或不可信的应用程序
  6. matlab cat函数_如何用Matlab编写贪吃蛇游戏?(持续更新)
  7. Java常见异常处理
  8. 转载 Div+css浏览器兼容实例分析(一)
  9. 技术揭秘:华为云DLI背后的核心计算引擎
  10. 2.12_binary_tree_二叉树的创建和遍历
  11. java远程控制win10,如何在win10系统下远程连接linux服务器?(vnc版)
  12. python : autopep8
  13. MySQL—内连接和外连接区别
  14. 阿里云总监课第四期:阿里褚霸携专家团独家分享弹性计算最佳实践
  15. Guava---Joiner
  16. python微信抢票脚本_春节到了 教你使用python来抢票回家
  17. 尚品汇 09_支付模块
  18. 常用的web服务器软件有哪些
  19. 自学Python3脚本100例(1-10)
  20. 连接数据库时出错 : The server time zone value is unrecognized or represents more than one time z

热门文章

  1. DedeCms织梦 tag标签静态化-教程
  2. 计算机与软件学院在北辰校区的东区还西区,如何坐公交 或 地铁去天津的河北工业大学北辰校区教师公寓-45号楼| Moovit...
  3. 010_StringRedisTemplate
  4. 适合练习英语口语的脱口秀
  5. UltraEdit v21.00
  6. matlab功率谱密度单位,功率谱密度单位是什么?和功率有关系吗?
  7. linux 进程 signal,c/c++ linux 进程间通信系列1,使用signal,kill
  8. 程序员自我修养阅读笔记——动态链接
  9. php扩展名与文件类型对照表
  10. PingCAP 入选 CB Insights 中国「数据链路安全领航者」榜单,保障全球用户存储安全