情景:通过不同的出行方式和数量拿到不同的减碳量
代码从controller开始贴 是为了更贴近真实场景
原始代码
controller:
/**
* 获取减碳量
* @param travelEnum 出行方式
* @param number 出行数量
* @return
*/
@GetMapping("test2")
public String getCarbonEmission2(@RequestParam("travelEnum")TravelEnum travelEnum,
@RequestParam("number") Integer number){
return greenTravelService.getCarbonEmission2(travelEnum,number);
}
枚举类:
TravelEnum:
@Getter
@AllArgsConstructor
public enum TravelEnum {
WALK(1,"步行","walkModeService"),
RIDE(2,"骑行","rideModeService"),
CAR(3,"开车","carModeService");
private int type;
private String message;
private String beanName; //默认注入对象名称 就是类名首字母小写
}
service:
public String getCarbonEmission2(TravelEnum travelEnum, Integer number) {
switch (travelEnum) {
case WALK:
log.info("通过一系列计算得出步行减碳为500g");
return "通过一系列计算得出步行减碳为500g";
case RIDE:
log.info("通过一系列计算得出骑行减碳为350g");
return "通过一系列计算得出骑行减碳为3500g";
case CAR:
log.info("通过一系列计算得出开车减碳为200g");
return "通过一系列计算得出开车减碳为200g";
default:
return null;
}
}
改进:
controller:
/**
* 获取减碳量
* @param travelEnum 出行方式
* @param number 出行数量
* @return
*/
@GetMapping("test1")
public String getCarbonEmission(@RequestParam("travelEnum")TravelEnum travelEnum,
@RequestParam("number") Integer number){
return greenTravelService.getCarbonEmission(travelEnum,number);
}
swevice:
@Autowired
GreenTravelModeFactory greenTravelModeFactory;
public String getCarbonEmission(TravelEnum travelEnum, Integer number) {
//通过工厂拿到具体实现类的service
GreenTravelModeService travelModeService = greenTravelModeFactory.getTravelMode(travelEnum);
//调用具体实现类的方法
return travelModeService.getCarbonEmission(travelEnum, number);
}
其中 GreenTravelModeService 是一个接口:
public interface GreenTravelModeService {
public String getCarbonEmission(TravelEnum travelEnum, Integer number);
}
GreenTravelModeService 有三个实现类,分别代表 三种不同出行方式获得减碳的具体实现逻辑
其中
WalkModeService 实现类:
@Component
@Slf4j
public class WalkModeService implements GreenTravelModeService{
@Override
public String getCarbonEmission(TravelEnum travelEnum, Integer number) {
log.info("通过一系列计算得出步行减碳为500g");
return "通过一系列计算得出步行减碳为500g";
}
}
RideModeService 实现类:
@Component
@Slf4j
public class RideModeService implements GreenTravelModeService{
@Override
public String getCarbonEmission(TravelEnum travelEnum, Integer number) {
log.info("通过一系列计算得出骑行减碳为350g");
return "通过一系列计算得出骑行减碳为3500g";
}
}
CarModeService 实现类:
@Component
@Slf4j
public class CarModeService implements GreenTravelModeService{
@Override
public String getCarbonEmission(TravelEnum travelEnum, Integer number) {
log.info("通过一系列计算得出开车减碳为200g");
return "通过一系列计算得出开车减碳为200g";
}
}
上文中的: GreenTravelModeService travelModeService = greenTravelModeFactory.getTravelMode(travelEnum);
就是通过工厂拿到 真正执行这个 GreenTravelModeService 的实现类,怎末拿? 看下面代码。
GreenTravelModeFactory:
@Component
public class GreenTravelModeFactory {
public GreenTravelModeService getTravelMode(TravelEnum travelEnum){
//通过springContext上下文对象拿到容器中的service
return SpringContextUtil.getBean(travelEnum.getBeanName(),GreenTravelModeService.class);
}
}
通过自定义的 SpringContextUtil 拿到容器中的对象,因为前面三个实现类都已经注入到spring容器中(@Component),且注入的对象名称就是 类名将首字母小写
SpringContextUtil:
@Component
@Slf4j
public class SpringContextUtil implements ApplicationContextAware {
@PostConstruct
private void init(){
System.out.println(applicationContext);
}
private static ApplicationContext applicationContext;
public static<T> T getBean(String name,Class<T> classs){
//通过容器中对象的name以及class类型拿到对象
return applicationContext.getBean(name,classs);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext=applicationContext;
}
}
该类通过实现 ApplicationContextAware 从而拿到 applicationContext 从而 能够到容器中拿到对象,项目启动,
setApplicationContext 该方法就会执行。