可选依赖项

有时您正在编写的库可能具有可选的依赖项。 例如“如果apache http客户端在类路径上,请使用它;否则,请使用它。 否则–退回到HttpURLConnection”。

为什么要这么做? 由于各种原因–在分发库时,您可能不想强加较大的依赖范围。 另一方面,更高级的库可能会带来性能上的好处,因此任何需要这些的人都可以包括它。 或者,您可能希望允许轻松插入某些功能的实现,例如json序列化。 您的库不在乎是Jackson,gson还是本机android json序列化–因此您可以使用所有这些库提供实现,然后选择找到依赖项的实现。

实现此目的的一种方法是显式指定/传递要使用的库。 当库/框架的用户实例化其主类时,他们可以传递boolean useApacheClient=true或枚举值JsonSerializer.JACKSON 。 这不是一个坏选择,因为它迫使用户了解他们正在使用的依赖项(并且是事实上的依赖项注入)

spring等使用的另一个选项是动态检查类路径上是否存在依赖项。 例如

private static final boolean apacheClientPresent = isApacheHttpClientPresent();
private static boolean isApacheHttpClientPresent() {try {Class.forName("org.apache.http.client.HttpClient");logger.info("Apache HTTP detected, using it for HTTP communication.);return true;} catch (ClassNotFoundException ex) {logger.info("Apache HTTP client not found, using HttpURLConnection.");return false;}
}

然后,每当您需要发出HTTP请求时(其中ApacheHttpClient和HttpURLConnectionClient是您自己的HttpClient接口的自定义实现):

HttpClient client = null;
if (apacheClientPresent) {client = new ApacheHttpClient();
} else {client = new HttpURLConnectionClient();
}

请注意,使用“ isXPresent”布尔值保护所有可能尝试从依赖项加载类的代码非常重要。 否则,类加载异常可能会发生。 例如在Spring,他们将Jackson依赖项包装在MappingJackson2HttpMessageConverter

if (jackson2Present) {this.messageConverters.add(new MappingJackson2HttpMessageConverter());
}

这样,如果Jackson不存在,则不会实例化该类,也根本不会尝试加载Jackson类。

究竟是偏爱自动检测还是需要显式配置要使用的基本依赖项,这是一个难题。 因为自动检测可能会使您的库用户不了解该机制,并且当他们添加用于其他目的的依赖项时,它可能会被您的库选择,并且行为可能会更改(尽管应该这样做,但始终存在微小的差异) 。 您当然应该记录下来,甚至记录消息(如上所述),但这可能不足以避免(不愉快的)意外情况。 因此,我无法回答何时使用哪种方法,应视具体情况决定。

这种方法也适用于内部依赖项–您的核心模块可能会寻找一个更具体的模块来使用它,否则会回退到默认值。 例如,您使用System.nano()提供了“经过时间”的默认实现,但是使用Android时,您最好依靠SystemClock –因此,您可能希望检测是否存在经过时间的android实现。 这看起来像逻辑耦合,因此在这种情况下,最好还是使用显式方法。

总的来说,这是使用可选依赖项的一种很好的技术,它具有基本的后备功能。 或没有回退的许多可能选项之一。 很高兴知道您可以做到,并将其包含在问题的可能解决方案的“工具包”中。 但是您不应该总是在显式(依赖注入)选项上使用它。

翻译自: https://www.javacodegeeks.com/2015/06/optional-dependencies.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/359523.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

XML-RPC协议学习

XML-RPC调用包括2部分:客户端client(调用线程)、服务器端server(被调用的线程)。服务端是通过特定的URL获得的,调用过程如下: 1.客户端程序使用XML-RPC客户端发出作业请求,指定方法名…

extjs tree 遍历树节点并设置选中

function initTreeChecked(){//获取根节点 var rootnoe Ext.getCmp("id").getRootNode();; setAllNodes(rootnoe); } //遍历所有节点 function setAllNodes(node){ setNodeChecked(node);//设置选中 var nodesnode.childNodes; for(var i0;i<…

Android开发中调用系统窗口的方法

//直接拨号 Intent callIntent new Intent(Intent.ACTION_CALL,Uri.parse("tel:12345678")); startActivity(callIntent); //将电话号码传入拨号程序 Intent dialIntent new Intent(Intent.ACTION_DIAL,Uri.parse("tel:12345678")); startActivity(dial…

navicate导出导入表数据问题

1.导出导入json&#xff0c;如下图&#xff0c;右击表点击导出向导&#xff0c;选择json导出类型&#xff0c;根据提示导出即可。 导入时&#xff0c;右击接收的表&#xff0c;点击导入向导&#xff0c;根据提示即可快速导入&#xff08;注&#xff1a;不同系统之间导出导入易…

spring pojo_使用Spring将POJO公开为JMX MBean

spring pojo这是一个非常不错的教程&#xff0c;介绍了如何通过我们最新的JCG合作伙伴 “ The Holy Java ”博客&#xff08;很酷的名字&#xff09;实现“ 用Spring轻松将POJO作为JMX MBean公开 ”。 &#xff08;注意&#xff1a;对原始帖子进行了少量编辑以提高可读性&#…

android地图实时标记

问题描述我在用百度地图给上边做标注的时候&#xff0c;用了一下主要代码&#xff1a;class MyOverlayItem extends ItemizedOverlay<OverlayItem>{ private ArrayList<OverlayItem> mOverlayList new ArrayList<OverlayItem>();private double mLat1 34.0…

tongweb通过控制台简单设置确认相关常用参数

1.环境版本 jdk&#xff0c;tongweb版本确认是否正确 2.检查tongweb的 license是不是永久版本&#xff0c;试用期版本到期会停止服务。 3 JVM运行编码配置-根据系统需要配置 3.1-Dfile.encodingUTF-8 编码根据系统需要配置 4. tongweb运行内存大小--根据系统需要配置 4.1一般 …

编译原理--LL(1)分析法实验C++

一、实验项目要求 1.实验目的 根据某一文法编制调试LL&#xff08;1&#xff09;分析程序&#xff0c;以便对任意输入的符号串进行分析。本次实验的目的主要是加深对预测分析LL&#xff08;1&#xff09;分析法的理解。 2.实验要求 对下列文法&#xff0c;用LL&#xff08;…

实际中进行GC调整

调优垃圾回收与任何其他性能调优活动没有什么不同。 您需要确保了解当前的情况和期望的结果&#xff0c;而不是因为对应用程序的随机部分进行调整而产生了诱惑。 通常&#xff0c;只需执行以下过程即可&#xff1a; 陈述您的绩效目标 运行测试 测量 与目标比较 进行更改并…

达梦数据库出现卡慢简单分析点

1.检查是否有锁表 查询锁表&#xff1a;select sess_id,sql_text from v$sessions sess,v$lock lck where sess.trx_idlck.trx_id and lck.blocked1; --查询僵死会话 解锁&#xff1a;根据会话ID&#xff0c;停止会话 sp_close_session(sess_id); 2.根据v$sessions,V$L…

对象的属性

首先要理解的是“实例变量”。 我们在__init__方法中并不是创建了实例变量&#xff0c;我们是添加了一个或者多个属性给实际的对象 在__init__内部 self.x 5和外部 f.x 5没有什么不同。 那么类呢&#xff1f; 1 >>> class Bar(object): 2 pass 3 4 >>>…

hibernate.session.get()方法不能获取表中最新数据解决方式样例

1.A a (A)session.get(A.class, id); sess.createSQLQuery("update A set name where id ").executeUpdate(); A a1 (A)session.get(A.class, id);//a1中获取不到修改后的name值 sess.refresh(a1);//刷新a1对象&#xff0c;取出数据库数据 注&#xff1a;hibern…

hibernate 映射_Hibernate映射集合性能问题

hibernate 映射首先&#xff0c;本文的灵感来自于Burt Beckwith在2011年1月27日于SpringOne 2GX上发表的有关高级GORM –性能&#xff0c;自定义和监视的演讲 。 简而言之&#xff0c; Burt Beckwith讨论了使用映射集合和GORM中的Hibernate 2级缓存的潜在性能问题&#xff0c;以…

SEL selector (二)

SEL消息机制工作原理是什么 引用下面文章&#xff1a; 我们在之前有提到,一个类就像一个 C 结构.NSObject 声明了一个成员变量: isa. 由于 NSObject 是所有类的根类,所以所有的对象都会有一个 isa 的成员变量[公共继承].而该 isa 变量指向该对象的类(图3.15)[类在Objective-C中…

Ext grid 根据行号获取行数据

var storeExt.getCmp(grid_id).store;// var storerowstore.getAt(row_num);//行数据 var phonenumberstorerow.get(phonenumber);//列信息 //------------------------------------------------------------------------- var dataExt.getCmp(grid_id).store.data; var d…

mobile cpu上禁用alpha test的相关总结

因为&#xff0c;每家芯片的特性不同&#xff0c;根据向framebuffer写法的不同&#xff0c;分为tile-based的mobile cpu&#xff0c;如ImgTec PowerVR&#xff0c;ARM Mali&#xff0c;一部分老版本Qualcomm Adreno。还有标准的direct&#xff08;immediate&#xff09;的mobil…

学习笔记_jquery(js)遍历页面标签

$(#selectTable tr).each(function(i){ // 遍历 tr $(this).children(td).each(function(j){ // 遍历td var id $(this).context.id; }); }); //---------------------- $("input[namename1]").each(function(){ //遍历name…

简易分享功能(非第三方)

在做一个新项目时&#xff0c;需要一个新浪和微信的分享功能&#xff0c;起初看到这个需求&#xff0c;感觉没有什么&#xff0c;直接使用第三方比较成熟的分享组件就可以的&#xff0c;比如&#xff1a;jiathis、百度分享组件&#xff0c;这些都可以很轻松并且方便的完成所需要…

达梦定时迁移数据

1. 生成迁移源代码 1.1 启动DM迁移工具&#xff08;bin/dts.exe&#xff09; 1.2 右击迁移管理空白处 -> 新建工程 1.3 展开工程 -> 右击迁移&#xff0c;新建迁移 -> 输入迁移名称&#xff0c;确认 1.4 右击迁移名称&#xff0c;打开 -> 输入源数据库连接信息&…

JSP教程–最终指南

编者注&#xff1a; JavaServer Pages&#xff08;JSP&#xff09;技术使您可以轻松创建同时包含静态和动态组件的Web内容。 JSP技术提供了Java Servlet技术的所有动态功能&#xff0c;但提供了一种更自然的方法来创建静态内容。 JSP技术的主要功能包括用于开发JSP页面的语言&…