Dynamically choose dependency without if else

北战南征 提交于 2019-12-22 01:31:53

问题


How can i choose dependency without if else condition.

Suppose i have a interface:

public interface A{

String doSomething(String req);
}

there are two service implements A:

@Component
public class FirstImpl implements A{

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

and:

@Component
public class SecondImpl implements A{

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

Now i create a AdapterService class:

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

Now call Implementation:

@Service
public class BusinessService{
    @Autowired
    private AdapterService adapterService;

    void doSomething(String name,String req){
        return adapterService.getService(name).doSomething();
    }
}

Now if i need to create another class which implements A then need to add condition in ServiceAdapter class. Like "Third".equals(name) return another injected service. For every new service there need to add another if else condition and inject corresponding service. How can i avoid this Adapter class. Spring dynamically choose depenedency from name.


回答1:


If you have access to applicationContext object, you can call

applicationContext.getBean(name)

and totally avoid the ServiceAdapter class. Only thing is you need to have those beans in the container.

Try with this:

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

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



回答2:


Here the java SPI, Service Provider Interface, see here, would do just as well, as trying to use the Spring hammer.

For an interface x.y.z.A there is a discovery mechanism of implementing classes using the java SPI.

You can have several jars.

They have a text file META-INF/services/x.y.z.A with implementing class(es) on a line not starting with #.

As you might not want to instantiate a object of the class before it is selected by name you would either use a runtime annotation on the class, or have the SPI on a factory AFactory with minor construction overhead, creating an A.

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


来源:https://stackoverflow.com/questions/51718836/dynamically-choose-dependency-without-if-else

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!