版权声明:本文为CSDN博主「EmineWang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/a718515028/article/details/72457436
问题的提出
在实际工作中,我们经常会遇到一个接口及多个实现类的情况
,并且在不同的条件下会使用不同的实现类。从使用方式上看,有些类似SPI的用法,
但是由于SPI的使用并不是太方便,那么怎么办呢?我们可以借助ApplicationContext的getBeansOfType来实现
我们需要的结果。
首先我们看一下这个方法的签名
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
从上面的代码上我们可以看出来这个方法能返回一个接口的全部实现类(前提是所有实现类都必须由Spring IoC容器管理)。
org.springframework.beans及org.springframework.context这两个包是Spring IoC容器的基础,
其中重要的类有BeanFactory,BeanFactory是IoC容器的核心接口,其职责包括:实例化、定位、配置应用程序中的
对象及建立这些对象间的依赖关系。
ApplicationContext作为BeanFactory的子类,在Bean管理的功能上得到了很大的增强,也更易于与Spring AOP集成使用。
ApplicationContext的一种实际应用方式。
如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。
实例1
背景:请求参数的检验需要各种规则校验,每个规则都是一个类,需要依次遍历执行。
/**
* 参数检验工厂类
*
* 如果Bean实现了ApplicationContextAware接口的话,
* Spring将调用Bean的setApplicationContext()方法,
* 将bean所在应用上下文引用传入进来。
*/
@Component
public class CheckParamFactory implements ApplicationContextAware {
private static Map<CheckParamCode, CheckParam> checkParamBeanMap ;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, CheckParam> map = applicationContext.getBeansOfType(CheckParam.class);
checkParamBeanMap = new HashMap<>();
map.forEach((key, value) -> checkParamBeanMap .put(value.getCode(), value));
}
public static <T extends CheckParam> T getCheckParamBean(CheckParamCode code) {
return (T)checkParamBeanMap.get(code);
}
}
实例2
CheckParam
package com.lhh.myspringboot.interfac;
/**
* 参数检查接口
*/
public interface CheckParam {
CheckParamEnum getCode();
void check();
}
TimeCheck
package com.lhh.myspringboot.interfac;
import org.springframework.stereotype.Component;
/**
* 时间校验
*/
@Component
public class TimeCheck implements CheckParam{
@Override
public CheckParamEnum getCode() {
return CheckParamEnum.TimeCheck;
}
/**
* 时间校验逻辑
*/
@Override
public void check() {
System.out.println("时间校验");
}
}
NoneNullCheck
package com.lhh.myspringboot.interfac;
import org.springframework.stereotype.Component;
@Component
public class NoneNullCheck implements CheckParam {
@Override
public CheckParamEnum getCode() {
return CheckParamEnum.NoneNullCheck;
}
/**
* 参数非空校验逻辑
*/
@Override
public void check() {
System.out.println("参数非空校验逻辑");
}
}
CheckParamEnum
package com.lhh.myspringboot.interfac;
/**
* 参数检查类型枚举
*/
public enum CheckParamEnum {
TimeCheck,
NoneNullCheck
//private String code;
}
CheckParamFactory
package com.lhh.myspringboot.interfac;
import com.alibaba.fastjson.JSON;
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;
/**
* 参数检验工厂类
*/
@Component
public class CheckParamFactory implements ApplicationContextAware {
public static Map<CheckParamEnum, CheckParam> checkParamBeanMap ;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, CheckParam> map = applicationContext.getBeansOfType(CheckParam.class);
System.out.println("map:" + JSON.toJSONString(map));
checkParamBeanMap = new HashMap<>();
map.forEach((key, value) -> checkParamBeanMap.put(value.getCode(), value));
System.out.println("checkParamBeanMap:" + JSON.toJSONString(checkParamBeanMap));
}
public static <T extends CheckParam> T getCheckParamBean(CheckParamEnum code) {
return (T)checkParamBeanMap.get(code);
}
}
CheckParamFactoryTest
package com.lhh.myspringboot.interfac;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Set;
@RunWith(SpringRunner.class)
@SpringBootTest
public class CheckParamFactoryTest {
@Test
public void testCkeck(){
// 单个调用
CheckParam checkParamBean = CheckParamFactory.getCheckParamBean(CheckParamEnum.TimeCheck);
checkParamBean.check();
// 遍历调用
Set<CheckParamEnum> checkParamEnums = CheckParamFactory.checkParamBeanMap.keySet();
checkParamEnums.forEach(i->CheckParamFactory.getCheckParamBean(i).check());
}
}