使用Springboot根据配置文件动态注入接口实现类
作者:iFence 发布时间:2022-11-18 06:56:45
标签: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);
}
}
此时再运行即可~
来源:https://blog.csdn.net/Vector97/article/details/116309598
0
投稿
猜你喜欢
- 前言相信很多Java开发都遇到过一个面试题:Resource和Autowired的区别是什么?这个问题的答案相信基本都清楚,但是这两者在Sp
- 简介官方API文档Scaffold的of方法说明有说明调用Scaffold.of方法是在Scallfold的子组件的Build方法中,也就是
- 前言 短时间提升自己最快的手段就是背面试题,最近总结了Java常用的面试题,分享给大家,希望大家都能圆梦大厂,加油,我命由我不由天
- 这篇会深化View拖拽实例,利用Flutter Animation、插值器以及AnimatedBuilder教大家实现带动画的抽屉效果。先来
- 内容简介本篇将介绍 Flutter 中如何完成图片上传,以及上传成功后的表单提交。涉及的知识点如下:图片选择插件wechat_assets_
- 接触过Android开发的同学们都知道在Android中访问程序资源基本都是通过资源ID来访问。这样开发起来很简单,并且可以不去考虑各种分辨
- 为什么需要 StreamStream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 Output
- Java环境配置原理详解1.Jdk安装目录文件说明:一般jdk安装目录及路径 \Java\jdk1.7.0_79\lib,里面主要包含以下文
- 最近在做代码优化时学习和研究了下JAVA多线程的使用,看了菜鸟们的见解后做了下总结。1、继承Thread类实现多线程继承Thread类的方法
- 1、LongAdder由来LongAdder类是JDK1.8新增的一个原子性操作类。AtomicLong通过CAS算法提供了非阻塞的原子性操
- 修改FeginCilent定义的服务名到指定服务通过覆盖类来修改对应的服务名,这里将所有的FeginClient对应的服务名都修改好。pac
- ShardingSphere的路由引擎类型本篇文章源码基于4.0.1版本上篇文章我们了解到了ShardingSphere在路由流程过程中,根
- Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动
- 通常情况下我们想实现文字的走马灯效果需要在xml文件中这样设置<TextView android:layout_widt
- 前言1.因为涉及到对象锁,Wait、Notify一定要在synchronized里面进行使用。2.Wait必须暂定当前正在执行的线程,并释放
- 如下所示://读取json文件地址 /* String path = getClass().getClassLoader().g
- 本文提供了基于MD5加密16位和32位的方法,具体内容如下import java.io.IOException;import java.ma
- 引言在高并发的场景下,异步是一个极其重要的优化方向。前段时间,生产环境发生一次事故,笔者认为事故的场景非常具备典型性 。写这篇文章,笔者想和
- 一、基本定义Arrays类,全路径java.util.Arrays,主要功能为操作数组,Arrays类的所有方法均为静态方法,所以调用方式全
- 走马灯是一种常见的效果,本文讲一下如何用 PageView 在 Flutter 里实现一个走马灯, 效果如下,当前页面的高度比其它页面高,切