Drop 简介
Drop 简介
转载请保留作者信息:
作者:88250
时间:2009 年 11 月 30 日 Drop
是一个开源的 JSR-330(Dependency Injection for Java)参考实现,已通过 JSR-330 TCK 测试。该项目旨在构建一个符合 JSR-330 的最小化实现,使得新手能够更快了解 Java 依赖注入实现原理以及了解 Java 依赖注入标准规范。Drop 使用的是 Java 反射来进行依赖注入,没有使用代码生成来实现依赖注入。
-
Drop 简介
1 <ol class="writely-toc-subheading writely-toc-none" style="MARGIN-LEFT:0pt">
-
Drop 注入器配置
1 </li>
-
注入点检查
1 <ol class="writely-toc-subheading writely-toc-none" style="MARGIN-LEFT:0pt">
-
注入点合法性检查
1 </li>
-
注入点依赖满足检查
1 </li>
1 </li>
1 <ol class="writely-toc-subheading writely-toc-none" style="MARGIN-LEFT:0pt">
1 </li>
1 </li>
1 </li>
1 </li>
1 </li>
Drop 注入器配置
Drop 提供两种方式配置组件(Bean):-
Java 注解
1 例如:<br /> 2 3 <br /> 4 5 <span style="FONT-FAMILY:Courier New">@Named("helloSpeaker") </span>
1 <span style="FONT-FAMILY:Courier New">@Hello // 限定器</span>
1 <span style="FONT-FAMILY:Courier New">@SessionScoped // 作用域</span>
1 <span style="FONT-FAMILY:Courier New">public class HelloSpeaker {</span>
1 <span style="FONT-FAMILY:Courier New"> public String say() {</span>
1 <span style="FONT-FAMILY:Courier New"> return "Hello!";</span>
1 <span style="FONT-FAMILY:Courier New"> }</span>
1 <span style="FONT-FAMILY:Courier New">}</span> 2 3 4</li>
-
Builder-style APIs
1 <span style="FONT-FAMILY:Courier New">Configurer.createBean(concreteClass<T>) : Bean<T></span>
1 <span style="FONT-FAMILY:Courier New">Bean.<T>named(stringName) : Bean<T></span>
1 <span style="FONT-FAMILY:Courier New">Bean.<T>scoped(scopeAnnotation) : Bean<T></span>
1 <span style="FONT-FAMILY:Courier New">Bean.<T>qualified(qualifierAnnotation, qualifierAnnotation...) : Bean<T></span> 2 3</li>
1例如:<br />
2
3<br />
4
5final Configurer configurer = injector.getConfigurer();<br />
scoped(new DefaultScopedLiteral()).
qualified(new HelloLiteral());
在 JSR-330 中,Named 也是一种 Qualifier,所以上述例子也可以这样写:
1<span style="FONT-FAMILY:Courier New"> <span style="text-decoration: line-through;">named("helloSpeaker").</span>
qualified
(new NamedLiteral("helloSpeaker"),
new HelloLiteral());
注入点检查
Drop 使用类型安全的依赖解析算法,类型安全指的就是:-
- 不使用文本内容进行组件依赖配置
- 依赖类型 + 限定器 = 类型安全
在所有组件配置完成后,Drop 将对其进行注入点检查。
-
注入点
1 注入点描述了需要进行依赖注入(标注了 @Inject)的元素信息。依赖注入有三个方法:字段注入,构造器注入,方法注入。据此,注入点可以分为两类,字段注入点,参数注入点。 2 </div>
-
需要的类型
1 需要的类型指的是被注入实例的的类型。该信息包含在注入点描述中。 2 </div>
-
需要的限定器
1 需要的限定器指的是注入点中描述的限定器。当注入点同时存在需要的限定器与需要的类型时,依赖注入容器可以进行类型安全的依赖查找与注入。 2 </div>
-
依赖不满足
1 该情况指的是依赖注入容器在进行注入点依赖查找时未从容器中找到满足注入点条件的情况。 2 </div>
-
依赖混淆
1 该情况指的是依赖注入容器在进行注入点依赖查找时从容器中查找到多于一个满足注入点条件的情况。 2 </div>
-
依赖检查
1 依赖检查指的就是检查依赖注入器中的所有注入点是否合法以及是被否满足,发生在容器配置后。如果满足,则注入器可以进行依赖注入,如果不满足,则抛出检查异常。 2</li>
1<br />
注入点合法性检查
一个合法可注入的构造器:1<ol>
1<br />
2
3 一个合法可注入的字段:<br />
4
5<ol>
1<br />
2
3 一个合法可注入的方法:<br />
4
5<ol>
1<br />
2
3 Drop 目前还没有全部实现所有上述条件的检查。<br />
注入点依赖满足检查
JSR-330 规范将 @Named 定义为了一个限定器,并且有一个 String 类型的属性。这样,除了使用类型安全的依赖解析算法,也可以使用命名解析算法。下面,我们通过一个具体的例子来看看如何对注入点进行依赖满足检查。1</div>
-
@Inject private Speaker nightSpeaker1;
1 该字段是可依赖解析的,不存在依赖不满足或依赖混淆情况。注入器可以根据接口 Speaker 查找到其唯一的实现 NightSpeaker。 2</li>
-
@Inject private DarknessSpeaker nightSpeaker2;
1 该字段是可以依赖解析的,不存在依赖不满足或依赖混淆情况。注入器可以根据抽象类 DarknessSpeaker 查找到其唯一的实现 NightSpeaker。 2</li>
-
@Inject private NightSpeaker nightSpeaker3;
1 该字段是可以依赖解析的,不存在依赖不满足或依赖混淆情况。注入器可以根据具体类 DarknessSpeaker 查找到其唯一的实现 NightSpeaker。 2</li>
-
@Inject @Night private Speaker nightSpeaker4;
1 该字段是可以依赖解析的,不存在依赖不满足或依赖混淆情况。注入器可以根据接口 Speaker 与限定器 @Night 查找到其唯一的实现 NightSpeaker。 2</li>
-
@Inject @Named("nightSpeaker") private Speaker nightSpeaker4;
1 该字段是可以依赖解析的,不存在依赖不满足或依赖混淆情况。注入器可以根据接口 Speaker 与限定器 @Named("nightSpeaker") 查找到其唯一的实现 NightSpeaker。 2</li>
-
@Inject @Named("nightSpeaker") @Night private Speaker nightSpeaker4;
1 该字段是可以依赖解析的,不存在依赖不满足或依赖混淆情况。注入器可以根据接口 Speaker 与限定器集 {@Named("nightSpeaker"), @Night} 查找到其唯一的实现 NightSpeaker。 2</li>
现在,我们添加一个 Speaker 实现类:
1<span style="FONT-FAMILY:Courier New">}</span>
1<br />
依赖注入
注入顺序
JSR-330 规定了依赖注入的顺序,如下(忽略了静态成员注入):- 构造器注入
- 父类字段注入
- 父类方法注入
- 子类字段注入
- 子类方法注入
注入实现
算法实现了遵循 JSR-330 的依赖注入顺序: SimpleBean.java:
protected void resolveDependencies(final Object reference)
throws Exception {
final Class<?> superclass = reference.getClass().getSuperclass();
resolveSuperclassFieldDependencies(reference, superclass);
resolveSuperclassMethodDependencies(reference, superclass);
resolveCurrentclassFieldDependencies(reference);
resolveCurrentclassMethodDependencies(reference);
}
具体实现为 Java 类层次递归实现,请参考源码 。
中英术语对照表
英文
|
中文
|
Annotation | 注解 |
Qulifier | 限定器 |
Scope
|
作用域
|
Bean
|
组件
|
Injection Point
|
注入点
|
Required Type
|
需要的类型
|
Required Qualifiers
|
需要的限定器
|
1<br />
2
3<a href="http://docs.google.com/View?id=ddrm6c35_1143hf63xgkq">well-formed</a>
1</div>