guice AssistedInject 主要的场景是解决一个对象的创建同时依赖一个实例访问以及ioc 容器,通用的解决方法
是通过工厂方法,因为比较常见,所以guice 提供了一个扩展,可以解决类似问题,对于需要使用的时候我们
需要基于工厂方法注入
参考实例
- AppDemoInject
需要依赖ioc 容器的bean 以及实例的
package com.dalong;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
public class AppDemoInject {
private UserContext userContext;
private String name;
private String password;
@Inject
public AppDemoInject(@Assisted("name") String name,@Assisted("password") String password, UserContext userContext) {
this.name=name;
this.password=password;
this.userContext=userContext;
}
// 工厂方法
public interface Factory {
// 此处因为类型相同,我们需要明确名称,基于Assisted 指明
AppDemoInject create(@Assisted("name") String name,@Assisted("password") String password);
}
public String info(){
return String.format("%s----------%s--------%s",name,password,userContext.context().get("name"));
}
}
UserContext bean
@ImplementedBy(DefaultUserContext.class)
public interface UserContext {
default Map<String,Object> context() {
Map<String,Object> result = new HashMap<>();
result.put("name","demoapp");
return result;
}
}
- UserLogin 使用AppDemoInject
基于工厂方法注入
public class UserLogin {
private UserContext userContext;
private TokenContext tokenContext;
@Inject
private AppDemoInject.Factory factory;
@Inject
public UserLogin (UserContext userContext, TokenContext tokenContext){
this.tokenContext=tokenContext;
this.userContext=userContext;
}
public void doLogin(String name,String password){
AppDemoInject app = factory.create(name,password);
String result = app.info();
System.out.println(result);
}
}
- 入口测试
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
// 使用AssistedInject 解决
install(new FactoryModuleBuilder().build(AppDemoInject.Factory.class));
}
});
UserLogin userLogin = injector.getInstance(UserLogin.class);
userLogin.doLogin("dalong","demoapp");
说明
以上模式使用场景还是比较多的,比如graylog 开发中,使用了不少此模式,而且从实践上,比较喜欢直接将工厂方法放到bean 中,类似上边的玩法