考虑一个包,许多类都实现了接口Policy
。该政策有一种方法canAccess
。还有100多项政策,例如MenNotAllowedPolicy
,ChiledNotAllowedPolicy
,......都实施了Policy
属性文件描述了哪些策略应用于哪种服务,例如:
BarrowBook=MenNotAllowedPolicy
BarrowMovie=MenNotAllowedPolicy,ChiledNotAllowedPolicy
要使用这些策略,有一个简单的循环,它获取一个人的服务名称,循环属性文件并运行人员的策略。该代码的主要部分是:
public canPersonAccessService(aPerson , aService){
//the listPolicy will be read from property file
for(String policyClassName: listPolicy){
Class<?> clazz = Class.forName("foo.bar.Policies"+ policyClassName);
Policy policy = (policy) clazz.newInstance();
policy.canAccess(aPerson);
}
}
虽然Ii可以通过捕获Policy类来改善,但我想知道是否可以使用Spring更轻松地完成它?我决定使用ClassName
作为键并将class instance
作为值的HashMap,但我该如何创建它?!
这是我的问题的模仿:)
答案 0 :(得分:1)
将名为Policy
的接口定义为所有策略实现的基础接口
interface Policy {
boolean canAccess(User u);
}
为每个策略实现都有一个Spring Bean - 确保在@Component
中命名bean,并确保它与属性文件中使用的名称匹配
@Component("MenNotAllowedPolicy")
public static class MenNotAllowedPolicy implements Policy {
public boolean canAcces(User u) {
...
}
}
使检查策略的类也是一个Spring Bean,并在其中自动安装Spring ApplicationContext
@Component
public static class PolicyChecker {
...
@Autowired
private ApplicationContext appContext;
...
public boolean canPersonAccessService(User person, ....) {
for(String policyName: listPolicy) {
Policy policy = appContext.getBean(policyName, Policy.class);
....
policy.canAccess(person);
....
}
}
}
我们通过其bean名称查找策略,同时还确保bean实现Policy接口,如getBean
方法的第二个参数所示。
希望这有帮助!