JAVA 代码的热部署,动态语言 Groovy 使用的三种方式

本文由 简悦 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 使用吧!