收藏 分享(赏)

依赖注入与JSR-330的参考实现—Guice.docx

上传人:凯文文 文档编号:46577 上传时间:2018-07-31 格式:DOCX 页数:6 大小:25.09KB
下载 相关 举报
依赖注入与JSR-330的参考实现—Guice.docx_第1页
第1页 / 共6页
依赖注入与JSR-330的参考实现—Guice.docx_第2页
第2页 / 共6页
依赖注入与JSR-330的参考实现—Guice.docx_第3页
第3页 / 共6页
依赖注入与JSR-330的参考实现—Guice.docx_第4页
第4页 / 共6页
依赖注入与JSR-330的参考实现—Guice.docx_第5页
第5页 / 共6页
点击查看更多>>
资源描述

1、依赖注入与 JSR-330 的参考实现 Guice2015/05/12 | 分类: 基础技术 | 0 条评论 | 标签: GUICE分享到:1原文出处: wwsun.me依赖注入(控制反转的一种形式),它是 Java 开发主流中一个重要的编程范式(思维方式)。简单的说,使用 DI 技术可以让对象从别处获得依赖项,而不是由它自己来构造。使用DI 有很多好处,它能降低代码之间的耦合度,让代码更易于测试、更易读。 Java DI 的官方标准是 JSR-330,本文我们还会介绍 JSR-330 的参考实现 Guice 3,一个轻量级 的 DI框架。IoC and DI使用 IoC 范式编程时,程序逻辑

2、的流程通常是由一个功能中心来控制的。而使用 IoC,这个“中心控制”的设计原则会被反转过来。调用者的代码处理程序的执行顺序,而程序逻辑则被封装在接受调用的子流程中。通过一个例子来理解 IoC:在 GUI 应用中,GUI 框架负责控制调用事件处理器,而不是应用逻辑。当用户点击了一个动作,比如“向前”,GUI 框架会自动调用 对应的事件处理器,而应用逻辑可以把重点放在处理动作上。程序的控制被反转了,将控制权由应用逻辑转移到了 GUI 框架。IoC 也被称为好莱坞原则 :会有另一段代码拥有最初的控制线程,并且由它来调用你的代码,而不是由你的代码调用它。不要给我们打电话,我们会打给你。 好莱坞原则Io

3、C 有多种不同的实现,包括工厂模式、服务器定位模式,当然还有依赖注入。需要注意的是,DI 并不等于 IoC,DI 只是 IoC 的一种实现方式,IoC 是一种机制。DI 是 IoC 的一种特定形态,是指寻找依赖项的过程不在当前执行代码的直接控制之下。Java 中为 DI 提供的容器有 Guice、Spring、PicoContainer 等。DI 的好处有:松耦合、易测试、强内聚、可重用、更轻盈的代码。Example下面编写代码来解释到底什么是 DI,如何使用 DI。我们首先编写传统的代码,然后使用工厂模式解耦,进而再使用 DI 来改进代码,通过这个过程,你将了解到 DI 的精妙之处。这些改进

4、都基于同一个关键技术,即面向接口编程。假设你想找到所有对 Java 可开发人员比较友善的好莱坞经纪人。首先,我们有了一个AgentFinder 接口,及其两个实现类 SpreadSheetAgentFinder 和WebServiceAgentFinder。AgentFinder 接口如下:123public interface AgentFinder public List findAllAgents();传统方式寻找友善经纪人为了找到经纪人,项目中有个默认的 HollywoodService 类,它会从SpreadSheetAgentFinder 里得到一个经纪人列表,并且过滤出友善的经纪

5、人,最终返回该列表。123456789public class HollywoodService public static List getFriendlyAgents() AgentFinder finder = new SpreadsheetAgentFinder();List agents = finder.findAllAgents();List friendlyAgents = filterAgents(agents,“Java Developers“);return friendlyAgents;10 /filterAgents这是最传统的编码方式,显然,HollywoodSer

6、vice 被 SpreadsheetAgentFinder 这个AgentFinder 的具体实现死死的绑定住了。为了改进这个问题,通常我们会想到一个常用的设计模式 工厂模式。工厂模式可以一定程度上解耦程序,它也是 IoC 的一种实现方式。工厂模式利用工厂模式(其实这里用到的是一个简单工厂)重新编写上面的代码,如下:123456public List getFriendlyAgents(String agentFinderType) AgentFinderFactory factory = AgentFinderFactory.getInstance();AgentFinder finder

