一个接口有多个实现类,我们在调用时,该怎么获取?
1,工厂类
一般常见思路,我们在工厂类中,根据传入的标志,返回对应的实现类。
缺点:有if else判定语句。
public interface A {
}
public class A1 implements A {
}
public class A2 implements A {
}
public class AFactory {
public A getService(String className) {
if (className.eqauls("XXXX")){
SpringUtils.getBean(A1.class);
} else if ......
}
}
2,静态块中构造Map存放
我们优化的思路是去掉if else判定。我们想到用map存放每个实现类
public interface A {
}
public class A1 implements A {
}
public class A2 implements A {
}
public class ABuilder {
private Map<String, A> SERVICES = new HashMap<>();
static {
SERVICES.put("a1", SpringUtils.getBean(A1.class));
SERVICES.put("a2", SpringUtils.getBean(A2.class));
}
public static A getService(String className) {
A a = SERVICES.get(className);
if (null == a ){
throw new RuntimeException("Invalid key:"+className);
}
return a;
}
}
3,Map存放优化
上面的方法,我们已经可以去掉大量的if else的判断比较了。
但是,还是存在一个缺点,我们编写的实现类后,需要在工具类的静态块中,把这个映射关系写进去。
那,有没有一种可能性。我们不用写这个呢。
还真的就有,请看下面的实现
public interface A {
String getName();
}
public class A1 implements A {
@Override
public String getName() {
return "A1";
}
}
public class A2 implements A {
@Override
public String getName() {
return "A2";
}
}
@Service
public class TestUtil {
@Autowired
Map<String, TestInterface> userMap;
public TestInterface getTestService(String type) {
return userMap.get(type);
}
}
public class Test {
@Autowired
private TestUtil testUtil;
@Test
public void getService() {
String className = "A1";
A a = testUtil.getTestService(className);
System.out.println(a.getName());
}
}
上面的实现,是spring帮我我们把接口对应的所有的实现类放到了这个map中。省掉我们开发
key默认是className
4,底层实现
以上其实,都是spring容器,底层提供的方法。
ApplicationContext.getBean(Class class);
ApplicationContext.getBeanOfType(String name, Class<T> clazz);
大家有觉得方便多了么?