简体   繁体   English

春季创建相同接口的bean

[英]Spring creating beans of same interface

Consider a package which many classes all implement an interface Policy . 考虑一个许多类都实现接口Policy The Policy has one method canAccess . 该策略具有一种canAccess方法。 There are 100+ policies like MenNotAllowedPolicy , ChiledNotAllowedPolicy ,... which all implement Policy 有100多个策略,例如MenNotAllowedPolicyChiledNotAllowedPolicy ,...全部都实现了Policy

A property file describe which policies are applied to which service, for example: 属性文件描述了将哪些策略应用于哪些服务,例如:

BarrowBook=MenNotAllowedPolicy
BarrowMovie=MenNotAllowedPolicy,ChiledNotAllowedPolicy

To uses these polices there is a simple loop, which gets a service name an person, loop the property file and run the polices for persons. 要使用这些策略,有一个简单的循环,该循环获得一个人的服务名称,循环属性文件并为人运行策略。 The main part of this code is: 该代码的主要部分是:

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);
  }
}

Although Ii can make better by catching the Policy classes but I wonder if it is possible to do it easier with Spring ?! 尽管通过捕获Policy类可以使Ii变得更好,但是我想知道Spring是否可以使它更容易? I decided a HashMap with ClassName as a key and the class instance as value, but how can I create it ?! 我决定将HashMap以ClassName作为键,并将class instance作为值,但是如何创建它呢?

This a mimic of my problem :) 这是我的问题的模仿:)

Define an interface called Policy as base interface for all policy implementations 为所有策略实现定义一个称为Policy的接口作为基本接口

interface Policy {
    boolean canAccess(User u);
}

Have one Spring Bean for each of the policy implementations - make sure you name the bean in @Component and ensure that it matches the name used in your properties file 每个策略实现都有一个Spring @Component确保在@Component命名该bean,并确保它与属性文件中使用的名称匹配

@Component("MenNotAllowedPolicy")
public static class MenNotAllowedPolicy implements Policy {
    public boolean canAcces(User u) {
      ...
    }
}

Make the class that checks the policies also a Spring Bean, and have Spring ApplicationContext autowired in it 使检查策略的类也成为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);
        ....
      }
    }
}

We look up policy by the its bean name, while also ensuring that bean implements Policy interface as indicated by second parameter of getBean method. 我们通过它的bean名称来查找policy,同时还要确保bean实现getBean方法的第二个参数所指示的Policy接口。

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM