使用Springboot根据配置文件动态注入接口实现类

Springboot根据配置文件动态注入接口实现类

需求

最近在做一个Springboot项目,需要面向不同需求的客户,但是为了方便管理分支,需要将不同客户的需求都写到同一套代码中,根据不同客户实例化对应的实现类。

实现

为了尽量不修改代码,少做不必要的逻辑判断,我们考虑为不同客户写不同的Service,然后根据配置参数实例化对应的Service。这样就遇到了需要根据配置文件实现不同类的需求。

针对这一需求大致有两种实现方式。但是针对我的需求,能用的只有第二种,但还是想将第一种一起总结一下。

两种方式都需要给定义接口,并针对不同客户对接口做不同实现。

接口类

public interface IAService {

    //获取客户名,所有客户都需要,但是需要针对不同客户做不同实现
    String getCustomName();
}

针对客户A和B对上面接口实现两个类

//注意要给Service命名
@Service("customA")
public class IAServiceShijiazhuangImpl implements IAService{
   //A客户的逻辑
    @Override
    public String getCustomName() {
        return "客户A";
    }
}
//注意要给Service命名
@Service("customB")
public class IAServiceLinyiImpl implements IAService{
 //客户B的逻辑
    @Override
    public String getCityName() {
        return "客户B";
    }
}

Service层写好以后,需要在Controller层做不同的实现。有两种方式

1.使用@Qualifier注解

在@Qualifier("customA")上标明要实现的类的Service填写的名字即可。但是这种方式有个弊端。Qualifier注解的参数必须是常量,无法填写配置文件的值,因此无法使用配置文件动态注入,只能动手改代码,基本是鸡肋般的存在。

@RestController
public class AController {

    //如果要给客户A部署,这里写客户A Service注解的名称,上面配置的是customA
    @Qualifier("customA")
    IAService iaService;

    //不同地区需要有不同的逻辑,下面service实例化的正好是不同地区的实例
    @GetMapping("/name")
    public String getCustomName() {
        return iaService.getCityName();
    }
}

2.使用@Resource注解

上面配置了两个不同客户Service注解的名称,我们可以使用Resource注解,通过配置文件的方式进行动态注入。通过配置文件进行灵活切换。

其实代码并没有多少改动,仅仅是换成了@Resource(name="${local.name}")而已,其中的local.name为从配置文件中要读取的变量对应的值。

@RestController
public class AController {

    //根据配置文件中配置的参数决定实例化哪个实现类,解决上面问题1
    @Resource(name="${local.name}")
    IAService iaService;

    //不同地区需要有不同的逻辑,下面service实例化的正好是不同地区的实例
    @GetMapping("/name")
    public String getCustomName() {
        return iaService.getCityName();
    }
}

SpringBoot同一接口多个实现类配置

SpringBoot项目中可能出现一个接口有多个实现类的情况,如果不进行配置,注入接口时编译器不知道要注入哪个实现类就会报错,因此需要进行配置。

以下进行举例:

接口如下:

public interface NoticeService {
    public String noticeUser(Long id);
}

两个实现类如下:

@Service
public class NoticeServiceImpl1 implements NoticeService {
 public String noticeUser(Long id){
  return noticeServe1(id);
 }
}
@Service
public class NoticeServiceImpl2 implements NoticeService {
 public String noticeUser(Long id){
  return noticeServe2(id);
 }
}

Controller如下:

@Controller
@RequestMapping("notice")
public class NoticeController{
 @Autowired
 NoticeService noticeService;
}

这样直接启动后就会报错,需要在添加@Qualifier注解:

@Controller
@RequestMapping("notice")
public class NoticeController{
 @Autowired
 @Qualifier("impl1")
 NoticeService noticeService;
}

需要调用的实现类中添加标识:

@Service("impl1")
public class NoticeServiceImpl1 implements NoticeService {
 public String noticeUser(Long id){
  return noticeServe1(id);
 }
}

