Spring学习资料之 依赖注入(二)
1.2 属性注入(Field Inject)
1.2.1 基本属性注入
首先来看一个例子。Service.java
1 @ImplementedBy(ServiceImpl.class)
2 public interface Service {
3 void execute();
4 }
ServiceImpl.java
1 public class ServiceImpl implements Service {
2 @Override
3 public void execute() {
4 System.out.println("This is made by Teny (www.teny32.blog.51cto.com).");
5 }
6 }
FieldInjectDemo.java1 /** a demo with Field inject2 * @author Teny (www.teny32.blog.51cto.com)3 * @version $Rev: 71 $4 */5 public class FieldInjectDemo {6 @Inject7 private Service servcie;8 public Service getServcie() {9 return servcie;
10 }
11 public static void main(String[] args) {
12 FieldInjectDemo demo = Guice.createInjector().getInstance(FieldInjectDemo.class);
13 demo.getServcie().execute();
14 }
15 }
这个例子比较简单。具体来说就是将接口Service通过@Inject注解注入到FieldInjectDemo类中,然后再FieldInjectDemo类中使用此服务而已。当然Service服务已经通过@ImplementedBy注解关联到ServiceImpl 类中,每次生成一个新的实例(非单例)。注意,这里FieldInjectDemo类没有通过Module等关联到Guice中,具体可以查看《》。
意料之中得到了我们期待的结果。
同样,我们通过问答的方式来加深理解(注意,入门教程我们只是强调怎么使用,至于原理和底层的思想我们放到高级教程中再谈)。
问题(1):可以自己构造FieldInjectDemo 对象而不通过Guice么?
1 /** field inject demo22 * @author xylz (www.imxylz.cn)3 * @version $Rev: 73 $4 */5 public class FieldInjectDemo2 {6 @Inject7 private Service servcie;8 public Service getServcie() {9 return servcie;
10 }
11 public static void main(String[] args) {
12 FieldInjectDemo2 fd = new FieldInjectDemo2();
13 fd.getServcie().execute();
14 }
15 }
就像上面的例子中一样,然后运行下看看?非常不幸,我们得到了一个谁都不喜欢的结果。
Exception in thread "main" java.lang.NullPointerException
at cn.imxylz.study.guice.inject.FieldInjectDemo2.main(FieldInjectDemo2.java:22)
很显然,由于FieldInjectDemo2不属于Guice容器(暂且称为容器吧)托管,这样Service服务没有机会被注入到FieldInjectDemo2类中。
问题(2):可以注入静态属性么?
看下面的代码。
1 public class FieldInjectDemo2 {2 @Inject3 private static Service servcie;4 public static Service getServcie() {5 return servcie;6 }7 public static void main(String[] args) {8 FieldInjectDemo2 fd = Guice.createInjector().getInstance(FieldInjectDemo2.class);9 FieldInjectDemo2.getServcie().execute();
10 }
11 }
很不幸!运行结果告诉我们Guice看起来还不支持静态字段注入。
好了,上面两个问题我们暂且放下,我们继续学习其它注入功能。
1.2.2 构造函数注入(Constructor Inject)
继续看例子。例子是说明问题的很好方式。
1 /**2 * $Id: ConstructorInjectDemo.java 75 2009-12-23 14:22:35Z xylz $3 * xylz study project (www.imxylz.cn)4 */5 package cn.imxylz.study.guice.inject;67 import com.google.inject.Guice;8 import com.google.inject.Inject;9
10 /** a demo with constructor inject
11 * @author xylz (www.imxylz.cn)
12 * @version $Rev: 75 $
13 */
14 public class ConstructorInjectDemo {
15
16 private Service service;
17 @Inject
18 public ConstructorInjectDemo(Service service) {
19 this.service=service;
20 }
21 public Service getService() {
22 return service;
23 }
24 public static void main(String[] args) {
25 ConstructorInjectDemo cid = Guice.createInjector().getInstance(ConstructorInjectDemo.class);
26 cid.getService().execute();
27 }
28
29 }
30
31
我们在构造函数上添加@Inject来达到自动注入的目的。构造函数注入的好处是可以保证只有一个地方来完成属性注入,这样可以确保在构造函数中完成一些初始化工作(尽管不推荐这么做)。当然构造函数注入的缺点是类的实例化与参数绑定了,限制了实例化类的方式。
问题(3):构造函数中可以自动注入多个参数么?
1 public class ConstructorInjectDemo {23 private Service service;4 private HelloWorld helloWorld;5 @Inject6 public ConstructorInjectDemo(Service service,HelloWorld helloWorld) {7 this.service=service;8 this.helloWorld=helloWorld;9 }
10 public Service getService() {
11 return service;
12 }
13 public HelloWorld getHelloWorld() {
14 return helloWorld;
15 }
16 public static void main(String[] args) {
17 ConstructorInjectDemo cid = Guice.createInjector().getInstance(ConstructorInjectDemo.class);
18 cid.getService().execute();
19 System.out.println(cid.getHelloWorld().sayHello());
20 }
21 }
22
23
非常完美的支持了多参数构造函数注入。当然了没有必要写多个@Inject,而且写了的话不能通过编译。
1.2.3 Setter注入(Setter Method Inject)
有了上面的基础我们再来看Setter注入就非常简单了,只不过在setter方法上增加一个@Inject注解而已。
1 public class SetterInjectDemo {23 private Service service;45 @Inject6 public void setService(Service service) {7 this.service = service;8 }9
10 public Service getService() {
11 return service;
12 }
13
14 public static void main(String[] args) {
15 SetterInjectDemo sid = Guice.createInjector().getInstance(SetterInjectDemo.class);
16 sid.getService().execute();
17 }
18
19 }
20
21
好了我们再回头看问题2的静态注入(static inject)。下面的例子演示了如何注入一个静态的字段。
1 /** a demo for static field inject2 * @author Teny (www.teny32.blog.51cto.com)3 * @version $Rev: 78 $4 */5 public class StaticFieldInjectDemo {67 @Inject8 private static Service service;9
10 public static void main(String[] args) {
11 Guice.createInjector(new Module() {
12 @Override
13 public void configure(Binder binder) {
14 binder.requestStaticInjection(StaticFieldInjectDemo.class);
15 }
16 });
17 StaticFieldInjectDemo.service.execute();
18 }
19 }
20
21
非常棒!上面我们并没有使用Guice获取一个StaticFieldInjectDemo实例(废话),实际上static字段(属性)是类相关的,因此我们需要请求静态注入服务。但是一个好处是在外面看起来我们的服务没有Guice绑定,甚至client不知道(或者不关心)服务的注入过程。
再回到问题(1),参考上面静态注入的过程,我们可以使用下面的方式来注入实例变量的属性。
1 public class InstanceFieldInjectDemo {23 @Inject4 private Service service;5 public static void main(String[] args) {6 final InstanceFieldInjectDemo ifid = new InstanceFieldInjectDemo();7 Guice.createInjector(new Module() {8 @Override9 public void configure(Binder binder) {
10 binder.requestInjection(ifid);
11 }
12 });
13 ifid.service.execute();
14 }
15 }
16
17
实际上这里有一种简便的方法来注入字段,实际上此方法也支持Setter注入。
1 public class InstanceFieldInjectDemo {23 @Inject4 private Service service;5 public static void main(String[] args) {6 InstanceFieldInjectDemo ifid = new InstanceFieldInjectDemo();7 Guice.createInjector().injectMembers(ifid);8 ifid.service.execute();9 }
10 }
11
12
转载于:https://blog.51cto.com/teny32/1353217
Spring学习资料之 依赖注入(二)相关推荐
- Spring学习4之依赖注入(DI)
前言 上节学习了IOC创建对象的方式,我们在不知不觉中使用了最简单的构造注入,什么是构造注入,什么又是依赖注入呢? 一.首先我们要了解DI是什么? 创建对象的过程中Spring可以依据配置对象的属性进 ...
- spring学习笔记03-spring-DI-依赖注入详解(通过xml配置文件来配置依赖注入)
spring学习笔记03-spring-DI-依赖注入详解 1.概念 2.构造函数注入 3.set方法注入 4.集合的注入 需要被注入的实体对象 package com.itheima.service ...
- Spring(二)--------Spring配置、DI依赖注入、Bean自动装配
Spring(二)--------Spring配置.DI依赖注入.Bean自动装配 5.Spring配置 5.1 别名 设置别名:第一种方式alias <!--其中name为ID的对应值--&g ...
- 一步一步手绘Spring DI运行时序图(Spring 自动装配之依赖注入)
相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...
- Spring 的控制反转/依赖注入
第一章 Spring 的控制反转/依赖注入 回顾 增删改查. 课前测: 本章内容 spring:春天 IOC:将创建对象的权力交给 spring 核心容器去控制.工厂模式 BeanFactory: 懒 ...
- SpringMVC:学习笔记(11)——依赖注入与@Autowired
SpringMVC:学习笔记(11)--依赖注入与@Autowired 使用@Autowired 从Spring2.5开始,它引入了一种全新的依赖注入方式,即通过@Autowired注解.这个注解允许 ...
- 零配置 之 Spring 注解实现Bean依赖注入
转载自 [第十二章]零配置 之 12.2 注解实现Bean依赖注入 --跟我学spring3 12.2 注解实现Bean依赖注入 12.2.1 概述 注解实现Bean配置主要用来进行如依赖注入. ...
- Spring IOC容器的依赖注入流程(收集和注册、分析和组装)
Spring IOC容器的依赖注入流程 Spring IOC容器的依赖注入工作可以分为两个阶段: 阶段一:收集和注册 第一个阶段可以认为是构建和收集bean定义的阶段,在这个阶段中,我们可以通过XML ...
- Spring受管Bean依赖注入(设值注入)
设值注入是Spring支持的多种依赖注入类型中的一种,也是最为常见的一种.设值(setter)注入指在通过调用无参构造器(或无参静态工厂方法,或工厂Bean的蜚静态工厂方法)实例化受管Bean后调用s ...
最新文章
- es父子结构查询_ES 父子文档查询
- 设计模式在工作中的实践
- java集合类深入分析之TreeMap/TreeSet篇
- windows下qt5 kinect 2.0开发与环境配置
- 两两交换链表中的节点Python解法
- IOS之学习笔记四(类的实现和对象和id)
- 世界上最难的视觉图_世界上最长的蛇有多长?四川惊现55米洪荒巨蟒(图)
- 职业梦想是计算机的英语作文,理想职业英语作文2篇
- begin backup导致的故障恢复全过程
- 手写深浅拷贝(js)
- linux环境下编译llvm源码
- BZOJ 4766: 文艺计算姬 [矩阵树定理 快速乘]
- 什么导致了android.os.NetworkOnMainThreadException异常
- 超好用的录屏软件 captura
- 西门子安装未找到ssf文件_西门子Step7 V5.5 中文版+Sp1 安装教程
- 4152: [AMPPZ2014]The Captain
- html 设置不同字体,在html中怎么设置一行字两个不同样式的字体
- gradle 设备未就绪。解决方法
- 关于majaro安装后的配置,简单记录 机型华硕FZ53v
- 第一次作业:阅读与准备工作
热门文章
- gridstack 宽度改变_Model Y在Model 3有哪些改变?
- 【图像分类】基于Pascal VOC2012增强数据的多标签图像分类实战
- 全球及中国虚拟厨房(仅限外卖的餐厅)行业运营模式分析及发展规划建议研究报告2021-2027年版
- 全球与中国重型离合器市场运营状况分析与“十四五”发展规划建议2021年版
- python数据分析入门学习笔记儿
- 回顾2011年最热门的开源PHP项目
- vue移动端过渡动画_Vue.js实现微信过渡动画左右切换效果
- 智慧赋能黔货出山 丰收节交易会·李喜贵:贵州农业数字化
- 创建性设计模式之2--建造者模式
- Spring学习总结(一)——Spring实现IoC的多种方式