Spring Boot 2 实践记录之 条件装配

实验项目是想要使用多种数据库访问方式,比如 JPA 和 MyBatis。

项目的 Service 层业务逻辑相同,只是具体实现代码不同,自然是一组接口,两组实现类的架构比较合理。

不过这种模式却有一个问题,如果 Bean 是按实现类装配,则在切换数据库访问方式时,就需要大量的代码修改。如果按接口装配,则会出现歧义(同一接口有两个实现,无法自动装配)。

虽然可以使用「首选Bean」或「限定」装配,但是与直接使用实现类装配一样,切换数据库访问地,仍然要大量修改源码。

经过实验,使用「条件装配」实现了利用配置切换数据库访问方式,不需要修改代码了。

示例:

先定义 Service 接口:

public interface UserServiceInterface {......  
}

再定义 MyBatis 实现类:

@Service
@Conditional(MybatisCondition.class)
public class UserServiceMybatisImpl implements UserServiceInterface {......
}

注意其中的 @Conditional(MybatisCondition.class),MybatisCondition 类必须实现 org.springframework.context.annotation.Condition 接口,该接口仅有一个 matches 方法,当该方法返回真时,UserServiceMybatisImpl 被装配。

MybatisCondition 的 matches 方法的逻辑被实现为根据配置文件中的 use.data.access.method 属性是否为 mybatis,来决定是否装配 UserServiceMybatisImpl 类:

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;public class MybatisCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {Environment env = context.getEnvironment();if (env.getProperty("use.data.access.method").equals("mybatis")) {return true;}return false;}
}

再定义 SPA 实现类及其 SpaCondition 类,实现方式与 Mybatis 相同,仅在配置项为 spa 时,装配 UserServiceSpaImpl 类:

@Service
@Conditional(SpaCondition.class)
public class UserServiceSpaImpl implements UserServiceInterface {......
}
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;public class SpaCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {Environment env = context.getEnvironment();if (env.getProperty("use.data.access.method").equals("spa")) {return true;}return false;}
}

定义一个类,自动装配 UserServiceInterface,并打印其类名:

