本教程主要详细讲解Guice的构造函数注入. 我们将通过详细的代码以及步骤进行讲解.
技术 | 版本 |
---|---|
Java | 1.8+ |
Guice | 4.2.3 |
mvn archetype:generate -DgroupId=io.edurt.lc.guice -DartifactId=guice-binder-constructor -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>lc-guice</artifactId>
<groupId>io.edurt.lc.guice</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>guice-binder-constructor</artifactId>
<name>Learning Center for Guice Binder(Constructor)</name>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
guice
: guice就是我们核心要使用的依赖
在Guice中我们可以通过将需要的实体信息通过构造函数直接注入到我们需要的任意地方,我们通过列举一个例子来实际说明。
src/main/java
目录下新建io.edurt.lc.guice.GuiceConstructorService类文件,在文件输入以下内容package io.edurt.lc.guice;
import com.google.inject.ImplementedBy;
@ImplementedBy(GuiceConstructorServiceImpl.class)
public interface GuiceConstructorService
{
void print(String source);
}
src/main/java
目录下新建io.edurt.lc.guice.GuiceConstructorServiceImpl类文件,在文件输入以下内容package io.edurt.lc.guice;
public class GuiceConstructorServiceImpl
implements GuiceConstructorService
{
@Override
public void print(String source)
{
System.out.println(String.format("Hello Guice Binder For Constructor, %s", source));
}
}
src/test/java
目录创建io.edurt.lc.guice.TestGuiceConstructor类文件进行定义的服务进行测试,添加以下代码package io.edurt.lc.guice;
import com.google.inject.Guice;
import com.google.inject.Inject;
public class TestGuiceConstructor
{
private GuiceConstructorService service;
@Inject
public TestGuiceConstructor(GuiceConstructorService service)
{
this.service = service;
}
public GuiceConstructorService getService()
{
return service;
}
public static void main(String[] args)
{
TestGuiceConstructor test = Guice.createInjector().getInstance(TestGuiceConstructor.class);
test.getService().print("Test Case 1");
}
}
运行单元测试后,控制台会输出以下信息:
Hello Guice Binder For Constructor, Test Case 1
这个示例很好理解,实际就是说我们将GuiceConstructorService
接口通过@Inject
注入到了TestGuiceConstructor
应用中。当然我们通过@ImplementedBy(GuiceConstructorServiceImpl.class)
实现了类似GuiceConstructorService service = new GuiceConstructorServiceImpl()
的操作,不过每次会生成一个新的实例,如果需要单例模式的话,需要单独操作。
注意:在本次程序中我们并没有通过Module关联到Guice,方便我们快速测试应用等。 我们无法通过非Guice容器进行注入,以下就是一个错误的示例 static也是无法进行注入的
package io.edurt.lc.guice;
import com.google.inject.Inject;
public class TestGuiceConstructorNo
{
@Inject
private GuiceConstructorService service;
public GuiceConstructorService getService()
{
return service;
}
public static void main(String[] args)
{
TestGuiceConstructorNo test = new TestGuiceConstructorNo();
test.getService().print("Test Case 1");
}
}
我们运行上述代码,会提示以下错误信息
Exception in thread "main" java.lang.NullPointerException
at io.edurt.lc.guice.TestGuiceConstructorNo.main(TestGuiceConstructorNo.java:18)
这也就说明我们无法在非Guice容器中进行实例注入
上述实例我们只是注入了一个参数,那我们尝试一下多参数注入。
src/main/java
目录下新建io.edurt.lc.guice.GuiceConstructorTwoService类文件,在文件输入以下内容package io.edurt.lc.guice;
import com.google.inject.ImplementedBy;
@ImplementedBy(GuiceConstructorTwoServiceImpl.class)
public interface GuiceConstructorTwoService
{
void print();
}
src/main/java
目录下新建io.edurt.lc.guice.GuiceConstructorTwoServiceImpl类文件,在文件输入以下内容package io.edurt.lc.guice;
public class GuiceConstructorTwoServiceImpl
implements GuiceConstructorTwoService
{
@Override
public void print()
{
System.out.println(String.format("Hello Guice Binder For Constructor Two"));
}
}
src/test/java
目录创建io.edurt.lc.guice.TestGuiceConstructorMultiple类文件进行定义的服务进行测试,添加以下代码package io.edurt.lc.guice;
import com.google.inject.Guice;
import com.google.inject.Inject;
public class TestGuiceConstructorMultiple
{
private GuiceConstructorService service;
private GuiceConstructorTwoService twoService;
public GuiceConstructorService getService()
{
return service;
}
public void setService(GuiceConstructorService service)
{
this.service = service;
}
public GuiceConstructorTwoService getTwoService()
{
return twoService;
}
public void setTwoService(GuiceConstructorTwoService twoService)
{
this.twoService = twoService;
}
@Inject
public TestGuiceConstructorMultiple(GuiceConstructorService service, GuiceConstructorTwoService twoService)
{
this.service = service;
this.twoService = twoService;
}
public static void main(String[] args)
{
TestGuiceConstructorMultiple multiple = Guice.createInjector().getInstance(TestGuiceConstructorMultiple.class);
multiple.getService().print("One");
multiple.getTwoService().print();
}
}
运行程序后,输出以下结果
Hello Guice Binder For Constructor, One
Hello Guice Binder For Constructor Two
我们使用一个
@Inject
也能实现多个参数的实例注入,当然还支持Set方式注入,只需要在参数的set方法上增加@Inject
注解即可实现,这里我们不多做叙述,可自行实验。
我们说过无法通过static属性直接进行注入使用,方法总是很多的,Guice提供了以下static注入方式.
在src/test/java
目录创建io.edurt.lc.guice.TestGuiceStatic类文件进行定义的服务进行测试,添加以下代码
package io.edurt.lc.guice;
import com.google.inject.Guice;
import com.google.inject.Inject;
public class TestGuiceStatic
{
@Inject
private static GuiceConstructorService service;
public static void main(String[] args)
{
Guice.createInjector(binder -> binder.requestStaticInjection(TestGuiceStatic.class));
TestGuiceStatic.service.print("Static");
}
}
运行程序后,输出以下结果
Hello Guice Binder For Constructor, Static
在代码中我们没有向以上两个示例直接使用Guice
获取实例,而是使用了binder.requestStaticInjection
方式进行了注入,这个是和static属性息息相关的,当我们注入static属性的时候要告知Guice我们具体使用static属性的父类,这样Guice才可以帮我们注入进来。
细心的话会想到我们既然使用binder.requestStaticInjection
方式注入static属性,那么非static属性是不是也可以通过类似的方式注入?
答案是可以的,非static的属性我们需要通过binder.requestInjection(Type);
方式注入,实例如下:
在src/test/java
目录创建io.edurt.lc.guice.TestGuiceNonStatic类文件进行定义的服务进行测试,添加以下代码
package io.edurt.lc.guice;
import com.google.inject.Guice;
import com.google.inject.Inject;
public class TestGuiceNonStatic
{
@Inject
private GuiceConstructorService service;
public static void main(String[] args)
{
TestGuiceNonStatic applicationBinder = new TestGuiceNonStatic();
Guice.createInjector(binder -> binder.requestInjection(applicationBinder));
applicationBinder.service.print("Non Static");
}
}
运行程序后,输出以下结果
Hello Guice Binder For Constructor, Non Static
当然我们还可以通过Guice.createInjector().injectMembers(new Object());
方式注入。
注意我们需要创建一个主类的实例才可以注入,使用TestGuiceNonStatic.class是无法注入的
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有