- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章详解spring-boot下如何满足多生产环境中个性化定制功能由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
在项目的开发中,我们很难做到开发一套标准的流程来解决所有客户的需求。比如,我们当前的计量项目,分别运行于赤峰市和河北省。虽然两个区域处理的业务相同,但是对细节的实现要求却不同。前面也学习过计量检定软件,其为了解决各个定制者使用的功能需求,最后采取的方案是:将基础项目复制多份,进而满足不同的客户需求。优点当然是有的,但比起缺点来,优点便不值一提。缺点很明显,总结为一句话就是:项目变得难以维护。所以,当前让我们看到的就是,几个开发人员,每天处于解决问题当中。本文将给出一种方案,来有效的规避上述问题.
资源与环境 。
示例代码:https://github.com/mengyunzhi/springbootsamplecode/tree/master/dynamic-autowire 。
开发环境:java1.8 + spring-boot:2.1.3.release
需求假设 。
你好
或hello
hallo
。增加功能时,不更改核心代码。注意:如果你看完需求假设后,毫无触动,请忽略本文以下内容 。
解决方案 。
解决方案中,我们涉及了两种设计模块,分别为:策略模式及工厂模式.
策略模式:一般用于将具体的算法进行抽象及剥离。此项目中,我们的具体算法是说你好.
工厂模式:一般用于根据环境来动态的创建bean的情况下。引项目中,我们将根据不同国家的人,来返回不同的说你好这个算法.
先给出uml图:
speakservice 。
speakservice即为我们供其它模块调用的说话服务,调用其中的sayhello()来完成说你好功能.
1
2
3
4
5
6
7
8
|
package
com.mengyunzhi.demo.dynamicautowire;
/**
* 你好
*/
public
interface
speakservice {
void
sayhello();
}
|
在其实现类中,我们注入sayhellofactory,让其来返回正确的sayhelloservice,最终调用sayhello()来完成目标.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package
com.mengyunzhi.demo.dynamicautowire;
import
org.springframework.beans.factory.annotation.autowired;
import
org.springframework.stereotype.service;
/**
* 你好
*/
@service
public
class
speakserviceimpl
implements
speakservice {
private
final
sayhellofactory sayhellofactory;
// 说话工厂
@autowired
public
speakserviceimpl(sayhellofactory sayhellofactory) {
this
.sayhellofactory = sayhellofactory;
}
@override
public
void
sayhello() {
this
.sayhellofactory.getsayhelloservice().sayhello();
}
}
|
sayhellofactory 。
1
2
3
4
5
6
7
8
9
10
11
|
package
com.mengyunzhi.demo.dynamicautowire;
/**
* 说话工厂
*/
public
interface
sayhellofactory {
void
setcountrycode(countrycode countrycode);
sayhelloservice getsayhelloservice();
}
|
在此,我们增加一个countrycode表示当前访问者的国家。其实在获取访问者国家时,我们也可以调用其它bean的其它来实现.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package
com.mengyunzhi.demo.dynamicautowire;
/**
* 国家代码
*/
public
enum
countrycode {
china((
byte
)
0
,
"中国"
),
usa((
byte
)
1
,
"美国"
);
private
byte
code;
private
string name;
countrycode(
byte
code, string name) {
this
.code = code;
this
.name = name;
}
public
byte
getcode() {
return
code;
}
public
string getname() {
return
name;
}
}
|
使用enum来控制范围,避免factory在获取bean时发生异常.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
package
com.mengyunzhi.demo.dynamicautowire;
import
org.springframework.beans.factory.annotation.autowired;
import
org.springframework.stereotype.service;
import
java.util.hashmap;
import
java.util.list;
import
java.util.map;
/**
* 说话工厂
*/
@service
public
class
sayhellofactoryimpl
implements
sayhellofactory {
/**
* bean列表
*/
private
final
map<
byte
, sayhelloservice> servicesbycode =
new
hashmap<>();
/**
* 国家代码
*/
private
countrycode countrycode = countrycode.china;
@override
public
void
setcountrycode(countrycode countrycode) {
this
.countrycode = countrycode;
}
/**
* 初始化
*
* @param sayhelloservices spring获取到的所以实现了speakservice的bean
*/
@autowired
public
void
init(list<sayhelloservice> sayhelloservices) {
for
(sayhelloservice sayhelloservice : sayhelloservices) {
this
.register(sayhelloservice.getcode(), sayhelloservice);
}
}
/**
* 注册bean
*
* @param code 代码
* @param sayhelloservice bean
*/
private
void
register(
byte
code, sayhelloservice sayhelloservice) {
this
.servicesbycode.put(code, sayhelloservice);
}
/**
* 获取bean
*
* @return 对应的sayhelloservice bean
*/
@override
public
sayhelloservice getsayhelloservice() {
return
this
.servicesbycode.get(
this
.countrycode.getcode());
}
}
|
增加map<byte, sayhelloservice> servicesbycode来存储对应国家的sayhelloservicebean。增加getsayhelloservice()来根据当前国家代码来返回相应的bean.
sayhelloservice 。
1
2
3
4
5
6
7
8
9
10
|
package
com.mengyunzhi.demo.dynamicautowire;
/**
* 说话
*/
public
interface
sayhelloservice {
void
sayhello();
byte
getcode();
}
|
将sayhello()方法抽离,getcode()以获取国家代码.
中国人你好 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package
com.mengyunzhi.demo.dynamicautowire;
import
org.springframework.stereotype.component;
/**
* 中国话
*/
@component
public
class
sayhelloservicechineseimpl
implements
sayhelloservice {
@override
public
void
sayhello() {
system.out.println(
"您好"
);
}
@override
public
byte
getcode() {
return
countrycode.china.getcode();
}
}
|
美国人hello 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package
com.mengyunzhi.demo.dynamicautowire;
import
org.springframework.stereotype.component;
/**
* 美国话
*/
@component
public
class
sayhelloserviceenglishimpl
implements
sayhelloservice {
@override
public
void
sayhello() {
system.out.println(
"hello"
);
}
@override
public
byte
getcode() {
return
countrycode.usa.getcode();
}
}
|
测试 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package
com.mengyunzhi.demo.dynamicautowire;
import
org.junit.test;
import
org.junit.runner.runwith;
import
org.springframework.beans.factory.annotation.autowired;
import
org.springframework.boot.test.context.springboottest;
import
org.springframework.test.context.junit4.springrunner;
@springboottest
@runwith
(springrunner.
class
)
public
class
speakserviceimpltest {
@autowired
speakservice speakservice;
@autowired
sayhellofactory sayhellofactory;
@test
public
void
sayhello() {
// 默认说你好
speakservice.sayhello();
// 将国家设置为美国,再说你好
sayhellofactory.setcountrycode(countrycode.usa);
speakservice.sayhello();
// 将国家设置为中国,再说你好
sayhellofactory.setcountrycode(countrycode.china);
speakservice.sayhello();
}
}
|
您好 hello 您好 。
时序图 。
增加德国人 。
增加德国人sayhelloservicegermanyimpl. 。
在countrycode中,增加德国. 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package
com.mengyunzhi.demo.dynamicautowire;
import
org.springframework.stereotype.component;
@component
public
class
sayhelloservicegermanyimpl
implements
sayhelloservice {
@override
public
void
sayhello() {
system.out.println(
"hallo"
);
}
@override
public
byte
getcode() {
return
countrycode.germany.getcode();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package
com.mengyunzhi.demo.dynamicautowire;
/**
* 国家代码
*/
public
enum
countrycode {
china((
byte
)
0
,
"中国"
),
usa((
byte
)
1
,
"美国"
),
germany((
byte
)
2
,
"德国"
);
private
byte
code;
private
string name;
countrycode(
byte
code, string name) {
this
.code = code;
this
.name = name;
}
public
byte
getcode() {
return
code;
}
public
string getname() {
return
name;
}
}
|
单元测试 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@test
public
void
sayhello1() {
// 默认说你好
speakservice.sayhello();
// 将国家设置为美国,再说你好
sayhellofactory.setcountrycode(countrycode.usa);
speakservice.sayhello();
// 将国家设置为德国,再说你好
sayhellofactory.setcountrycode(countrycode.germany);
speakservice.sayhello();
// 将国家设置为中国,再说你好
sayhellofactory.setcountrycode(countrycode.china);
speakservice.sayhello();
}
|
测试结果如下:
您好 hello hallo 您好 。
总结 。
在解决问题时,只所有我们看的不够远,可能是由于自己站的不够高。同样的问题,困惑我了多日,直到近期系统的学习设计模式 、angular官方教程、spring 实战后,结合近期项目变更带来的新需求,才在使用设计模式解决此问题上有所启发.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://segmentfault.com/a/1190000018673552 。
最后此篇关于详解spring-boot下如何满足多生产环境中个性化定制功能的文章就讲到这里了,如果你想了解更多关于详解spring-boot下如何满足多生产环境中个性化定制功能的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我目前被指派去调查并以某种方式找到一种“定制”(对身份验证、常量、消息等进行修改)OpenSSH 的方法,并且作为一个“基于网络”的人,我真的不知道从哪儿开始。因此非常感谢评论。 问题: 我从 her
我拥有的 excel 文件超过 1,000,000 行和 26 列。 下面是用于查找特定数据的代码,并根据该数据创建一个新文件,目前创建一个新文件大约需要 15 分钟 请如果有专家可以帮助我更快地处理
我正在处理Zend_Form现在,我很难弄清楚如何: 使用表单按钮的自定义图像, 在特定位置插入文本和链接(就我而言,我想在提交按钮之前添加“忘记密码?”链接)。 我已通读手册,但没有看到任何相关内容
是否可以将图像添加到 UISwitch 背景,例如当状态为 ON 时(作为一个背景)和当状态为 OFF 时(另一个背景图像)? 最佳答案 要更改背景颜色(不是图像),您只需执行以下操作即可。这会更改领
到目前为止,我刚刚开始使用 Octave 并在我的终端上运行它。 每次打开提示符时,我的命令行都以: octave-3.4.0:1> 因此我使用以下内容来使其更短且更易于阅读: PS1('>> ')
在阅读Struts2文档时,我遇到了下面引用的段落 customizing controller - Struts 1 lets to customize the request processor
我正在尝试自定义 jQuery Tag-It 小部件 (http://aehlke.github.com/tag-it/) 以实现以下两种行为: 1)允许在标签中使用逗号(我可以通过自定义trigge
我是整个 Emacs 的新手,让我着迷的一件事是开箱即用的 Emacs 在编程时不会让您陷入困境。我主要使用 Python 和 C++ 进行编程,然后按回车键将光标发送回新行的第 1 列,而不是让你停
我有这些行 y DB,我想按以下顺序排序,并包含字符和数字。 Score 列是一个 varchar。获胜者和失败者也在分数栏中。 得分 WINNER 100+ 100 90 80+ 80 50 LOS
我正在使用 Bootstrap,您如何自定义轮播? 有什么建议吗? https://v4-alpha.getbootstrap.com/components/carousel/ 最佳答案 .activ
我有一个投票设置,使用脚本将其拉入我的 WP 页面。通过http://quipol.com/ EG 我已经通过 firebug 找到了样式并在其中相应地自定义了它们,但我想知道是否有一种方法可以实现
美好的一天。 如果 JLabel 和 JTextField 字体大小可以根据需要更改,是否也可以更改 JTable 的列名称和元素的字体样式(大小、外观、颜色)? 添加更多内容,我正在使用 Windo
进一步回答我的问题Java JFilechooser 。建议扩展 BasicFileChooserUI,重写 create/getModel 并提供 BasicDirectoryModel 的实现。
我想制作(好吧..正在制作..)一个标签页。我用 border-top:none 属性制作了一个“选项卡框”,所以它看起来像是选项卡的一部分,在里面我有一个表格。 我想知道,有没有办法删除表格标题的所
我有大量的项目正在进行中,还有几个解决方案(它们是项目“池”的子集)。有时拥有一个仅用于特定测试的 .sln 是件好事。 问题: NUGet 分别绑定(bind)到每个解决方案。 NUGet 喜欢在
我计划编写一些 git 钩子(Hook)作为一个项目,将用户的操作记录在数据库中。然后可以使用该数据库查询他的所有事件。我尝试记录的操作是 promise pull 推送 merge 分支机构 我想把
大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进。 在本文中,我们将学习中间件,以及如何使用它进一步定制应用程序。我
我正在尝试使用 yasg 自定义我的 api 文档。 首先,我想确定我自己的部分的命名,以及本部分应包含哪些端点。似乎部分的命名是基于不属于最长公共(public)前缀的第一个前缀,例如: 如果我们有
我需要(即客户要求)提供自定义键盘,供用户在文本字段和区域中输入文本。我已经有一些可以执行键盘操作并将测试附加到文本字段的东西,但是我想让它更通用并让它像标准的 iphone 键盘一样工作,即当用户选
我有一个项目,它在特定位置(不是/src/resources)包含资源(模板文件)。我希望在运行 package-bin 时将这些资源打包。 我看到了 package-options 和 packag
我是一名优秀的程序员,十分优秀!