我对如何在Spring中使用上述场景(依赖注入上下文)感到困惑
class Login {
String username;
String password;
UserAuthService userAuth;
/*
assume getter and setter
methods for above private
properties here
*/
}
UserAuthService是一个具有布尔方法validate(String username,String password);
的接口它由BasicAuthService,LDAPAuthService,MockBasicAuthService,MockLDAPAuthService实现; 另外假设BasicAuthServie有一个属性serverAddress,作为具有认证服务器IP地址的字符串, 与LDAPAuthService相同。
我的问题的背景是依赖注入和Spring,
据我所知,基于beanconfig文件的Spring(的IOC)将注入一个具体的实现 UserAuthService。
1。在beanconfig文件中我们只能配置一个ref say() 场景:假设UI用户有一个下拉列表来选择BasicAuth / LDAPAuth。用户选择了LDAPAuth,如何在春季处理这个案例? 因为我们在beanconfig文件中有硬连线ref =“beanIdBasicAuthService”。有没有办法动态地改变参考?
2。稍微复杂一点(假设IT管理员左右),UI现在提供选择身份验证服务器地址的选项(这是Basic / LDAP Auth服务类中的属性) 再次在beanconfig文件中,我们将硬连线属性。如何在春季动态改变它? (除了显式获取注入的bean并调用setterMethod)
这些情况对我来说有点混乱。有人可以解释一下吗?
答案 0 :(得分:0)
回答这两个问题:改为注入工厂类。 例如。在你的例子中:
class Login {
String username;
String password;
UserAuthServiceFactory userAuthFactory;
/*
assume getter and setter
methods for above private
properties here
*/
}
class UserAuthServiceFactory {
UserAuthService createUserAuth(String type, String remoteHost, ...) {...}
}
答案 1 :(得分:0)
Spring提供了一些白魔法,但你真的需要黑魔法: - )。
更严重的是,你是正确的:Spring只能在bean创建时配置bean,并且只有在创建bean 时才能配置bean。顺便说一下,还有范围的问题:Singleton bean只会被创建一次,同一个对象将在整个应用程序中使用,而使用bean范围时,将从应用程序上下文请求时构造一个新对象。 / p>
但是,一旦你有了bean,就可以自由地使用它并更改Spring初始化的值。
这就是第二个问题的方法:在UI中注入AuthService,只需通过UI更改服务器地址(稍微同步......):将使用新地址从那一刻起。
对于第一个问题,我首先要说在您的Login
类这样的类中注入身份验证服务并不常见。首先,它强制您通过对应用程序上下文的请求创建任何Login
对象,这会不必要地将您的应用程序与Spring类绑定。恕我直言,更好的设计是让一个主认证类注入一个具体的认证对象的容器,并委托实际的认证。这是Spring Security对AuthenticationManager执行的操作,它将实际身份验证委派给AuthenticationProviders。