Spring Boot中一接口多实现

一般常规场景是一接口一个实现实例:

public interface ISayService {
    String say();
}
@Service
public class SayServiceImpl implements ISayService {
    @Override
    public String say() {
        return "帅哥/美女,你们长得真好看";
    }
}

然后直接通过Autowired来获取实例

@Api(value = "Demo", tags = {"Demo"})
@RestController
@RequestMapping("query")
public class DemoController {
    @Autowired
    ISayService sayService;
    @ApiOperation(value = "查询信息", notes = "查询信息")
    @PostMapping("info")
    public ResponseEntity queryInfo() {
        return ResponseEntity.ok(sayService.say());
    }
}

定义@Service标识的方式:

@Service("sayService")
public class SayServiceImpl implements ISayService {
    @Override
    public String say() {
        return "帅哥/美女,你们长得真好看";
    }
}
@Service("girlService")
public class GirlServiceImpl implements ISayService {
    @Override
    public String say() {
        return "美女,你好漂亮啊";
    }
}
@Service("boyService")
public class BoyServiceImpl implements ISayService {
    @Override
    public String say() {
        return "帅哥,你真是超帅";
    }
}

调用:

 @Autowired
    ISayService sayService;
    @Autowired
    ISayService girlService;
    @Autowired
    ISayService boyService;


@Autowired
    @Qualifier("sayService")
    ISayService service1;
    @Autowired
    @Qualifier("girlService")
    ISayService service2;
    @Autowired
    @Qualifier("boyService")
    ISayService service3;

第三种,通过ApplicationContextAware来获取实:

@Component
public class ApplicationContextHandler implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    public static Object getBean(String beanName) {
        return applicationContext.getBean(beanName);
    }
}

直接通过名字去获取实例


@Api(value = "Demo", tags = {"Demo"})
@RestController
@RequestMapping("query")
public class DemoController {
    @ApiOperation(value = "查询信息", notes = "查询信息")
    @PostMapping("info")
    public ResponseEntity queryInfo(String beanName) {
        ISayService sayService=(ISayService) ApplicationContextHandler.getBean(beanName);
        return ResponseEntity.ok(sayService.say());
    }
}

传入不同的值获取不同的返回:

/query/info?beanName=girlService

返回:美女,你好漂亮

/query/info?beanName=boyService

返回:帅哥,你可真帅


上述接口中的方法(getBean)代码:

@Component
public class SpringUtils implements ApplicationContextAware {
    private static ApplicationContext APPLICATION_CONTEXT = null;
    private SpringUtils() {
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (SpringUtils.APPLICATION_CONTEXT == null) {
            SpringUtils.APPLICATION_CONTEXT = applicationContext;
        }
    }
    /**
     * 获取ApplicationContext
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return APPLICATION_CONTEXT;
    }
    /**
     * 通过name获取 Bean.
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }
    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }
    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}


qrcode