此时再运行即可~

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Springboot实现根据条件切换注入不同实现类的示例代码

    最近有个一需求需要根据外界环境的属性(操作系统 || yml属性 || 其他bean的状态) 来实现启动时注入两套不同的实现类, 实现切换. 实现启动时条件注入分2步: 第一步 使用@Conditional(参数为 True false条件实现类 需要你自己实现)注解 @Conditional(RabbitMqCondition.class) public class RabbitmqSMSMsgServiceImpl extends RabbitmqBasicMsgService { // @

  • 详解SpringBoot配置文件启动时动态配置参数方法

    序言 当我们要同时启用多个项目而又要使用不同端口或者变换配置属性时,我们可以在配置文件中设置${变量名}的变量来获取启动时传入的参数,从而实现了动态配置参数,使启用项目更加灵活 例子 server: port: ${PORT:50101} #服务端口 spring: application: name: xc‐govern‐center #指定服务名 eureka: client: registerWithEureka: true #服务注册,是否将自己注册到Eureka服务中 fetchReg

  • SpringBoot同一接口多个实现类配置的实例详解

    SpringBoot项目中可能出现一个接口有多个实现类的情况,如果不进行配置,注入接口时编译器不知道要注入哪个实现类就会报错,因此需要进行配置.以下进行举例: 接口如下: public interface NoticeService { public String noticeUser(Long id); } 两个实现类如下: @Service public class NoticeServiceImpl1 implements NoticeService { public String not

  • SpringBoot注入配置文件的3种方法详解

    这篇文章主要介绍了SpringBoot注入配置文件的3种方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 方案1:@ConfigurationProperties+@Component 定义spring的一个实体bean装载配置文件信息,其它要使用配置信息是注入该实体bean /** * 将配置文件中配置的每一个属性的值,映射到这个组件中 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配

  • 详解SpringBoot中实现依赖注入功能

    今天给大家介绍一下SpringBoot中是如何实现依赖注入的功能. 在以往spring使用中,依赖注入一般都是通过在Spring的配置文件中添加bean方法实现的,相对于这个方式SpringBoot的实现方式就显得非常便捷了.SpringBoot的实现方式基本都是通过注解实现的. 下面来看一下具体案例,这里我编写了三个测试类用于测试依赖注入到底是否可以正确实现. TestBiz接口: package example.biz; public interface TestBiz { public S

  • 使用Springboot根据配置文件动态注入接口实现类

    Springboot根据配置文件动态注入接口实现类 需求 最近在做一个Springboot项目,需要面向不同需求的客户,但是为了方便管理分支,需要将不同客户的需求都写到同一套代码中,根据不同客户实例化对应的实现类. 实现 为了尽量不修改代码,少做不必要的逻辑判断,我们考虑为不同客户写不同的Service,然后根据配置参数实例化对应的Service.这样就遇到了需要根据配置文件实现不同类的需求. 针对这一需求大致有两种实现方式.但是针对我的需求,能用的只有第二种,但还是想将第一种一起总结一下. 两

  • spring boot 动态生成接口实现类的场景分析

    目录 一: 定义注解 二: 建立动态代理类 三: 注入spring容器 四: 编写拦截器 五: 新建测试类 在某些业务场景中,我们只需要业务代码中定义相应的接口或者相应的注解,并不需要实现对应的逻辑. 比如 mybatis和feign: 在 mybatis 中,我们只需要定义对应的mapper接口:在 feign 中,我们只需要定义对应业务系统中的接口即可. 那么在这种场景下,具体的业务逻辑时怎么执行的呢,其实原理都是动态代理. 我们这里不具体介绍动态代理,主要看一下它在springboot项目

  • springboot yml配置文件值注入方式

    目录 yml配置文件值注入 搭建项目 创建实体类 spring boot核心配置文件application.yml 测试类 运行 自动注入yml文件和properties文件 yml文件的自动注入class Properties配置文件自动注入 代码中直接注入 yml配置文件值注入 搭建项目 参考 IDEA快速搭建spring-boot项目(Spring initializr) pom.xml 创建项目后,还需在pom.xml中的<dependencies>标签添加该依赖. <depen

  • 使用SpringBoot根据配置注入接口的不同实现类(代码演示)

    目录 一.引言 二.代码演示 1.问题描述 2.解决方案 2.1使用@Autowired的时候将接口变量名改为实现类的限定名 2.2 使用@Autowired配合@Qualifier指定限定名注入实现类 2.3@ConditionalOnProperty 三.总结 一.引言 我们在使用springboot进行开发的时候经常用到@Autowired和@Resource进行依赖注入,但是当我们一个接口对应多个不同的实现类的时候如果不进行一下配置项目启动时就会报错,那么怎么根据不同的需求注入不同的类型

  • SpringBoot之通过BeanPostProcessor动态注入ID生成器案例详解

    在分布式系统中,我们会需要 ID 生成器的组件,这个组件可以实现帮助我们生成顺序的或者带业务含义的 ID. 目前有很多经典的 ID 生成方式,比如数据库自增列(自增主键或序列).Snowflake 算法.美团 Leaf 算法等等,所以,会有一些公司级或者业务级的 ID 生成器组件的诞生.本文就是通过 BeanPostProcessor 实现动态注入 ID 生成器的实战. 在 Spring 中,实现注入的方式很多,比如 springboot 的 starter,在自定义的 Configuratio

  • springboot手动动态注入controller和service方式

    目录 手动动态注入controller和service 在controller中使用参数 说明 手动动态注入controller和service package test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.fac

  • 创建动态代理对象bean,并动态注入到spring容器中的操作

    使用过Mybatis的同学,应该都知道,我们只需要编写mybatis对应的接口和mapper XML文件即可,并不需要手动编写mapper接口的实现.这里mybatis就用到了JDK动态代理,并且将生成的接口代理对象动态注入到Spring容器中. 这里涉及到几个问题.也许有同学会有疑问,我们直接编写好类,加入@Component等注解不是可以注入了吗?或者在配置类(@Configuration)中直接声明该Bean类型不也可以注入吗? 但具体到mybatis,这里我们用的是接口.由于spring

  • 浅谈SpringBoot集成Quartz动态定时任务

    SpringBoot自带schedule 沿用的springboot少xml配置的优良传统,本身支持表达式等多种定时任务 注意在程序启动的时候加上@EnableScheduling @Scheduled(cron="0/5 * * * * ?") public void job(){ System.out.println("每五秒执行一次"); } 为什么要使用Quartz 多任务情况下,quartz更容易管理,可以实现动态配置 执行时间表达式: 表达式示例: 集成

随机推荐