Skip to content

Commit 3d69c97

Browse files
committed
Guice依赖注入(构造函数注入)
1 parent 871baf0 commit 3d69c97

16 files changed

+552
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,6 @@ Spring整合学习中心
4444
- [Guice教程](guice/README.md)
4545

4646
- [Guice依赖注入(一)](guice/binder/DOC.md)
47+
- [Guice依赖注入(构造函数注入)](guice/binder-constructor/DOC.md)
4748

4849

guice/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ Guice系列整合教程.
1616
---
1717

1818
- [Guice依赖注入(一)](binder/DOC.md)
19+
- [Guice依赖注入(构造函数注入)](binder-constructor/DOC.md)

guice/binder-constructor/DOC.md

+338
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,338 @@
1+
# Guice依赖注入(构造函数注入)
2+
3+
本教程主要详细讲解Guice的构造函数注入.
4+
5+
#### 基础环境
6+
7+
---
8+
9+
| 技术 | 版本 |
10+
| ----- | ----- |
11+
| Java | 1.8+ |
12+
| Guice | 4.2.3 |
13+
14+
#### 初始化项目
15+
16+
---
17+
18+
- 初始化项目
19+
20+
```bash
21+
mvn archetype:generate -DgroupId=com.edurt.sli.guice -DartifactId=guice-binder-constructor -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false
22+
```
23+
24+
- 修改pom.xml增加Guice依赖
25+
26+
```xml
27+
<?xml version="1.0" encoding="UTF-8"?>
28+
<project xmlns="http://maven.apache.org/POM/4.0.0"
29+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
30+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
31+
32+
<parent>
33+
<artifactId>learn-integration-guice</artifactId>
34+
<groupId>com.edurt.sli.guice</groupId>
35+
<version>1.0.0</version>
36+
</parent>
37+
38+
<modelVersion>4.0.0</modelVersion>
39+
40+
<artifactId>guice-binder-constructor</artifactId>
41+
<name>Guice依赖注入(构造函数注入)</name>
42+
43+
<properties>
44+
<system.java.version>1.8</system.java.version>
45+
<guice.version>4.2.3</guice.version>
46+
<lombok.version>1.18.2</lombok.version>
47+
</properties>
48+
49+
<dependencies>
50+
<dependency>
51+
<groupId>com.google.inject</groupId>
52+
<artifactId>guice</artifactId>
53+
<version>${guice.version}</version>
54+
</dependency>
55+
<dependency>
56+
<groupId>org.projectlombok</groupId>
57+
<artifactId>lombok</artifactId>
58+
<version>${lombok.version}</version>
59+
</dependency>
60+
</dependencies>
61+
62+
<build>
63+
<plugins>
64+
<plugin>
65+
<groupId>org.apache.maven.plugins</groupId>
66+
<artifactId>maven-compiler-plugin</artifactId>
67+
<version>${plugin.maven.compiler.version}</version>
68+
<configuration>
69+
<source>${system.java.version}</source>
70+
<target>${system.java.version}</target>
71+
</configuration>
72+
</plugin>
73+
</plugins>
74+
</build>
75+
76+
</project>
77+
```
78+
79+
`guice`: guice就是我们核心要使用的依赖
80+
81+
#### 构造函数注入
82+
83+
---
84+
85+
在Guice中我们可以通过将需要的实体信息通过构造函数直接注入到我们需要的任意地方,我们通过列举一个例子来实际说明。
86+
87+
- 创建`com.edurt.sli.guice.sample`文件夹,并在该文件夹下创建`Service`接口文件,用于添加我们需要测试的函数
88+
89+
```java
90+
package com.edurt.sli.guice.sample;
91+
92+
import com.google.inject.ImplementedBy;
93+
94+
@ImplementedBy(ServiceImpl.class)
95+
public interface Service {
96+
97+
void print(String source);
98+
99+
}
100+
```
101+
102+
- 创建`Service`接口的实现类`ServiceImpl`,用于实现接口中的方法,代码如下
103+
104+
```java
105+
package com.edurt.sli.guice.sample;
106+
107+
public class ServiceImpl implements Service {
108+
@Override
109+
public void print(String source) {
110+
System.out.println(String.format("Hello Guice, %s", source));
111+
}
112+
113+
}
114+
```
115+
116+
- 创建用于测试注入的应用类`Application`,代码如下
117+
118+
```java
119+
package com.edurt.sli.guice.sample;
120+
121+
import com.google.inject.Guice;
122+
import com.google.inject.Inject;
123+
124+
public class Application {
125+
126+
private Service service;
127+
128+
@Inject
129+
public Application(Service service) {
130+
this.service = service;
131+
}
132+
133+
public Service getService() {
134+
return service;
135+
}
136+
137+
public static void main(String[] args) {
138+
Application application = Guice.createInjector().getInstance(Application.class);
139+
application.service.print("Test");
140+
}
141+
142+
}
143+
```
144+
145+
我们运行程序输出
146+
147+
```bash
148+
Hello Guice, Test
149+
```
150+
151+
这个示例很好理解,实际就是说我们将`Service`接口通过`@Inject`注入到了`Application`应用中。当然我们通过`@ImplementedBy(ServiceImpl.class)`实现了类似`Service service = new ServiceImpl()`的操作,不过每次会生成一个新的实例,如果需要单例模式的话,需要单独操作。
152+
153+
> 注意:在本次程序中我们并没有通过Module关联到Guice,方便我们快速测试应用等。
154+
> 我们无法通过非Guice容器进行注入,以下就是一个错误的示例
155+
> static也是无法进行注入的
156+
157+
```java
158+
package com.edurt.sli.guice.sample;
159+
160+
import com.google.inject.Inject;
161+
162+
public class ApplicationCustom {
163+
164+
@Inject
165+
private Service service;
166+
167+
public Service getService() {
168+
return this.service;
169+
}
170+
171+
public static void main(String[] args) {
172+
ApplicationCustom custom = new ApplicationCustom();
173+
custom.getService().print("Test");
174+
}
175+
176+
}
177+
```
178+
179+
我们运行上述代码,会提示以下错误信息
180+
181+
```java
182+
Exception in thread "main" java.lang.NullPointerException
183+
at com.edurt.sli.guice.sample.ApplicationCustom.main(ApplicationCustom.java:16)
184+
```
185+
186+
这也就说明我们无法在非Guice容器中进行实例注入
187+
188+
#### 多参数注入
189+
190+
---
191+
192+
上述实例我们只是注入了一个参数,那我们尝试一下多参数注入。
193+
194+
- 我们先书写另一个需要注入的服务和实现,`PrintService`代码如下
195+
196+
```java
197+
package com.edurt.sli.guice.sample;
198+
199+
import com.google.inject.ImplementedBy;
200+
201+
@ImplementedBy(PrintServiceImpl.class)
202+
public interface PrintService {
203+
204+
void print();
205+
206+
}
207+
```
208+
209+
- 实现类`ImplementedBy`代码如下
210+
211+
```java
212+
package com.edurt.sli.guice.sample;
213+
214+
public class PrintServiceImpl implements PrintService {
215+
216+
@Override
217+
public void print() {
218+
System.out.println("print Service");
219+
}
220+
221+
}
222+
```
223+
224+
- 该服务我们只提供固定的输出字符串信息`print Service`,接下来我们进行对多参数注入,`ApplicationMultiple`代码如下
225+
226+
```java
227+
package com.edurt.sli.guice.sample;
228+
229+
import com.google.inject.Guice;
230+
import com.google.inject.Inject;
231+
import lombok.Data;
232+
233+
@Data
234+
public class ApplicationMultiple {
235+
236+
private Service service;
237+
private PrintService printService;
238+
239+
@Inject
240+
public ApplicationMultiple(Service service, PrintService printService) {
241+
this.service = service;
242+
this.printService = printService;
243+
}
244+
245+
public static void main(String[] args) {
246+
ApplicationMultiple multiple = Guice.createInjector().getInstance(ApplicationMultiple.class);
247+
multiple.getPrintService().print();
248+
multiple.getService().print("Multiple");
249+
}
250+
251+
}
252+
```
253+
254+
运行程序后,输出以下结果
255+
256+
```java
257+
print Service
258+
Hello Guice, Multiple
259+
```
260+
261+
我们使用一个`@Inject`也能实现多个参数的实例注入,当然还支持Set方式注入,只需要在参数的set方法上增加`@Inject`注解即可实现,这里我们不多做叙述,可自行实验。
262+
263+
#### static静态参数注入
264+
265+
---
266+
267+
我们说过无法注入通过static属性直接进行注入使用,方法总是很多的,Guice提供了以下static注入方式
268+
269+
```java
270+
package com.edurt.sli.guice.sample;
271+
272+
import com.google.inject.Guice;
273+
import com.google.inject.Inject;
274+
275+
public class ApplicationStatic {
276+
277+
@Inject
278+
private static Service service;
279+
280+
public static void main(String[] args) {
281+
Guice.createInjector(binder -> binder.requestStaticInjection(ApplicationStatic.class));
282+
ApplicationStatic.service.print("Static");
283+
}
284+
285+
}
286+
```
287+
288+
在代码中我们没有向以上两个示例直接使用`Guice`获取实例,而是使用了`binder.requestStaticInjection`方式进行了注入,这个是和static属性息息相关的,当我们注入static属性的时候要告知Guice我们具体使用static属性的父类,这样Guice才可以帮我们注入进来。
289+
290+
细心的话会想到我们既然使用`binder.requestStaticInjection`方式注入static属性,那么非static属性是不是也可以通过类似的方式注入?
291+
292+
答案是可以的,非static的属性我们需要通过`binder.requestInjection(Type);`方式注入,实例如下:
293+
294+
```java
295+
package com.edurt.sli.guice.sample;
296+
297+
import com.google.inject.Guice;
298+
import com.google.inject.Inject;
299+
300+
public class ApplicationBinder {
301+
302+
@Inject
303+
private Service service;
304+
305+
public static void main(String[] args) {
306+
ApplicationBinder applicationBinder = new ApplicationBinder();
307+
Guice.createInjector(binder -> binder.requestInjection(applicationBinder));
308+
applicationBinder.service.print("Test");
309+
}
310+
311+
}
312+
```
313+
314+
当然我们还可以通过`Guice.createInjector().injectMembers(new Object());`方式注入。
315+
316+
> 注意我们需要创建一个主类的实例才可以注入,使用ApplicationBinder.class是无法注入的
317+
318+
#### 打包文件部署
319+
320+
---
321+
322+
- 打包数据
323+
324+
```bash
325+
mvn clean package -Dmaven.test.skip=true -X
326+
```
327+
328+
运行打包后的文件即可
329+
330+
```bash
331+
java -jar target/guice-binder-constructor-1.0.0.jar
332+
```
333+
334+
#### 源码地址
335+
336+
---
337+
- [GitHub](https://github.com/qianmoQ/spring-learn-integration/tree/master/guice/guice-binder-constructor)
338+
- [Gitee](https://gitee.com/qianmoQ/spring-learn-integration/tree/master/guice/guice-binder-constructor)

guice/binder-constructor/README.md

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Guice依赖注入(构造函数注入)
2+
3+
---
4+
5+
我们主要讲解一下Guice依赖注入(构造函数注入).
6+
7+
### Technology distribution
8+
9+
---
10+
11+
|技术|版本|
12+
|:---:|---|
13+
|Java|1.8+|
14+
|Guice|4.2.3|
15+
16+
### 贡献者(排名不分先后)
17+
18+
---
19+
20+
- [qianmoQ](https://github.com/qianmoQ)

0 commit comments

Comments
 (0)