public class Test {@Autowiredprivate UserServiceInterface userServiceInterface;public void testUserService() {System.out.println(userServiceInterface.getClass();}
}      

现在还不能运行,需要添加配置项。

先将配置项配置为 mybatis:

use.data.access.method = mybatis

运行 Test 类的 testUserService 方法,结果为:

UserServiceMybatisImpl

将配置项修改为 spa:

use.data.access.method = spa

运行 Test 类的 testUserService 方法,结果为:

UserServiceSpaImpl

 

不过,有个小小的缺憾,就是在 Idea 中,如下代码行:

@Autowired
private UserServiceInterface userServiceInterface;

会有错误提示:

Could not autowire. There is more than one bean of 'UserServiceInterface' type.
Beans:
userServiceMybatisImpl   (UserServiceMybatisImpl.java) 
userServiceSpaImpl   (UserServiceSpaImpl.java)

由于配置项是在运行时读取的,Idea 在静态语法检查时,实在没办法搞定这个自动装配的判断。

没关系,不影响运行!

转载于:https://www.cnblogs.com/matchless/p/10389918.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/264797.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过简易的前台代码实现无限二级域名转向(来自无忧 biyuan老矣)

只要空间支持泛域名解析&#xff0c;无须服务端脚本语言和DNS&#xff0c;通过前台代码便可实现无限二级域名的构造&#xff1a; <html> <head> <title>碧原网络免费二级域名</title> <head> </head> <body> <scrīp…

MySQL入门-3:安装与客户端工具

大纲1、安装 MySQL2、检索数据3、数据过滤一、安装环境CentOS-6.5-i386mysql 5.1.73为了方便&#xff0c;这里采用yum方式安装&#xff0c;对于学习实验环境完全没问题&#xff0c;注意下面的操作都以root身份操作。除非对MySQL需要定制化或者安装多个实例&#xff0c;建议使用…

实验吧-web-天下武功唯快不破(Python中byte和str的转换)

题目&#xff1a;看看响应头 打开网站&#xff0c;既然已经提示我们看响应头了&#xff0c;那我们就看看呗(习惯bp&#xff0c;也可直接F12查看) 可以看到&#xff0c;响应头部分有个FLAG&#xff0c;而且有提示&#xff1a;please post what you find with parameter:key 所以…

一个弹出页面的徐徐升起的js效果

<HTML><HEAD><title>提醒信息</title><base target"_blank"><SCRIPT language"JavaScript"> window.resizeTo(220,210); var windowW220 // wide var windowH210 // high var Yoffset0 // in pixels, ne…

我国域名***日均58起 高安全DNS防御系统建设刻不容缓

日前&#xff0c;国家互联网应急中心发布的《2013年中国互联网网络安全报告》显示&#xff0c;作为互联网运行的关键基础设施&#xff0c;我国域名系统面临安全漏洞和拒绝服务***等多种威胁&#xff0c;是影响网络稳定运行的薄弱环节。中心监测报告显示&#xff0c;2013年针对我…

P4592 [TJOI2018]异或 (可持久化Trie)

[题目链接] https://www.luogu.org/problemnew/show/P4592 题目描述 现在有一颗以\(1\)为根节点的由\(n\)个节点组成的树&#xff0c;树上每个节点上都有一个权值\(v_i\)。现在有\(Q\)次操作&#xff0c;操作如下&#xff1a; \(1\;x\;y&#xff1a;\)查询节点xx的子树中与\(y\…

xml与数据库略解

1.0 简介 本论文简要的探讨了XML和数据库之间的关系&#xff0c;同时列出一些可以使用数据库处理XML文档的软件。虽然这里不打算详尽地介绍这些软件&#xff0c;但是笔者希望它能够描述使用数据库处理XML文档中的主要部分。这里有点偏向与关系数据库&#xff0c;…

魔方阵

①问题描述 魔方阵是一个古老的智力问题&#xff0c;它要求在一个mm的矩阵中填入1&#xff5e;m2的数字&#xff08;m为奇数&#xff09;&#xff0c;使得每一行、每一列、每条对角线的累加和都相等&#xff0c;如图1所示。 15 8 1 24 17 16 14 7 5 23 22 20 13 6…

专题训练5总结

这个专题学习了两种算法 1.稳定婚姻匹配问题 2.最大团问题 稳定婚姻匹配问题&#xff1a; 1.Stable Match 关于信号站匹配 多了一个容量的权值 如果距离相同看容量大小 数据处理较麻烦&#xff01; 2.marriage 稳定婚姻匹配问题入门题 3.The Stable Marriage problem 和入门题…

CodeSmith实用技巧(八):生成的代码输出到文件中

在CodeSmith中&#xff0c;要把生成的代码文件输出到文件中&#xff0c;你需要在自己的模版中继承OutputFileCodeTemplate类。<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /><% CodeTemplate Language"C#"TargetL…

python 3的33个保留字列表_python 33个保留字是什么意思

and 用于表达式运算&#xff0c;逻辑与操作as 用于类型转换assert 断言&#xff0c;用于判断变量或条件表达式的值是否为真break 中断循环语句的执行class 用于定义类continue 继续执行下一次循环def 用于定义函数或方法del 删除变量或者序列的值elif 条件语句 与if else 结合使…

SSH整合jar包下载

2019独角兽企业重金招聘Python工程师标准>>> http://blog.sina.com.cn/s/blog_8a3d83320100zhmp.html svn使用 spring 下载 http://maven.springframework.org/release/org/springframework/spring/4.0.5.RELEASE/ http://repo.spring.io/libs-release-local/org/sp…

面试之什么是java虚拟机

java虚拟机体系结构 方法区 堆 java虚拟机栈 本地方法栈方法区 java虚拟机编译的class文件中二进制数据类型解析数据存在方法区中 是所有线程共享和存在数据的线程安全问题 当二个线程使用同一类并且类还被加载 则让一个线程加载 另一个线程等待java虚拟机栈 是线程私有的 既决…

高质量c/c++编程(9)

第9章 类的构造函数、析构函数与赋值函数构造函数、析构函数与赋值函数是每个类最基本的函数。它们太普通以致让人容易麻痹大意&#xff0c;其实这些貌似简单的函数就象没有顶盖的下水道那样危险。每个类只有一个析构函数和一个赋值函数&#xff0c;但可以有多个构造函数&#…

三合一剪弦器怎么用_三合一冲锋衣推荐选购攻略:

一、冲锋衣的类别二、三合一冲锋衣小评测。三、冲锋衣维护一、冲锋衣的类别冲锋衣分&#xff1a;硬壳、软壳&#xff0c;三合一&#xff0c;三种类型。软壳是介于抓绒衣和冲锋衣之间的衣服&#xff0c;防水上比硬壳差&#xff0c;只能防小雨&#xff0c;但优势在于活动方便&…

Celery 之异步任务、定时任务、周期任务

什么是Celery?Celery 是芹菜Celery 是基于Python实现的模块, 用于执行异步定时周期任务的其结构的组成是由 1.用户任务 app 2.管道 broker 用于存储任务 官方推荐 redis rabbitMQ / backend 用于存储任务执行结果的 3.员工 worker 一 异步任务 1 from celery import…

堆栈认知——栈溢出实例(ret2libc)

参考&#xff1a;栈溢出实例–笔记三&#xff08;ret2libc&#xff09; 地址&#xff1a;https://qingmu.blog.csdn.net/article/details/119481681 目录1、栈溢出含义及栈结构2、ret2libc基本思路3、实战3.1、二进制程序3.2、查看栈结构3.3、第一次栈溢出3.4、第二次栈溢出1、…

对”命令“操作的命令

乍一看这个标题有点拗口&#xff0c;什么叫对“命令”操作的命令呢&#xff1f;其实从字面上就可以理解我要表达的意思&#xff0c;今天这篇博客写的还是命令&#xff0c;但是这些命令有点不一样&#xff0c;不一样的地方在于这些命令操作的对象就是“命令”。1&#xff0c; t…

用代理技术实现简单的AOP框架

在许多的实现AOP框架的技术中&#xff0c;不管是静态织入还是动态织入&#xff0c;关键点在于拦截方法&#xff0c;并在方法中加入预处理和后处理。而实现方法的拦截的一个简单办法就是 把类的实例委托给类的真实代理(RealProxy).这样以来&#xff0c;方法的调用都会被转换成消…

halcon 单通道图像转成3通道_halcon图像处理基本运算

halcon图像处理基本运算图像处理最基本的操作包括颜色空间转换&#xff0c;各种代数运算&#xff0c;放射变换等。通过熟悉这些常见的操作&#xff0c;可以对图像有基本的认识&#xff0c;尤其是对刚开始接触视觉图像处理的人而言&#xff0c;熟悉这些操作&#xff0c;可以快速…