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 ...
随机推荐
- Linux_安装
总结: 分区-->格式化-->起一个设备文件名(逻辑分区一定从5开始)-->指定挂载点(必须是空的目录名称作为盘幅)
- hive vs hbase
HIVE和HBASE区别 两者分别是什么? Apache Hive是一个构建在Hadoop基础设施之上的数据仓库.通过Hive可以使用HQL语言查询存放在HDFS上的数据.HQL是一种类SQL语言,这 ...
- ATS 自定义日志格式
字段解释 %<chi> 客户端IP %<caun> The username of the authenticated client. A hyphen (-) means t ...
- SSM-1第一章 认识SSM框架和Redis
第一章 认识SSM框架和Redis 1.1 Spring框架 Sring理念 Ioc 控制反转 IOC是一个容器,在Spring中,它会认为一切Java资源都是JavaBean,容器的目标是 ...
- Java SE之Java工作原理
在Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器.这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口.编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后 ...
- MySQL自动设置create_time和update_time
参考表结构 CREATE TABLE `t_baby` ( `baby_id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, ...
- 【Udacity并行计算课程笔记】- Lesson 3 Fundamental GPU Algorithms (Reduce, Scan, Histogram)
本周主要内容如下: 如何分析GPU算法的速度和效率 3个新的基本算法:归约.扫描和直方图(Reduce.Scan.Histogram) 一.评估标准 首先介绍用于评估GPU计算的两个标准: ste ...
- JXL导出Excel(只支持xls版本)——(一)
注意: 导出的后缀是xls可以直接打开,如果导出的后缀是xlsx打开报错,需要手动将名字改为xls才可以打开.也就是JXL不可以导出xlsx的excel. Jar包
- SpringMVC的JSON数据交互(七)-@Response,@RestController,@RequestBody用法
1.@RequestBody (自动将请求的数据封装为对象) 作用: @RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConve ...
- JNI打通java和c
1.JNI简介 The Java Native Interface (JNI) is a programming framework that enables Java code running in ...