Spring⼀个接⼝多个实现,如何根据外部条件来实时替换具体实
现类
代码:
<T> Map<String, T> getBeansOfType(Class<T> var1) throws BeansException;
作⽤:
1. 传⼊⼀个接⼝的Class 类型,获取这个class 的所有具体实现,不包括抽象类
2. 还可以将 applicationContext 单独设置⼀个值,写成⼀个⼯具类,结合ApplicationContext 类的其他⽅法,⽐如:
getBean(String var1)
需求:
定义了⼀个接⼝,来对外提供服务,这个接⼝下的⽅法不能随便改变,⽽接⼝有⼀系列实现,且实现还在不断添加,如何在传⼊外部不同的条件下,实现实时更换接⼝的实现类
之前的解决办法:
是在controller 中分别引⼊具体的实现,通过⼀个外部条件在controller 判断使⽤那个实现,
弊端:
1.每次增加新的接⼝,都需要在controller 中在@Autowired ⼀个依赖,都必须修改Controller 类的代码,enum类型如何使用
2.之前最多引⼊的实现类有9个,但是实现还在不断增加,如果继续引⼊更多类,spring 创建这个controller的时间⼤⼤增加,因为引⼊加载太多类,
修改的办法:
通过spring 的ApplicationContext(应⽤上下⽂)的getBeansOfType ⽅法传⼊接⼝类型,⼀次性获取所有实现类
问题:
1怎么获得实时的应⽤上下⽂对象 applicationContext
任何类 实现 ApplicationContextAware 接⼝,实现setApplicationContext ⽅法,就会在启动时,向实现
类的实现⽅法注⼊applicationContext对象
例⼦:
package com.util;
import com.service.TestService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Configurable;
import t.ApplicationContext;
import t.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class TestServiceFactory implements ApplicationContextAware {
private static Map<TypeEnum, TestService> testServiceMap;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String,TestService> map = BeansOfType(TestService.class);
testServiceMap = new HashMap<>();
map.forEach((key,value) -> testServiceMap.Code(),value));
}
public TestService getTestService(TypeEnum typeEnum) {
(typeEnum);
}
}
2. 怎么根据外部条件实现获得对应的实现类?
可以在接⼝中加⼀个getCode⽅法,实现类实现这个⽅法,然后返回⼀个定义的枚举类型,然后将getBeansOfType获得map进⾏转换例⼦:
package com.util;
public enum TypeEnum {
impl1,
impl2
}
接⼝
package com.service;
import com.util.TypeEnum;
import org.springframework.stereotype.Service;
@Service
public interface TestService {
public TypeEnum getCode();
public String test();
}
实现类
import org.springframework.stereotype.Service;
@Service
public class TestServiceImpl1 implements TestService { @Override
public TypeEnum getCode() {
return TypeEnum.impl1;
}
@Override
public String test() {
String();
}
}
package com.service.impl;
import com.service.TestService;
import com.util.TypeEnum;
import t.annotation.Primary; import org.springframework.stereotype.Service;
@Service
public class TestServiceImpl2 implements TestService { @Override
public TypeEnum getCode() {
return TypeEnum.impl2;
}
@Override
public String test() {
String();
}
}
controller类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.service.TestService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
@RequestMapping("test")
public class TestController {
@Autowired
TestServiceFactory testServiceFactory;
private TestService testService;
@ResponseBody
@RequestMapping("test")
public String test(HttpServletRequest request, HttpServletResponse response){ String type = Parameter("type");
testService = getTestService(type);
st();
}
public TestService getTestService(String type) {
TypeEnum typeEnum = null;
if(type.equals("1")) typeEnum = TypeEnum.impl1;
if(type.equals("2")) typeEnum = TypeEnum.impl2;
TestService(typeEnum);
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论