文档章节

JSR-330 依赖注入

哈库纳
 哈库纳
发布于 2014/01/17 14:27
字数 1245
阅读 930
收藏 29

    这篇是承接《轻量级 Java 开发框架 设计》系列Blog文的后续文章。本文是最新 《Hasor 开发指南》中依赖注入章节的完整内容,开发指南目前仍然在努力编写中。

概念

    “依赖注入(DI)”有时候也被称为“控制反转(IoC)”本质上它们是同一个概念。具体是指,当某个类调用另外一个类的时候通常需要调用者来创建被调用者。但在控制反转的情况下调用者不在主动创建被调用者,而是改为由容器注入,因此而得名。

    这里的“创建”强调的是调用者的主动性。而依赖注入则不在需要调用者主动创建被调用者。

    举个例子通常情况下调用者(ClassA),会先创建好被调用者(FunBean),然后在调用方法callFoo中调用被调用者(FunBean)的foo方法:

public class ClassA {
    private FunBean funBean = new FunBean();
    public void callFoo() {
        this.funBean.foo();
    }
}
public class FunBean {
    public void foo() {
        System.out.println("say ...");
    }
}

    使用了依赖注入的情况恰恰相反,调用者(ClassA)事先并不知道要创建哪个被调用者(FunBean)。ClassA调用的是被注入进来的FunBean,通常我们会为需要依赖注入的对象留有set方法,在调用callFoo方法之前是需要先将funBean对象通过setFunBean方法设置进来的。例如:

public class ClassA {
    private FunBean funBean = null;
    public void setFunBean(FunBean funBean) {
        this.funBean = funBean;
    }
    public void callFoo() {
        this.funBean.foo();
    }
}
public class FunBean {
……

传统注入方式

    严格意义上来说注入的形式分为两种,它们是“构造方法注入”和“set属性注入”。我们经常听到有第三种注入方式叫“接口注入”。其实它只是“set属性注入”的一种接口表现形式。

  • A.构造方法注入:是指被注入的对象通过构造方法传入,例如下面代码:
public class ClassA {
    private FunBean funBean = null;
    public ClassA(FunBean funBean) {
        this.funBean = funBean;
    }
    public void callFoo() {
        this.funBean.foo();
    }
}
  • B.set属性注入:是指被注入的对象通过其get/set读写属性方法注入进来,例如:
public class ClassA {
    private FunBean funBean = null;
    public void setFunBean(FunBean funBean) {
        this.funBean = funBean;
    }
    public void callFoo() {
        this.funBean.foo();
    }
}
  • C.接口注入:是指通过某个接口的set属性方法来注入,大家可以看到其本质还是set属性注入。只不过调用者(ClassA),需要实现某个注入接口。
public interface IClassA {
    public void setFunBean(FunBean funBean);
}
public class ClassA implements IClassA{
    private FunBean funBean = null;
    public void setFunBean(FunBean funBean) {
        this.funBean = funBean;
    }
    public void callFoo() {
        this.funBean.foo();
    }
}

Guice与JSR-330

    JSR-330相关的API是由“javax.inject.*”软件包提供的一组标准API。通过注解作为其表现形式。Hasor使用Google旗下的开源DI容器Guice作为其JSR-330的标准支持组件。

    Guice是Google开发的一个轻量级,基于Java5(主要运用泛型与注释特性)的依赖注入框架(IoC)。Guice非常小而且快。Guice是类型安全的,它能够对构造函数,属性,方法(包含任意个参数的任意方法,而不仅仅是setter方法)进行注入。

    Guice还具有一些可选的特性比如:自定义scopes,传递依赖,静态属性注入,与Spring集成和AOP联盟方法注入等。对于DI框架来说,性能是很重要的,Guice比Spring快这是主流说法,在Guice的官方网站上您可以看到它宣称比Spring快1000倍!

    Hasor选用Guice是由于它的开发接口十分灵活,比起Spring而言Guice更适合作为一个内嵌DI工具来使用。

    由于Guice是JSR-330标准的实现,这也就使得Hasor也具备了支持JSR-330标准的能力。在下面几个小节会讲解如何使用JSR-330标准将其注入到需要的类上。

