今天跟大伙儿聊聊Spring里一个贼有意思的小技巧:怎么动态获取一个接口的所有实现类。想象一下,你手里有一把万能钥匙,能打开所有实现了某个接口的“锁”,岂不快哉?这就是今天要教你们的“独门秘籍”。
什么是接口和实现类?
先来复习一下基础知识,啥叫接口?接口就像一个合同,规定了要做哪些事情,但具体怎么做它不管。实现类就是签了合同的乙方,得按照合同办事,把规定的事情都做好。一个接口可以有很多个实现类,就像一个合同可以被很多公司签署一样。
为什么要动态获取实现类?
假设你写了一个电商网站,有各种各样的支付方式,比如支付宝、微信、银联等等。每种支付方式都可以看作是实现了“支付”接口的不同实现类。现在,你想让用户自由选择支付方式,咋办?总不能写一堆if-else吧?这时候,动态获取实现类就派上用场了!
如何实现动态获取?
秘诀就在ApplicationContextAware
这个接口!它就像一个“情报员”,能获取Spring容器里的所有信息。咱们可以利用它,把所有实现了某个接口的类都收集起来,放到一个Map里,就像给每个“锁”都贴上标签。以后要用哪个实现类,直接根据标签找就行啦!
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import cn.com.baidu.filter.InterfaceService; // 确保导入了正确的包
/**
* 获取接口实现类
*/
@Component
public class InterfaceServiceLocator implements ApplicationContextAware {
private Map<String, InterfaceService> serviceMap = new HashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
serviceMap = applicationContext.getBeansOfType(InterfaceService.class);
}
public Map<String, InterfaceService> getServiceMap() {
return serviceMap;
}
public InterfaceService getService(String beanName) {
return serviceMap.get(beanName);
}
}
代码解释:
@Component
: 把InterfaceServiceLocator
变成Spring管理的Bean。implements ApplicationContextAware
: 让InterfaceServiceLocator
可以获取Spring容器的信息。setApplicationContext
: Spring容器启动时会自动调用这个方法,把ApplicationContext
注入进来。getBeansOfType(InterfaceService.class)
: 这就是核心代码!它能获取所有实现了InterfaceService
接口的Bean,并以Bean的名字为键,Bean对象为值,存到serviceMap
里。getService(String beanName)
: 根据Bean的名字获取对应的实现类。
使用示例
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import cn.com.baidu.filter.InterfaceService;
import cn.com.baidu.filter.InterfaceServiceLocator;
@Component
public class MyService {
@Autowired
private InterfaceServiceLocator locator;
public void doSomething() {
InterfaceService service1 = locator.getService("interfaceServiceImpl1");
if (service1 != null) {
// 使用 service1
}
InterfaceService service2 = locator.getService("interfaceServiceImpl2");
if (service2 != null) {
// 使用 service2
}
}
}
代码解释:
@Autowired
: 自动注入InterfaceServiceLocator
。locator.getService("interfaceServiceImpl1")
: 根据Bean的名字获取InterfaceServiceImpl1
的实例。
温馨提示
Bean的名字默认是类名首字母小写,比如 InterfaceServiceImpl1
的Bean名字就是interfaceServiceImpl1
。当然,你也可以用@Service("myService1")
之类的注解自定义Bean的名字。确保你的实现类都加上了 @Service
或@Component
之类的注解,让Spring能扫描到它们。
总结
今天咱们学习了如何动态获取接口的所有实现类,是不是感觉很神奇?有了这个技巧,以后处理类似场景就方便多啦!再也不用写一堆if-else了,代码也更简洁优雅了。桥哥的秘籍就分享到这里,赶紧去试试吧!