本文由 简悦 SimpRead 转码, 原文地址 zhuanlan.zhihu.com
JAVA 代码的热部署,动态语言 Groovy 使用的三种方式
一、概述
Groovy 是构建在 JVM 上的一个轻量级却强大的动态语言, 它结合了 Python、Ruby 和 Smalltalk 的许多强大的特性.
Groovy 就是用 Java 写的 , Groovy 语法与 Java 语法类似, Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码, 相对于 Java, 它在编写代码的灵活性上有非常明显的提升,Groovy 可以使用其他 Java 语言编写的库.
Groovy 通常是被用来扩展现有的代码,就是说,当你需要某个实现类动态生成的时候,就可以使用 Groovy 来完成,比如: 1. 动态类实现从文件生成,改动后能立即检测到。 2. 动态类实现从数据库中生成,改动后能立即检测到。 3. 动态类作为 Spring 的 bean 被管理起来,改动后能立即检测到。
这次,我要讲的就是这三种方式。
首发地址: 品茗 IT - 同步发布
如果大家正在寻找一个 java 的学习环境,或者在开发中遇到困难,可以 ,共同学习,节约学习时间,减少很多在学习中遇到的难题。加入我们的 java 学习圈,点击即可加入
二、准备工作
本篇的使用场景是:假设有一个规则接口,它的实现可以是本地的 JAVA 代码实现,也可以是 groovy 文件实现,也可以通过数据库存储的 Groovy 脚本实现,也可以是 Spring 管理的 bean。然后这多种不同的规则实现,放到一个列表中,统一执行。
在 xxl-job 中,所有的任务都要实现 IJobHandler 接口,它的 web Glue 方式就是基于 Groovy 实现的。
2.1 规则接口 IRule
IRule 定义了这个规则接口。
IRule:
1
2
3
4
5
6
7
8
9
10
11
12
|
package cn.pomit.skill.groovy.rule;
public interface IRule {
static final int NORMAL_TYPE = 0;
static final int GROOVY_FILE_TYPE = 1;
static final int GROOVY_DB_TYPE = 2;
static final int GROOVY_SPRING_TYPE = 3;
int getType();
void printInfo();
}
|
2.2 普通的 JAVA 实现
如果是普通的 Java 实现,就很简单。
NormalJavaRule:
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 cn.pomit.skill.groovy.rule.normal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.pomit.skill.groovy.rule.IRule;
public class NormalJavaRule implements IRule {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public int getType() {
return NORMAL_TYPE;
}
@Override
public void printInfo() {
log.info("这是正常的JAVA代码");
printInfoHigh();
}
//加这段是为了测试改动后输出是否有变化,在ide里,只靠上面的打印看不出来效果
public void printInfoHigh() {
log.info("这是正常的JAVA代码的代码");
}
}
|
三、非 Spring 环境 Groovy 文件方式
3.1 Groovy 文件
定义一个 GroovyFileRule 的 Groovy 文件,执行自己的规则。
GroovyFileRule:
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 cn.pomit.skill.groovy.rule.file;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.pomit.skill.groovy.rule.IRule;
class GroovyFileRule implements IRule {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public int getType() {
return GROOVY_FILE_TYPE;
}
@Override
public void printInfo() {
log.info("这是一段来自Groovy文件的代码");
printInfoHigh();
}
public void printInfoHigh() {
log.info("这是一段来自Groovy文件的代码的代码");
}
}
|
3.2 读取并生成实例
我这里定义了一个 GroovyFactory,用来实现将 Groovy 文件生成 IRule 的实现.
GroovyFactory :
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
|
package cn.pomit.skill.groovy.rule;
import java.net.URL;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource;
public class GroovyFactory {
private static GroovyFactory groovyFactory = new GroovyFactory();
private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
public static GroovyFactory getInstance() {
return groovyFactory;
}
/**
* 根据groovy文件路径生成IRule的实现
* @param packagePath
* @return
* @throws Exception
*/
public IRule getIRuleFromPackage(String filePath) throws Exception {
URL url = this.getClass().getClassLoader().getResource(filePath);
Class<?> clazz = groovyClassLoader.parseClass(new GroovyCodeSource(url));
if (clazz != null) {
Object instance = clazz.newInstance();
if (instance != null) {
if (instance instanceof IRule) {
return (IRule) instance;
}
}
}
throw new IllegalArgumentException("读取groovy文件异常");
}
}
|
3.3 使用这个实现
1
2
3
4
5
6
7
8
9
|
//调用普通的JAVA实现做对比
List<IRule> rules = new ArrayList<>();
NormalJavaRule normalJavaRule = new NormalJavaRule();
rules.add(normalJavaRule);
//直接读取Groovy文件生成IRule实现
IRule groovyFile = GroovyFactory.getInstance()
.getIRuleFromPackage("cn/pomit/skill/groovy/rule/file/GroovyFileRule.groovy");
rules.add(groovyFile);
|
执行并调用 list 里面元素的printInfo
方法,结论:
1
2
3
4
|
2020-01-02 12:16:25,738 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.normal.NormalJavaRule] 这是正常的JAVA代码
2020-01-02 12:16:25,739 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.normal.NormalJavaRule] 这是正常的JAVA代码的代码
2020-01-02 12:16:25,744 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.file.GroovyFileRule] 这是一段来自Groovy文件的代码
2020-01-02 12:16:25,745 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.file.GroovyFileRule] 这是一段来自Groovy文件的代码的代码
|
改动 JAVA 普通的实现,打印的东西不会改动(如果只是改变打印内容,ide 可能会做优化,可以直接改动逻辑,会更明显)。
改动 Groovy 文件,打印的东西马上就做改动了。
四、数据库 Groovy 脚本方式
4.1 Groovy 脚本
定义一个 GroovyDbRule 的脚本,执行自己的规则。GroovyDbRule 脚本存储在数据库中,
GroovyDbRule 脚本如下:
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 cn.pomit.skill.groovy.rule.file;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.pomit.skill.groovy.rule.IRule;
class GroovyDbRule implements IRule {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public int getType() {
return GROOVY_DB_TYPE;
}
@Override
public void printInfo() {
log.info("这是一段来自数据库的Groovy脚本");
printInfoHigh();
}
public void printInfoHigh() {
log.info("这是一段来自数据库的Groovy脚本的代码");
}
}
|
建表语句及插入以上脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
CREATE TABLE `pomit_rule` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`rule` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
`create_time` timestamp(0) DEFAULT CURRENT_TIMESTAMP,
`update_time` timestamp(0) DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0),
`visible` int(11) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of pomit_rule
-- ----------------------------
INSERT INTO `pomit_rule` VALUES (5, 'GroovyDbRule', 'package cn.pomit.skill.groovy.rule.file;\r\n\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport cn.pomit.skill.groovy.rule.IRule;\r\n\r\nclass GroovyDbRule implements IRule {\r\n private Logger log = LoggerFactory.getLogger(this.getClass());\r\n \r\n @Override\r\n public int getType() {\r\n return GROOVY_DB_TYPE;\r\n }\r\n\r\n @Override\r\n public void printInfo() {\r\n log.info(\"这是一段来自数据库的Groovy脚本\");\r\n printInfoHigh();\r\n }\r\n \r\n public void printInfoHigh() {\r\n log.info(\"这是一段来自数据库的Groovy脚本的代码\");\r\n }\r\n}\r\n', '2020-01-02 10:36:01', '2020-01-02 10:36:01', NULL);
|
4.2 读取并生成实例
在 GroovyFactory,加入从字符串生成 IRule 实现的方法.
在上面 3.2 中的 GroovyFactory 中,加入下面的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/**
* 根据脚本内容生成IRule的实现
* @param code
* @return
* @throws Exception
*/
public IRule getIRuleFromCode(String code) throws Exception {
Class<?> clazz = groovyClassLoader.parseClass(code);
if (clazz != null) {
Object instance = clazz.newInstance();
if (instance != null) {
if (instance instanceof IRule) {
return (IRule) instance;
}
}
}
throw new IllegalArgumentException("读取groovy脚本异常");
}
|
4.3 使用这个实现
这里使用到了数据库,所以要使用 ORM 框架,我使用了 Mybatis。RulesDao 是 Mybatis 对 4.1 中表 pomit_rule 操作的一个 Mapper。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
//调用普通的JAVA实现做对比
List<IRule> rules = new ArrayList<>();
NormalJavaRule normalJavaRule = new NormalJavaRule();
rules.add(normalJavaRule);
//直接读取Groovy文件生成IRule实现
IRule groovyFile = GroovyFactory.getInstance()
.getIRuleFromPackage("cn/pomit/skill/groovy/rule/file/GroovyFileRule.groovy");
rules.add(groovyFile);
//从Db的Groovy脚本中生成IRule实现
Rules ruleGroovy = rulesDao.getByName("GroovyDbRule");
if (ruleGroovy != null) {
IRule groovyDb = GroovyFactory.getInstance().getIRuleFromCode(ruleGroovy.getRule());
rules.add(groovyDb);
}
|
执行并调用 list 里面元素的printInfo
方法,结论:
1
2
3
4
5
6
|
2020-01-02 12:16:25,738 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.normal.NormalJavaRule] 这是正常的JAVA代码
2020-01-02 12:16:25,739 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.normal.NormalJavaRule] 这是正常的JAVA代码的代码
2020-01-02 12:16:25,744 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.file.GroovyFileRule] 这是一段来自Groovy文件的代码
2020-01-02 12:16:25,745 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.file.GroovyFileRule] 这是一段来自Groovy文件的代码的代码
2020-01-02 12:16:25,745 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.file.GroovyDbRule] 这是一段来自数据库的Groovy脚本
2020-01-02 12:16:25,745 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.file.GroovyDbRule] 这是一段来自数据库的Groovy脚本的代码
|
改动 JAVA 普通的实现,打印的东西不会改动(如果只是改变打印内容,ide 可能会做优化,可以直接改动逻辑,会更明显)。
改动 Groovy 文件,打印的东西马上就做改动了。
改动数据库中的 Groovy 脚本,打印的东西马上就做改动了。
五、Spring 中使用 Groovy 的方式
5.1 Groovy 文件
定义一个 SpringGroovyRule 文件,执行自己的规则。这里拿它来测试 Spring 是如何将 Groovy 文件作为 Bean 来使用,不再手动读取 Groovy 文件。
SpringGroovyRule 如下:
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 cn.pomit.skill.groovy.rule.spring;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.pomit.skill.groovy.rule.IRule;
import org.springframework.stereotype.Service;
public class SpringGroovyRule implements IRule {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public int getType() {
return GROOVY_SPRING_TYPE;
}
@Override
public void printInfo() {
log.info("这是一段Spring的Groovy代码");
printInfoHigh();
}
public void printInfoHigh() {
log.info("这是一段Spring的Groovy代码的代码");
}
}
|
5.2 读取并生成实例
建立 Spring 的配置文件(SpringBoot 也要这样玩,因为 Groovy 文件没有 JAVA 配置的方式生成 Bean):spring-groovy.xml。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:lang="http://www.springframework.org/schema/lang"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/lang
http://www.springframework.org/schema/lang/spring-lang.xsd">
<lang:defaults refresh-check-delay="60000" />
<!-- groovy文件定义为bean -->
<lang:groovy id="springGroovyRule"
script-source="classpath:cn/pomit/skill/groovy/rule/spring/SpringGroovyRule.groovy">
</lang:groovy>
</beans>
|
5.3 使用这个实现
如果是在 SpringBoot 下,需要引入上面的 xml 文件:@ImportResource(locations={"classpath:spring-groovy.xml"})
注入这个 bean:
1
2
|
@Resource(name = "springGroovyRule")
IRule springGroovyRule;
|
可以将它放到之前定义的List<IRule> rules
中,并调用里面元素的printInfo
方法,执行完成如下:
1
2
3
4
5
6
7
8
|
2020-01-02 12:16:25,738 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.normal.NormalJavaRule] 这是正常的JAVA代码
2020-01-02 12:16:25,739 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.normal.NormalJavaRule] 这是正常的JAVA代码的代码
2020-01-02 12:16:25,744 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.file.GroovyFileRule] 这是一段来自Groovy文件的代码
2020-01-02 12:16:25,745 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.file.GroovyFileRule] 这是一段来自Groovy文件的代码的代码
2020-01-02 12:16:25,745 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.file.GroovyDbRule] 这是一段来自数据库的Groovy脚本
2020-01-02 12:16:25,745 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.file.GroovyDbRule] 这是一段来自数据库的Groovy脚本的代码
2020-01-02 12:16:25,747 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.spring.SpringGroovyRule] 这是一段Spring的Groovy代码
2020-01-02 12:16:25,748 [http-nio-8086-exec-1][IP:|USER:][INFO cn.pomit.skill.groovy.rule.spring.SpringGroovyRule] 这是一段Spring的Groovy代码的代码
|
六、过程中用到的其他文件
6.1 完整的 GroovyFactory
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
|
package cn.pomit.skill.groovy.rule;
import java.net.URL;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource;
public class GroovyFactory {
private static GroovyFactory groovyFactory = new GroovyFactory();
private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
public static GroovyFactory getInstance() {
return groovyFactory;
}
/**
* 根据groovy文件路径生成IRule的实现
* @param packagePath
* @return
* @throws Exception
*/
public IRule getIRuleFromPackage(String filePath) throws Exception {
URL url = this.getClass().getClassLoader().getResource(filePath);
Class<?> clazz = groovyClassLoader.parseClass(new GroovyCodeSource(url));
if (clazz != null) {
Object instance = clazz.newInstance();
if (instance != null) {
if (instance instanceof IRule) {
return (IRule) instance;
}
}
}
throw new IllegalArgumentException("读取groovy文件异常");
}
/**
* 根据脚本内容生成IRule的实现
* @param code
* @return
* @throws Exception
*/
public IRule getIRuleFromCode(String code) throws Exception {
Class<?> clazz = groovyClassLoader.parseClass(code);
if (clazz != null) {
Object instance = clazz.newInstance();
if (instance != null) {
if (instance instanceof IRule) {
return (IRule) instance;
}
}
}
throw new IllegalArgumentException("读取groovy脚本异常");
}
}
|
6.2 完整的 RuleFactory
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
61
62
63
64
65
|
package cn.pomit.skill.groovy.rule;
import java.util.ArrayList;
import java.util.List;
import cn.pomit.skill.groovy.rule.db.Rules;
import cn.pomit.skill.groovy.rule.db.RulesDao;
import cn.pomit.skill.groovy.rule.normal.NormalJavaRule;
public class RuleFactory {
private static volatile RuleFactory singleton = null;
private RuleFactory() {
}
public static RuleFactory getInstance() {
// 第一次校验singleton是否为空
if (singleton == null) {
synchronized (RuleFactory.class) {
// 第二次校验singleton是否为空
if (singleton == null) {
singleton = new RuleFactory();
}
}
}
return singleton;
}
private RulesDao rulesDao;
private RuleFactory(RulesDao rulesDao) {
this.rulesDao = rulesDao;
}
public static RuleFactory getInstance(RulesDao rulesDao) {
// 第一次校验singleton是否为空
if (singleton == null) {
synchronized (RuleFactory.class) {
// 第二次校验singleton是否为空
if (singleton == null) {
singleton = new RuleFactory(rulesDao);
}
}
}
return singleton;
}
public List<IRule> getRuleList() throws Exception {
//调用普通的JAVA实现做对比
List<IRule> rules = new ArrayList<>();
NormalJavaRule normalJavaRule = new NormalJavaRule();
rules.add(normalJavaRule);
//直接读取Groovy文件生成IRule实现
IRule groovyFile = GroovyFactory.getInstance()
.getIRuleFromPackage("cn/pomit/skill/groovy/rule/file/GroovyFileRule.groovy");
rules.add(groovyFile);
//从Db的Groovy脚本中生成IRule实现
Rules ruleGroovy = rulesDao.getByName("GroovyDbRule");
if (ruleGroovy != null) {
IRule groovyDb = GroovyFactory.getInstance().getIRuleFromCode(ruleGroovy.getRule());
rules.add(groovyDb);
}
return rules;
}
}
|
6.3 数据库访问相关实体
Rules:
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 cn.pomit.skill.groovy.rule.db;
import java.util.Date;
public class Rules {
private Integer id;
private String rule;
private String name;
private Date create_time;
private Date update_time;
private Integer visible;
public String getRule() {
return rule;
}
public void setRule(String rule) {
this.rule = rule;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getVisible() {
return visible;
}
public void setVisible(Integer visible) {
this.visible = visible;
}
public Date getUpdate_time() {
return update_time;
}
public void setUpdate_time(Date update_time) {
this.update_time = update_time;
}
public Date getCreate_time() {
return create_time;
}
public void setCreate_time(Date create_time) {
this.create_time = create_time;
}
}
|
RulesDao:
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
|
package cn.pomit.skill.groovy.rule.db;
import java.util.List;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
@Mapper
public interface RulesDao {
@Select("SELECT * FROM pomit_rule where id = #{id}")
Rules getById(@Param("id") Integer id);
@Select("SELECT * FROM pomit_rule where name = #{name}")
Rules getByName(@Param("name") String name);
@Insert("INSERT INTO pomit_rule(name,rule) VALUE(#{name},#{rule})")
Integer setRule(@Param("name") String name,@Param("rule") String rule);
@Select("SELECT * FROM pomit_rule order by create_time DESC")
List<Rules> getRuleList();
@Update("UPDATE pomit_rule SET visible=0 WHERE id = #{id}")
Integer deleteRule(@Param("id") Integer id);
@Update("UPDATE pomit_rule SET rule= #{rule} WHERE id = #{id}")
Integer updateRule(@Param("id") Integer id,@Param("rule") String rule);
}
|
6.4 SpringBoot 相关实体
ApiApplication:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package cn.pomit.skill.groovy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
@ImportResource(locations={"classpath:spring-groovy.xml"})
public class ApiApplication {
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
}
|
6.5 测试 web
WebRest:
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
|
package cn.pomit.skill.groovy.web;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.pomit.skill.groovy.rule.IRule;
import cn.pomit.skill.groovy.rule.RuleFactory;
import cn.pomit.skill.groovy.rule.db.RulesDao;
@RestController
@RequestMapping("/")
public class WebRest {
@Autowired
RulesDao rulesDao;
@Resource(name = "springGroovyRule")
IRule springGroovyRule;
@RequestMapping(value = "/test")
public String test() throws Exception {
List<IRule> list = RuleFactory.getInstance(rulesDao).getRuleList();
list.add(springGroovyRule);
for (IRule item : list) {
item.printInfo();
}
return "0000";
}
}
|
快速构建项目
Spring 项目快速开发工具:
一键快速构建 Spring 项目工具
一键快速构建 SpringBoot 项目工具
一键快速构建 SpringCloud 项目工具
一站式 Springboot 项目生成
Mysql 一键生成 Mybatis 注解 Mapper
Spring 组件化构建
SpringBoot 组件化构建
SpringCloud 服务化构建
喜欢这篇文章么,喜欢就加入我们一起讨论 SpringBoot 使用吧!