你好,我正在尝试研究 Dagger2 中的命名注入(inject)
这是我的 Java 类,但它们似乎都不起作用。 我想要的是基于@Named 注释我希望得到不同的对象。
public interface Server {
public void start();
public void stop();
public String request(String request);
}
public abstract class AbstractServer implements Server {
private boolean started;
@Override
public void start() {
started = true;
}
@Override
public void stop() {
if (!started) {
throw new IllegalStateException("Server was not started");
}
}
}
public class AudioServer extends AbstractServer{
@Override
public String request(String request) {
return "Response from Audio server: " + request;
}
}
public class VideoServer extends AbstractServer {
@Override
public String request(String request) {
return "Response from Video server: " + request;
}
}
@Module
public class ServerModule {
public ServerModule() {
}
@Provides
@Named("audio")
@Singleton
AudioServer provideAudioServer() {
return new AudioServer();
}
@Provides
@Named("video")
@Singleton
VideoServer provideVideoServer() {
return new VideoServer();
}
}
请注意 ServerComponent.java 没有编译
@Singleton
@Component(modules = {ServerModule.class})
public interface ServerComponent {
AudioServer provideAudioServer();
VideoServer provideVideoServer();
void inject(TestInject inject);
}
public class TestInject {
private static final Logger logger = Logger.getLogger(TestInject.class.getSimpleName());
@Inject
@Named("audio")
Server audioServer;
public TestInject() {
// ServerComponent component = DaggerServerComponent.builder()
// .build();
// component.inject(this);
}
public void test() {
String serverResponse = null;
if (audioServer != null) {
serverResponse = audioServer.request("game.mp3");
logger.warning(serverResponse);
} else {
serverResponse = "Failure";
logger.info(serverResponse);
}
}
public static void main(String[] args) {
TestInject inject = new TestInject();
inject.test();
}
}
已编辑 请在 TestInject.java
和 ServerComponent.java
中查看答案
public interface Server {
public void start();
public void stop();
public String request(String request);
}
public abstract class AbstractServer implements Server {
private boolean started;
@Override
public void start() {
started = true;
}
@Override
public void stop() {
if (!started) {
throw new IllegalStateException("Server was not started");
}
}
}
public class AudioServer extends AbstractServer{
@Override
public String request(String request) {
return "Response from Audio server: " + request;
}
}
public class VideoServer extends AbstractServer {
@Override
public String request(String request) {
return "Response from Video server: " + request;
}
}
@Module
public class ServerModule {
public ServerModule() {
}
@Provides
@Named("audio")
@Singleton
AudioServer provideAudioServer() {
return new AudioServer();
}
@Provides
@Named("video")
@Singleton
VideoServer provideVideoServer() {
return new VideoServer();
}
}
请注意 ServerComponent.java 没有编译
@Singleton
@Component(modules = {ServerModule.class})
public interface ServerComponent {
@Named("audio")
Server provideAudioServer();
@Named("video")
Server provideVideoServer();
void inject(TestInject inject);
}
public class TestInject {
private static final Logger logger = Logger.getLogger(TestInject.class.getSimpleName());
@Inject
@Named("audio")
Server audioServer;
@Inject
@Named("video")
Server videoServer;
public TestInject() {
ServerComponent component = DaggerServerComponent.builder()
.build();
component.inject(this);
}
public void testAudioServer() {
String serverResponse = null;
if (audioServer != null) {
serverResponse = audioServer.request("game.mp3");
logger.warning(serverResponse);
} else {
serverResponse = "audio server Failure";
logger.info(serverResponse);
}
}
public void testVideoServer() {
String serverResponse = null;
if (videoServer != null) {
serverResponse = videoServer.request("movie.mp4");
logger.warning(serverResponse);
} else {
serverResponse = "Video server Failure";
logger.info(serverResponse);
}
}
public static void main(String[] args) {
TestInject inject = new TestInject();
inject.testAudioServer();
inject.testVideoServer();
}
}
最佳答案
您的主要问题似乎与您期望在类 TestInject
中有一个名为 audio
的 Server
而您的提供者返回 AudioServer
所以 dagger 不能满足你的依赖。
确实不要忘记注解@Named
是用来区分2个相同类型的对象,换句话说你可以用@Named注解("audio")
不同的提供者,只要它们不返回相同的类型。然后,生成的对象将通过其类型和名称进行标识。
例如,这是解决您问题的一种方法:
TestInject
类:
public class TestInject {
...
public TestInject() {
// Needed to inject your dependencies
ServerComponent component = DaggerServerComponent.builder()
.build();
component.inject(this);
}
...
}
类 ServerComponent
@Singleton
@Component(modules = ServerModule.class)
public interface ServerComponent {
void inject(TestInject inject);
}
类 ServerModule
@Module
public class ServerModule {
@Provides
@Named("audio")
@Singleton
public Server provideAudioServer() {
return new AudioServer();
}
@Provides
@Named("video")
@Singleton
public Server provideVideoServer() {
return new VideoServer();
}
}
即使更新了您的问题,您的模块也应该符合我的建议,否则它不会因为前面描述的相同原因而编译。
关于java - Dagger2 Named(@Named) 多态或不同对象注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40194779/