    我们先假定有一个被调用者(PojoBean),下面是PojoBean类的源代码:

public class PojoBean {
    private String uuid    = UUID.randomUUID().toString();
    private String name    = "马三";
    private String address = "北京马连洼街道办...";
    public String getUuid() {
        return uuid;
    }
    public void setUuid(String uuid) {
        this.uuid = uuid;
    }
    ……
}

构造方法注入

public class ConstructorInject {
    private PojoBean userBean;
    @javax.inject.Inject/*依赖注入*/
    public ConstructorInject(PojoBean userBean) {
        this.userBean = userBean;
    }
    public String getUserName() {
        return this.userBean.getName();
    }
}

属性方式注入

public class MethodInject {
    private PojoBean userBean;
    @javax.inject.Inject/*依赖注入*/
    public void setUserBean(PojoBean userBean) { 
        this.userBean = userBean;
    }
    public String getUserName() {
        return this.userBean.getName();
    }
}

字段方式注入

    字段注入是DI容器对“set属性注入”的一种改进.这种改进使得被注入的对象不在需要实现一个set方法,DI容器会主动的将要注入的对象赋值到给定的字段上。

public class FieldInject {
    @javax.inject.Inject/*依赖注入*/
    private PojoBean userBean;
    public String getUserName() {
        return this.userBean.getName();
    }
}

单例Bean

