JSR330: DI
JSR330 DI
JSR 330 ,提供了一种可重用的、可维护、可测试的方式来获取Java对象。也称为Dependency Injection 。
DI应该都不陌生,因为它就是Spring core之一。在Spring盛行后,Google也提供了一种DI实现:Guice。因为这两个DI容器的盛行,JSR在2009年时诞生了。随后Spring、Guice也相继支持了该规范。
DI容器,也称为Injector。可以有多种实现方式,可以基于XML、注解、DSL(Domain-specific language),甚至是Java代码。在实现是,可以采用反射、代码生成技术等等,均不受限制。
内容摘要:
javax.inject
下面就说说JSR 330 规范是如何定义的:
Interface Summary |
|
Provider<T> |
Provides instances of T. |
Annotation Types Summary |
|
Inject |
Identifies injectable constructors, methods, and fields. |
Named |
String-based qualifier. |
Qualifier |
Identifies qualifier annotations. |
Scope |
Identifies scope annotations. |
Singleton |
Identifies a type that the injector only instantiates once. |
@Inject
该注解可以在constructor、field、method上使用,也可以在static 的非 final 的field、method上使用。使用该注解标注的constructor、field、method访问修饰符不受限制,可以是private、package、protected、public中任意一种。Injector在进行注入时,要按照constructors、fiedls、methods的顺序进行。
对被标注的constructor的要求:
在满足上述说明的情况下,可以有其他的依赖作为方法的参数,别的要求倒没有什么。
对被标注的field的要求:
1)字段不能是final的。
对被标注的method的要求:
1)方法不能是abstract。
2)可以有其他的依赖作为方法的参数。
如果一个@Inject 的方法A.a,被子类B重写了方法a,但没有指定@Inject,那么就不会注入。
@Qualifier
它是一个元注解,用在标注一个注解的。被@Qualifier标注的注解,称为Qualifier。用于指定采用哪个实例。
譬如说,A类有两个子类A1,A2。B类依赖了A,那么DI容器在为B的实例注入A依赖时到底该注入哪个实例呢?
Class B{ @Inject A a; }
如果使用这个注解,就可以解决该问题了:
定义来个Qualifier注解:
@Qualifier public @interface A_1 { } @Qualifier public @interface A_2 { }
然后对A1、A2两个类分别标注,加以区分:
@A_1 public class A1{ } @A_2 public class A2{ }
如果你希望注入的是A1,那么Class B应该这样调整:
Class B{ @Inject @A_1 A a; }
在JSR 330中,也默认设计了一个基于字符串命名的Qualifier,也就是@Named。
对上述案例,可以改造如下:
@Named(“A1”) Public class A1{ } @Named(“A2”) Public class A2{ } Class B{ @Inject @Named(“A1”) A a; }
也就是说,一个Qualifier可以把一个类定义成一个依赖类(类A1,A2中的使用方式),也可以用在注入时指定注入哪个依赖类的实例(Class B中的使用方式)。
@Named
它就是上面说的,默认的Qualifier。通过上面的例子,可以将其理解为Spring中的:
@Component:用于一个类上,告诉DI容器,这个类由DI容器来创建,并可以作为依赖类去注入到其他类中。
@Qualifier:用于指定使用哪个依赖类的实例。
上述代码在Spring中的写法是:
@Component(“A1”) Class A1{ } @Component(“A2”) Class A2{ } Class B{ @Autowired @Qualifier(“A1”) A a; }
@Scope、@Singleton
@Scope是Scope的元注解。用于声明Scope注解。譬如@Singleton。
Scope注解,用在类上,用于告诉Injector,为该类创建多少个对象。
也默认提供了一个Scope:@Singleton,它用于告诉容器,只为该类创建一个实例。所以当一类类被标注为@Singleton时,要注意线程安全性。
如果一个@Named或者其他自定义的Qualifier标准的类,没有被标注为@Singleton,那么就会创建多个实例。
单实例例子:
// Spring中的写法: @Component(“cxxx”) @Scope(“Singleton”) public class C{ } // 如果用JSR 330就可以写为: @Named(“cxxx”) @Scope(“prototype”) public class C{ }
多实例例子:
// Spring中的写法: @Component(“cxxx”) public class C{ } // 如果用JSR 330就可以写为: @Named(“cxxx”) public class C{ }
Provider
一个Provider用于提供某个类的实例。它就相当于Spring中的ObjectFactory。这是一个接口,不是一个注解,所以可以像其他的类一样使用它,它只有一个get方法。
class Car { @Inject Car(Provider<Seat> seatProvider) { Seat driver = seatProvider.get(); Seat passenger = seatProvider.get(); ... } }
我们也可以用它来解决类循环依赖的问题。
JSR330 vs Spring vs Guice vs HK2
功能说明 |
JSR330 |
Spring |
Guice |
HK2 |
告诉DI容器来管理一个类,并指定名称 |
@Named | Qualifier |
@Component |
||
告诉DI容器创建几个实例 |
@Singleton | 不写 |
@Scope(“Singleton”) | @Scope(“prototype”) |
||
标注constructor、field、method是可住入的 |
@Inject |
@Autowired |
||
告诉DI容器注入哪个依赖 |
@Named | Qualifier |
@Qualifier |
||
自定义如何获取对象 |
Provider |
ObjectFactory |
此外,Spring、Guice、HK2 也已经支持JSR330了,所以你可以根据功能来选择使用JSR330的API。
JSR330: DI的更多相关文章
- Spring使用 --- 基本概念(一):DI,依赖注入
Table of Contents 什么是依赖注入 怎样使用 什么时候使用 好处 本文讲述sprint基本概念之一: DI, 即依赖注入. 什么是依赖注入 说类A依赖于类B,最简单的例子是类A有一个类 ...
- 实战Asp.Net Core:DI生命周期
title: 实战Asp.Net Core:DI生命周期 date: 2018-11-30 21:54:52 --- 1.前言 Asp.Net Core 默认支持 DI(依赖注入) 软件设计模式,那使 ...
- [PLC]ST语言六:DI/EI/FEND/WDT/FOR/NEXT
一:DI/EI/FEND/WDT/FOR/NEXT 说明:简单的顺控指令不做其他说明. 控制要求:无 编程梯形图: 结构化编程ST语言:
- 核心一:DI
1.DI:中文名称:依赖注入 2.英文名称:(Dependency Injection) 3.DI是什么?? 3.1 DI和IoC是一样的 3.2 当一个类(A)中需要依赖另一类(B)对象时,把B赋值 ...
- Spring学习(5):DI的配置
一. 一些概念 应用程序中说的依赖一般指类之间的关系. 泛化:表示类与类之间的继承关系.接口与接口之间的继承关系: 实现:表示类对接口的实现: 依赖:当类与类之间有使用关系时就属于依赖关系,不同于关 ...
- spring in action学习笔记一:DI(Dependency Injection)依赖注入之CI(Constructor Injection)构造器注入
一:这里先说一下DI(Dependency Injection)依赖注入有种表现形式:一种是CI(Constructor Injection)构造方法注入,另一种是SI(Set Injection) ...
- Spring:DI依赖注入的几种方式
据我所学,spring实现依赖注入(DI)的方式分为三大类:基于构造器(构造方法)的依赖注入.基于setter的依赖注入.其他方式(c命名空间.p命名空间等).其中推荐使用setter方法注入,这种注 ...
- Spring总结三:DI(依赖注入)
简介: 所谓的依赖注入,其实是当一个bean实例引用到了另外一个bean实例时spring容器帮助我们创建依赖bean实例并注入(传递)到另一个bean中,比如你使用Spring容器创建的对象A里面需 ...
- 任务20:DI初始化的源码解读 & 任务21:依赖注入的使用
20 我们来看一下asp.net core中依赖注入的源码 https://github.com/aspnet/AspNetCore/tree/master/src/Hosting 任务21:依赖注入 ...
随机推荐
- Raspberry树莓派学习笔记2—配置RobotFramework自动化测试环境
一般RobotFramework都是安装在Windows/Linux的PC机上,这里将简单介绍在树莓派硬件平台上配置RobotFramework的开发和运行环境. 树莓派上配置了自动化测试软件,可以考 ...
- 在vi或者vim中显示行号
1. 为了显示行号,在vi/vim编辑器中执行一下命令中的一条 :set number 或者 :set nu 2. 为了关闭行号,在vi/vim编辑器中执行下面命令 :set nu! 如果你想要每次启 ...
- [HBase] - Hbase调优1
版本:HBase-0.98.6-cdh5.3.6 HBase参数调优 1. zookeeper.session.timeout: 默认90000(毫秒), 控制连接zk的timeout时间.由于hba ...
- 微信小程序 网络请求之re.request 和那些坑
微信小程序有四种网络请求类型,下面只详细介绍普通HTTPS请求(wx.request) 普通HTTPS请求(wx.request) 上传文件(wx.uploadFile) 下载文件(wx.downlo ...
- LNMP系统服务搭建过程详解
和LAMP不同的是LNMP中的N指的是Nginx(类似于Apache的一种web服务软件)其他都一样.目前这种环境应用的也是非常之多.Nginx设计的初衷是提供一种快速高效多并发的web服务软件.在静 ...
- JavaScript内置对象-Object
▓▓▓▓▓▓ 大致介绍 JavaScript的简单数据类型包括:Undefined.Null.Boolean.Number.String.JavaScript中这五种基本数据类型不是对象,其他所有值都 ...
- Ant 警告:sun.misc.BASE64Decoder 是 Sun 的专用 API,可能会在未来版本中删除
如果你用Ant编译项目,而且在项目中用了SUN的专用API,你会得到警告信息,然后Ant会报告编译失败: 这当然是不合理的,javac只是警告而已,ant凭什么就直接报失败呢? 其实最好的解决办法是避 ...
- Spring IoC介绍与Bean的使用
1. 介绍 IoC IoC-Inversion of Control,即"控制反转",它不是什么技术,而是一种设计思想.在 Java 开发中, IoC意味着将设计好的对象交给容 ...
- rpm的用法
rpm是由红帽公司开发的软件包管理方式,使用rpm我们可以方便的进行软件的安装.查询.卸载.升级等工作.但是rpm软件包之间的依赖性问题往往会很繁琐,尤其是软件由多个rpm包组成时. yum基於RPM ...
- MySQL调优三步曲(慢查询、explain profile)
在做性能测试中经常会遇到一些sql的问题,其实做性能测试这几年遇到问题最多还是数据库这块,要么就是IO高要么就是cpu高,所以对数据的优化在性能测试过程中占据着很重要的地方,下面我就介绍一些msyql ...