javax.inject包
javax.inject包
java提出的依赖注入标准,有别于以下传统的对象获取方式
- 构造方法
- 工厂模式
- 服务器定位模式(e.g. JNDI)
开发过程中是会有很多层层依赖的对象的,例如,Stopwatch依赖于TimeSource,为当前对象寻找一个所依赖对象的实例称做解决依赖,若没有实例被找到,则应用执行失败,我们称依赖不满足
当没有依赖注入时,也有很多解决依赖的方法,例如直接调用构造器
class Stopwatch {
final TimeSource timeSource;
Stopwatch() {
timeSource = new AtomicClock(...);
}
void start() {...}
void stop() {...}
}
如果需要更多的灵活性,可以使用工厂方法
class Stopwatch {
final TimeSource timeSource;
Stopwatch() {
timeSource = DefaultTimeSource.getInstance();
}
void start() {...}
void stop() {...}
}
我们必须权衡这两种方式:
- 构造器很简洁,但不灵活
- 工厂方法虽然从一定程度上解耦了调用方和具体实现,但是需要很多模版代码
- Service locators方式虽然实现了更好的耦合,但缺少了编译时的类型检查
而且,这几种方法都限制了单元测试,例如,如果我们使用工厂方法,所有依赖于依赖于工厂类的测试代码都需要模拟出factory,还要记得在用完之后清理掉它
void testStopwatch() {
// 先获取原始的实例
TimeSource original = DefaultTimeSource.getInstance();
// 用mock数据替换原始实例
DefaultTimeSource.setInstance(new MockTimeSource());
try {
Stopwatch sw = new StopWatch();
...
} finally {
// 将原始实例放回去以避免一些风险
DefaultTimeSource.setInstance(original);
}
}
实践经验告诉我们,模拟factor会导致大量的模式化代码,大量的模拟和清理将会很快失控。
依赖注入解决了所有的这些问题
class Stopwatch {
final TimeSource timeSource;
@Inject
Stopwatch(TimeSource timeSource) {
this.timeSource = timeSource;
}
void start() {...};
void stop() {...};
}
构造器进一步的将依赖层层传递,直到满足全部依赖。例如,我们需要构造一个StopwatchWidget实例:
class StopwatchWidget {
@Inject
StopwatchWidget(Stopwatch sw) {...}
}
构造器做了什么
- 找到一个TimeSource
- 利用TimeSource构造Stopwatch
- 利用Stopwatch构造StopwatchWidget
这使我们的代码看起来更加简洁和灵活,并从一定程度上弱化了依赖关系
在测试用例中,我们也可以直接通过像构造器传递模拟数据进行单元测试,再也不需要设置/清理factories了
void testStopwatch() {
Stopwatch sw = new Stopwatch(new MockTimeSource());
}
javax.inject包的更多相关文章
- javax.inject中@Inject、@Named、@Qualifier和@Provider用法
@Inject @Inject支持构造函数.方法和字段注解,也可能使用于静态实例成员.可注解成员可以是任意修饰符(private,package-private,protected,public).注 ...
- 使用javax.script包实现Java设置JS脚本中的变量
下面例子中,我们通过javax.script包ScriptEngine.put()方法设置JS脚本中的变量,JS把所有在线用户输出. package ajava.code.javase; import ...
- Eclipse中servlet显示无法导入javax.servlet包问题的解决方案
项目名-->右键 Property-->选择 JavaBuild Path-->选择 Add External JARs-->选择 把servlet-api.jar的路径输入即 ...
- Servlet之javax.servlet包
链接 : http://blog.sina.com.cn/s/blog_5d4214c70102wnf1.html
- Eclipse - servlet显示无法导入javax.servlet包问题的解决方案
项目名-->右键 Property-->选择 Java Build Path-->选择 Add External JARs-->选择 把servlet-api.jar的路径输入 ...
- Spring自动注入之@Autowired、@Resource、@Inject
相同点: 三者都支持对spring bean的自动注入 不同点: ①Autowired按照类型进行注入( Bean bean = applicationContext.getBean(Bean.cla ...
- Spring 学习——Spring JSR注解——@Resoure、@PostConstruct、@PreDestroy、@Inject、@Named
JSR 定义:JSR是Java Specification Requests的缩写,意思是Java 规范提案.是指向JCP(Java Community Process)提出新增一个标准化技术规范的正 ...
- Spring IOC之基于注解的容器配置
Spring配置中注解比XML更好吗?基于注解的配置的介绍提出的问题是否这种途径比XML更好.简单来说就是视情况而定. 长一点的答案是每一种方法都有自己的长处也不足,而且这个通常取决于开发者决定哪一种 ...
- 【Spring】装配Bean 组件扫描
实现自动装配需要用注解:注解分为 spring规范和java规范 ,java规范需要引入javax.inject 包 ,使用maven,直接引入. 从中可以看到 @Named @Inject属于jav ...
随机推荐
- SQL语句(一)SQL和数据库数据表的创建
SQL的组成 (1) 数据定义语言DDL(Data Definition Language) 用于数据库和数据表的创建.修改和删除等操作 CREATE (create) 创建数据库.数据表 ALTER ...
- jsp/servlet页面跳转丢失样式问题
问题:使用servlet,如何处理在多路径页面跳转中servlet转发页面样式丢失问题?(例如访问 http://localhost/project/listUser.action后转到http:// ...
- C# redis简单的使用
1.项目一:用于在Redis中添加数据 using System; using System.Collections.Generic; using System.Linq; using System. ...
- android 简单的读写联系人
一.读取联系人 (1).从raw_contact表读 contact_id (2).从data表中读取data1 (3).从mimetypes读取mimetype 1.AndroidManifest. ...
- .net 读写xml
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- POJ1287 Networking【最小生成树】
题意: 给出n个节点,再有m条边,这m条边代表从a节点到b节点电缆的长度,现在要你将所有节点都连起来,并且使长度最小 思路: 这是个标准的最小生成树的问题,用prim的时候需要注意的是他有重边,取边最 ...
- Android APP常见的5类内存泄露及解决方法
1.static变量引起的内存泄漏 因为static变量的生命周期是在类加载时开始 类卸载时结束,也就是说static变量是在程序进程死亡时才释放,如果在static变量中 引用了Activity 那 ...
- WPF复制异常问题(OpenClipboard 失败 (异常来自 HRESULT:0x800401D0 (CLIPBRD_E_CANT_OPEN)))
最近在维护WPF系统的时候发现的问题,刚刚开始自己的电脑都不能重现,后面写日志跟踪才发现问题的所在.问题主要是由于:1. 在程序访问剪切板的时候,有其他程序正在占用剪切板,导致自己的程序无法访问, ...
- 【转】Python数据类型之“数字(numerics)”
[转]Python数据类型之“数字(numerics)” 上一节内容说的是“Python基本语法”,本节主要讲下Python中的数据类型. 存储在内存中的数据通常有两个属性: 在内存中的存放位置:这个 ...
- CSS选择器中带点(.)怎么办?
在SharePoint中很多元素的ID都用点(.)来连接的,比如: <li class="ms-cui-group" id="Ribbon.Documents.Ed ...