7、= factory.getAgentFinder(agentFinderType);List agents = finder.findAllAgents();return filterAgents(agents, “Java Developers“);如你所见,这里不再有具体的实现来黏住你,而是通过注入 agentFinderType 的方式让你选择想要的 AgentFinder。但这里仍然还有问题:1. 代码注入的仅仅是一个引用凭据(agentFinderType),而不是真正实现 AgentFinder的对象2. 方法 getFriendlyAgents 中还有获取其依赖的代码,达不到只关

8、注自身智能的理想状态我们需要通过 DI 来达成这两个目标。手工实现 DI1234public static List getFriendlyAgents(AgentFinder finder)List agents = finder.findAllAgents();return filterAgents(agents,“Java Developers“);上面的代码是一个纯手工打造的 DI 方案,AgentFinder 被直接注入到getFriendlyAgents 方法中。现在这个 getFriendlyAgents 方法干净利落,只专注于纯业务逻辑。但是,这种手工方式的 DI 显然存在问题

9、,如何配置 AgentFinder 具体实现的问题并没有解决,原本 AgentFinderFactory 要做的工作还是要找一个地方去做。解决这个问题的方式是借助 DI 框架,而 DI 框架就是把你的代码打包起来的运行时环境,在你需要的时候注入依赖项。使用 GuiceJava 中 DI 方面的标准规范是 JSR-330,它提供了统一的 DI 通用功能的标准,而且提供了你需要了解的幕后规则及限制。这里不具体介绍 JSR-330,有兴趣的可以查找相关资料阅读。我们重点介绍 JSR-330 的参考实现 Guice,它是一个由 Google 实现的针对 Java 6以上版本的流行的、轻量级的 DI 框

10、架。下面我们使用 Guice 来解决手工方式实现 DI 的不足问题:首先我们需要创建一个定义绑定关系的 AgentFinderModule 模块(配置类)。123456public class AgentFinderModule extends AbstractModuleOverrideprotected void configure() bind(AgentFinder.class).to(WebServiceAgentFinder.class);绑定关系的确立在调用 Guice 的 bind 方法时发生,把要绑定的类(AgentFinder)传给它,然后调用 to 方法指明要注入到哪个实

11、现类。下面我们来 Guice 版本的 HollywoodService:123456789101112131415public class HollywoodServiceGuice private AgentFinder finder = null;Injectpublic HollywoodServiceGuice(AgentFinder finder)this.finder = finder;public List getFriendlyAgents()List agents = finder.findAllAgents();return filterAgents(agents, “Ja

12、va Developers“);/.我们在模块中声明了绑定关系,下面我们就可以让注入器构建对象关系图了。接下来我们看看在独立 Java 程序和 Web 应用程序这两种情况下分别要如何实现:1.构建 Guice 对象关系图 独立 Java 程序1234567public class HollywoodServiceClient public static void main(String args) Injector injector = Guice.createInjector(new AgentFinderModule();HollywoodServiceGuice hollywoodSer

13、viceGuice = injector.getInstance(HollywoodServiceGuice.class);List agents = hollywoodServiceGuice.getFriendlyAgents();2.构建 Guice 对象关系图 Web 应用程序 把 Gucie-servlet.jar 加到 web 应用的类库中,然后再 web.xml 中添加下面的配置项:123456789guiceFiltercom.google.inject.servlet.GuiceFilterguiceFilter/*3.然后是标准动作,扩展 ServletContextLis

14、tener 以便使用 Guice 的ServeltModule:1234567public class MyGuiceServletConfig extends GuiceServletContextListener Overrideprotected Injector getInjector() return Guice.createInjector(new ServletModule();4.最好,将其加入到 web.xml 文件中,以便 servlet 容器在部署应用时触发该类:123com.example.MyGuiceServletConfig经由注入器创建 HollywoodServiceGuice,你得到一个配置完备的类,马上就可以调用其中的 getFriendlyAgents 方法了。关于 JSR-330 和 Guice 的更多用法,请参考其 Github 页面 。References1. https:/ The Well-Grounded Java Developer, chapter 3, Dependency Injection

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 网络技术 > 热门技术

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:文库网官方知乎号:文库网

经营许可证编号: 粤ICP备2021046453号世界地图

文库网官网©版权所有2025营业执照举报