动态选择依赖关系

时间:2018-08-07 04:28:57

标签: java spring spring-boot design-patterns dependency-injection

如何在没有其他条件的情况下选择依赖项。

假设我有一个接口:

"

有两种服务实现public interface A{ String doSomething(String req); }

A

和:

@Component
public class FirstImpl implements A{

   @override
   String doSomething(String req){
   return "something";
  }
}

现在,我创建一个AdapterService类:

@Component
public class SecondImpl implements A{

 @override
    String doSomething(String req){
    return "something";
  }
}

现在调用实现:

@Component
public class AdapterService{
    @Autowired
    private FirstImpl first;
    @Autowired
    private SecondImpl second;

    public getService(String name){
        if("name".equals("First")){
            return first;
        }else if("name".equals("Second")){
            return second;
        }
    }
}

现在,如果我需要创建另一个实现A的类,则需要在ServiceAdapter类中添加条件。像@Service public class BussinessService{ @Autowired private AdapterService adapterService; void doSomething(String name,String req){ return adapterService.getService(name).doSomething(); } } 一样返回另一个注入的服务。对于每个新服务,需要添加其他条件,然后注入相应的服务。我如何避免这种Adapter类。 Spring从名称中动态选择依赖关系。

2 个答案:

答案 0 :(得分:2)

如果您有权访问applicationContext对象,则可以调用

  

applicationContext.getBean(name)

并完全避免使用ServiceAdapter类。唯一的事情是您需要将那些bean放入容器中。

尝试一下:

@Component
public class AdapterService{
    @Autowired
    private ApplicationContext applicationContext;

    public A getService(String name){
        return applicationContext.getBean(name,A.class);
    }
}

答案 1 :(得分:1)

在这里,java SPI, Service Provider Interface(请参阅here)和尝试使用弹簧锤一样好。

对于接口x.y.z.A,存在使用Java SPI实现类的发现机制。

你可以有几个罐子。

他们有一个文本文件META-INF/services/x.y.z.A,该文件的实现类不在以#开头的行上。

由于您可能不希望在通过名称选择该对象之前实例化该类的对象,因此可以在该类上使用运行时批注,或者在该对象上使用SPI。 工厂AFactory,只需少量的建设费用,即可创建A。

ServiceLoader<Dictionary> loader = ServiceLoader.load(A.class);
Iterator<A> dictionaries = loader.iterator();