    单例,通常是指整个应用程序范围内某个类型对象只有一个。Hasor使用AppContext接口表示一个应用程序,在一个AppContext内Hasor通过下面这样的代码可以保证单例:

@javax.inject.Singleton/*声明单例*/
public class SingletonBean {
    private long time = 0;
    public SingletonBean() {
        time = System.currentTimeMillis();
    }
    public void foo() {
        System.out.println("create at time:" + time);
    }
}

© 著作权归作者所有

哈库纳

哈库纳

粉丝 961
博文 84
码字总数 151810
作品 4
杭州
后端工程师
私信 提问
加载中

评论(10)

WeiPeng2K
WeiPeng2K

引用来自“哈库纳”的评论

引用来自“WeiPeng2K”的评论

引用来自“WeiPeng2K”的评论

引用来自“哈库纳”的评论

引用来自“WeiPeng2K”的评论

Jsr250又是干什么的?依赖注入这个词其实没有控制反转理解的深刻,将创建的权利反转给了容器。

好像没有人提到 JSR250

嗯,但是这货也可以wan

IOC

Java的 JSR 自己也干了不少重复的事情呀。

是的
哈库纳
哈库纳

引用来自“WeiPeng2K”的评论

引用来自“WeiPeng2K”的评论

引用来自“哈库纳”的评论

引用来自“WeiPeng2K”的评论

Jsr250又是干什么的?依赖注入这个词其实没有控制反转理解的深刻,将创建的权利反转给了容器。

好像没有人提到 JSR250

嗯,但是这货也可以wan

IOC

Java的 JSR 自己也干了不少重复的事情呀。
WeiPeng2K
WeiPeng2K

引用来自“WeiPeng2K”的评论

引用来自“哈库纳”的评论

引用来自“WeiPeng2K”的评论

Jsr250又是干什么的?依赖注入这个词其实没有控制反转理解的深刻,将创建的权利反转给了容器。

好像没有人提到 JSR250

嗯,但是这货也可以wan

IOC
WeiPeng2K
WeiPeng2K

引用来自“哈库纳”的评论

引用来自“WeiPeng2K”的评论

Jsr250又是干什么的?依赖注入这个词其实没有控制反转理解的深刻,将创建的权利反转给了容器。

好像没有人提到 JSR250

嗯,但是这货也可以wan
哈库纳
哈库纳

引用来自“WeiPeng2K”的评论

Jsr250又是干什么的?依赖注入这个词其实没有控制反转理解的深刻,将创建的权利反转给了容器。

好像没有人提到 JSR250
WeiPeng2K
WeiPeng2K
Jsr250又是干什么的?依赖注入这个词其实没有控制反转理解的深刻,将创建的权利反转给了容器。
哈库纳
哈库纳

引用来自“hantsy”的评论

JSR 330 用了好几年了,。。JSR 330 是从 JSR 299 中抽出来的,不过让 Java EE 更加混乱。
其中有两个完全画蛇添足的东西。
1. Singleton, JSR 330定义一个,EJB中有一个。
2. Scope JSR330 中定义了,JSR299 是定义一套(从CustomScope中派生出来),JSF 中完全使用自己的一套(JSF 2.2 终于放弃自己的IOC,拥抱 CDI 了)。

目前,Java EE 规范中,EJB,JSF, JAXRS都有自己的 IOC概念, Java EE 7 中大部分标准加强了 CDI 集成,但没有完全代替那些规范自己的一套。

我觉得 Java 的技术体系为了保证向后的兼容性,采用一直打补丁的方式。新标准,新规范。会不断的替换老的标准,但同时老的标准还不会失效造成的这样的一个局面。
hantsy
hantsy
JSR 330 用了好几年了,。。JSR 330 是从 JSR 299 中抽出来的,不过让 Java EE 更加混乱。
其中有两个完全画蛇添足的东西。
1. Singleton, JSR 330定义一个,EJB中有一个。
2. Scope JSR330 中定义了,JSR299 是定义一套(从CustomScope中派生出来),JSF 中完全使用自己的一套(JSF 2.2 终于放弃自己的IOC,拥抱 CDI 了)。

目前,Java EE 规范中,EJB,JSF, JAXRS都有自己的 IOC概念, Java EE 7 中大部分标准加强了 CDI 集成,但没有完全代替那些规范自己的一套。
哈库纳
哈库纳

引用来自“廖凯”的评论

inject 使用注解的方式使用起来还是很方便,在nexus的项目源码中就大量使用这种方式注入。也是用的google的Guice

是的,inject 确实很方便。用了 inject 我感觉最深的就是,配置少了,程序简单了。

对于我来说,使用 inject 可以随便移动类了。
书一
书一
inject 使用注解的方式使用起来还是很方便,在nexus的项目源码中就大量使用这种方式注入。也是用的google的Guice
Using JSR 330 Standard Annotations

7.11 Using JSR 330 Standard Annotations 从spring3.0开始,spring提供对JSR-330标准注解的支持.这些注解同spring注解的扫描方式相同.你只需将在你的类路径里添加相关的jar包. 如果你使用Mav...

流光韶逝
2016/09/26
4
0
控制反转与依赖注入通俗描述

控制反转(IOC): 由框架或其他某些东西来控制需要调用的事件处理器或其他东西,而不是由业务逻辑决定。 举例:spring中的bean,我们在spring项目中配置了datasource后,不需要关注如何调用它...

李矮矮
2016/09/26
13
0
Apache OpenWebBeans 2.0.3 发布

Apache OpenWebBeans团队很荣幸地宣布Apache OpenWebBeans-2.0.3的发布,OpenWebBeans具有模块化结构,并提供从Java SE环境到具有复杂ClassLoader层次结构或OSGi环境的Java EE8服务器集群的依...

周其
2018/01/02
680
5
轻量级 Java/Android 依赖注入--Feather

Feather 是个超轻量级的 Java 和 Android 依赖注入器 (JSR-330)。依赖注入框架通常被认为是“神奇”和“复杂”的,但是 Feather 只有几百行代码,非常的简单,简洁,还非常高效。 <dependenc...

叶秀兰
2015/10/29
297
0
Ding Framework 1.6.0 发布 PHP框架

Ding Framework 1.6.0 发布,该版本增加了MVC pre- 和post-dispatch拦截器,增加了当创建bean时候要对周期依赖的检查,修复了缓存中的bean被容器中的类知道的bug。 Ding 是一个 PHP 框架,提...

晨曦之光
2012/03/26
511
0

没有更多内容

加载失败,请刷新页面

加载更多

FPGA 设备 USB Platform Cable USB

lsusbFuture Technology Devices International, Ltd FT232H Single HS USB-UART/FIFO IC

MtrS
今天
4
0
lua web快速开发指南(6) - Cache、DB介绍

"数据库"与"缓存"的基本概念 数据库与缓存是服务端开发人员的必学知识点. 数据库 "数据库"是一种信息记录、存取的虚拟标记地点的集合统称. 比如现实生活中, 我们经常会用到文件柜、书桌等等数...

水果糖的小铺子
今天
7
0
Oracle分页查询语句的写法

Oracle分页查询语句的写法 Oracle分页查询语句使我们最常用的语句之一,下面就为您介绍的Oracle分页查询语句的用法,Oracle分页查询语句基本上可以按本文给出的格式来进行套用。   Oracle分...

康师傅
昨天
5
0
java并发图谱

1527
昨天
2
0
Mybatis之拦截器Interceptor

使用mybatis时用PageHelper进行分页,用到了PageInterceptor,借此了解下mybatis的interceptor。Mybatis的版本是3.4.6,MybatisHelper的版本是5.1.3。 1、PageInterceptor 先上一段代码,如下...

克虏伯
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部