Ram*_*oza 11 java dependency-injection inversion-of-control guice
以下是我所面临问题的近似值.
认为我们有一些密码验证器和一些规则.
public interface RuleChecker{
//Checks for a password strenght, returns 10
//for strong or 0 for soft password.
int check(String pass);
}
Run Code Online (Sandbox Code Playgroud)
然后我们有几个实现,我们的服务只接受密码,如果它超过8分.
public class NoCheck implements RuleChecker {
public int check(String pass){return 10;}
}
public class LengthCheck implements RuleChecker{
...
}
public class AlphanumericCheck implements RuleChecker{
...
}
public class AlphaAndLenghtCheckAdapter implements RuleChecker{
...
}
Run Code Online (Sandbox Code Playgroud)
但出于测试目的,我们希望在应用程序中实现一个Web服务,我们可以"管理"这些规则,并选择要拥有的规则.
public class PasswordCheckService{
private RuleChecker checker;
@Inject
public PasswordCheckService(final RuleChecker checker){
this.checker = checker;
}
public boolean checkPassword(String password){
return checker.check(password) > 8;
}
}
Run Code Online (Sandbox Code Playgroud)
那么,Guice中是否有任何方法可以在运行时更改服务的注入?
例:
我们启动了应用程序,默认情况下选择LengthCheck并将其注入应用程序,在我们选择NoCheck复选框和保存选项的网站上存储到数据库中,我可以将Guice配置为自动更改服务之前注入的bean吗?所以从现在开始,将不会检查新密码?
-
至于现在,我已经找到了这些主题
谷歌Guice和运行时不同的注射 但我不知道这种提供者是否适合我的问题.
Guice运行时依赖参数重新注入 这个好问题是说类似的东西,但不是我正在寻找的形式.
guice:命令行的运行时注入/绑定 这是我最接近我的问题,但他只在启动"运行时"时执行,并且不会随时更改它.
有帮助吗?
谢谢!
使用第一条评论的提示我实现了这个POC但仍然不起作用,如果你改变选择另一个按钮,服务bean不会更新. https://bitbucket.org/ramonboza/guicedynamicconfig
为每种字段类型(登录,密码,出生日期...)创建一个提供程序,并提供一个参数以将实现更改为返回。
public class MyModule extends AbstractModule {
public void configure() {
bind(RuleChecker.class).annotatedWith(named("password")).toProvider(PasswordRuleCheckerProvider.class);
bind(RuleChecker.class).annotatedWith(named("login")).toProvider(LoginRuleCheckerProvider.class);
}
}
public static class PasswordRuleCheckerProvider implements Provider<RuleChecker> {
private static CheckType type = CheckType.ALPHANUMERIC;
// static type setter.
public RuleChecker get() {
// it would even be better if you could use singletons here.
switch(type) {
case LENGTH:
return new LengthCheck();
case ALPHANUMERIC:
return new AlphanumericCheck();
case ALPHALENGTH:
return new AlphaAndLenghtCheckAdapter();
case NONE:
default:
return NoCheck();
}
}
}
// Almost same provider for your LoginRuleCheckerProvider. You could do something generic.
Run Code Online (Sandbox Code Playgroud)
在您的管理部分中,您更改“类型”值,因此您的规则也会更改。由于有注释,它可能会影响有限的字段集。例如:PasswordRuleCheckerProvider.setType(CheckType.LENGTH);。仅会影响的字段@Named('password')。
您必须像这样声明您的字段和服务:
public abstract class DynamicService {
protected void updateService() {
// Reinject with the new implementations the members.
App.getInjector().injectMembers(this);
}
}
public class PasswordCheckService extends DynamicService {
@Inject
@Named("password")
private RuleChecker passwordChecker;
public void changePasswordCheckType(CheckType type) {
PasswordRuleCheckerProvider.setType(type);
// Reinject, so you have your new implementation.
updateService();
}
// [...]
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19059 次 |
| 最近记录: |