匿名函数托管 func-spring-boot-starter
匿名函数托管 func-spring-boot-starter
项目地址
func-spring-boot-starter开源项目地址: https://gitee.com/yiur/func-spring-boot-starter
func-web-simple开源项目地址: https://gitee.com/yiur/func-web-simple
项目搭建
项目树结构
func-web-simple
	│  pom.xml
	└─ src
      └─ main
          ├─ java
          │  └─ com
          │      └─ simple
          │          └─ web
          │              │  FuncApplication.java
          │              │
          │              ├─ callback
          │              │      DefaultCallback.java
          │              │
          │              ├─ config
          │              │      FuncLinkConfig.java
          │              │
          │              ├─ controller
          │              │      ResultController.java
          │              │
          │              ├─ func
          │              │      HttpLink.java
          │              │      OutMessage.java
          │              │
          │              └─ lambda
          │                      LambdaConfig.java
          │
          └─ resources
                  application.yml
pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.resolving.func</groupId>
    <artifactId>func-web-simple</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <!--core-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.3.9</version>
        </dependency>
        <!--func-->
        <dependency>
            <groupId>func.spring.boot</groupId>
            <artifactId>func-spring-boot-starter</artifactId>
            <version>1.0.4.RELEASE</version>
        </dependency>
        <!--boot-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.3.12.RELEASE</version>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.12.RELEASE</version>
        </dependency>
        <!--test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.3.12.RELEASE</version>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>2.3.12.RELEASE</version>
            <optional>true</optional>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
yaml
server:
  port: 7000
  tomcat:
    uri-encoding: utf-8
  servlet:
    encoding:
      charset: utf-8
spring:
  application:
    name: func-web-simple
  devtools:
    restart:
      enabled: true
      additional-paths: src/main/java
      exclude: WEB-INF/**
func:
  link:
    # 默认代理模式
    singleton: true
    # 默认开启lambda模式
    lambda: true
    # 默认的callback回调函数类
    call-back: com.simple.web.callback.DefaultCallback
    # logger 配置
    logger:
      # 默认false 不输出日志
      enable-log: false
      # 如果FuncLambda配置了turn-on-log为true的话且funcLink中没有对应的log功能,输出已经日志
      message: "call method --> ?{methodName}(?{parameterSource})"
配置启动类
@EnableFuncLambda("com.simple.web.lambda")
扫描com.simple.web.lambda包下的接口
@EnableWebMvc
@EnableFuncLambda("com.simple.web.lambda")
@SpringBootApplication
public class FuncApplication {
    public static void main(String[] args) {
        SpringApplication.run(FuncApplication.class, args);
    }
}
配置匿名函数链接
FuncFactory 获取匿名函数链接生产工厂
@Configuration
public class FuncLinkConfig {
    @Autowired
    public FuncFactory funcFactory;
}
生成匿名函数链接
@Bean
public FuncLink funcLink() {
    return funcFactory.build();
}
配置匿名函数链接生命状态
setObject(key, lambda表达式) 链式编程
- key: (Bean name 或 refs) + : + FuncToolEnum类定义的可用状态 - 小工具: - FuncToolKey<String, FuncToolType>用于setObject中的key
- public FuncToolKey<String, FuncToolType> funcToolKey =
 (bean, toolEnum) -> FuncString.format(FuncStringType.FUNC_LINK_FORMAT, bean, toolEnum);
 
- funcFactory.build()
 .<FuncLogger>setObject(funcToolKey.splice("link-log", FuncToolType.LIFE_START_KEY), set -> "link-log => ?{methodName}");
 
 
- lambda: setObject 是一个泛型方法,所以前面的泛型用于约束后面的lambda表达式 
@Bean
public FuncLink funcLink() {
    return funcFactory.build()
        .<FuncLogger>setObject("link-log:log", set -> "link-log => ?{methodName}");
}
@Bean
public FuncLink funcLink() {
    return funcFactory.build()
        .<FuncCallbackThen<String, String>>setObject("outMessage:callback-then", data -> FuncString.format("[ { \"key\": \"replace\", \"value\": \"?\" } ]", data));
}
全配置
@Configuration
public class FuncLinkConfig {
    @Autowired
    public FuncFactory funcFactory;
    /**
     * tool key lambda
     */
    public FuncToolKey<String, FuncToolType> funcToolKey = (bean, toolEnum) -> FuncString.format(FuncStringType.FUNC_LINK_FORMAT, bean, toolEnum);
    @Bean
    public FuncLink funcLink() {
        FuncLink build = funcFactory.build()
                .<FuncLogger>setObject("link-log:log", set -> "link-log => ?{methodName}");
        setOutMessage(build);
        return build;
    }
    private void setOutMessage(FuncLink funcLink) {
        funcLink // OutMessage State of life
                .<FuncLifeStart>setObject(funcToolKey.splice("outMessage", FuncToolType.LIFE_START_KEY), data -> {
                    if (data.size() > 1) {
                        data.put("message", FuncString.format("start() -> { ? }", data.get("message")));
                    }
                    return data;
                })
                .<FuncCallbackThen<String, String>>setObject("outMessage:callback-then", data -> FuncString.format("[ { \"key\": \"replace\", \"value\": \"?\" } ]", data))
                .<FuncCallbackError<String>>setObject("outMessage:callback-error", error -> error instanceof InvocationTargetException ? ((InvocationTargetException) error).getTargetException().getMessage() : error.getMessage())
                .<FuncLifeEnd<String, String>>setObject("outMessage:life-end", data -> data);
    }
}
匿名函数链接的用法
life 匿名函数执行前与执行完毕
life 匿名函数执行前与执行完毕生命状态 不推荐
@Bean
public FuncLink funcLink() {
    return funcFactory.build()
        .<FuncLife<String, String>>setObject("outMessage:life", new FuncLife<String, String>() {
            @Override
            public Map<String, Object> start(Map<String, Object> map) {
                return map;
            }
            @Override
            public String end(String data) {
                return data;
            }
        });
}
life-start 匿名函数执行前生命状态 推荐
@Bean
public FuncLink funcLink() {
    return funcFactory.build()
        .<FuncLifeStart>setObject(funcToolKey.splice("outMessage:life-start", FuncToolType.LIFE_START_KEY), data -> {
            if (data.size() > 1) {
                data.put("message", FuncString.format("start() -> { ? }", data.get("message")));
            }
            return data;
        })
}
life-end 匿名函数执行完毕生命状态 推荐
@Bean
public FuncLink funcLink() {
    return funcFactory.build()
        .<FuncLifeEnd<String, String>>setObject("outMessage:life-end", data -> data);
}
life-start + life-end 组合 推荐
@Bean
public FuncLink funcLink() {
    return funcFactory.build()
        .<FuncLifeStart>setObject(funcToolKey.splice("outMessage:life-start", FuncToolType.LIFE_START_KEY), data -> {
            if (data.size() > 1) {
                data.put("message", FuncString.format("start() -> { ? }", data.get("message")));
            }
            return data;
        })
        .<FuncLifeEnd<String, String>>setObject("outMessage:life-end", data -> data);
}
callback 匿名函数执行成功或失败,回调函数
callback 匿名函数执行成功或失败回调 不推荐
@Bean
public FuncLink funcLink() {
    return funcFactory.build()
        .<FuncCallback<String, String>>setObject("outMessage:callback", new FuncCallback<String, String>() {
            @Override
            public String then(String s) {
                return s;
            }
            @Override
            public String error(Exception e) {
                return e.getMessage();
            }
        });
}
callback-then 匿名函数执行成功回调 推荐
@Bean
public FuncLink funcLink() {
    return funcFactory.build()
        .<FuncCallbackThen<String, String>>setObject("outMessage:callback-then", data -> FuncString.format("[ { \"key\": \"replace\", \"value\": \"?\" } ]", data));
}
callback-error 匿名函数执行失败回调 推荐
@Bean
public FuncLink funcLink() {
    return funcFactory.build()
        .<FuncCallbackError<String>>setObject("outMessage:callback-error", error -> error instanceof InvocationTargetException ? ((InvocationTargetException) error).getTargetException().getMessage() : error.getMessage());
}
logger 匿名函数执行前输出信息
log 匿名函数执行前输出信息 1.0.4使用
@Bean
public FuncLink funcLink() {
    return funcFactory.build()
        .<FuncLogger>setObject("link-log:log", set -> "link-log => ?{methodName}");
}
匿名函数配置
编写匿名函数托管的接口
- OutMessage 
- @Component
 public interface OutMessage { /**
 * 输出
 * @param message text
 * @param args replace
 * @return string
 */
 String out(String message, String... args); /**
 * 输出
 * @param message text
 * @return string
 */
 String out(String message); }
 
- HttpLink 
- @Component
 public interface HttpLink { /**
 * 返回关联
 * @return object
 */
 Object link(); }
 
匿名函数写法
@FuncConfiguration 匿名函数配置注解
@FuncConfiguration
public class LambdaConfig {
}
@FuncLambda 声明为匿名函数
- 提供给匿名函数额外功能的注解为
- @FuncParameter: 匿名函数链接想调用到函数参数变量,必须使用
- value: 变量名,匿名函数链接收到Map<K, V>键值对
 
- @EnableLog: 匿名函数调用前输出函数信息
- @CallbackClass: 匿名函数绑定的回调函数类 不推荐
 
- @FuncParameter: 匿名函数链接想调用到函数参数变量,必须使用
- @FuncLambda属性解析
- classFile: 匿名函数托管的接口
- refs: 声明一个ref,提供给匿名函数链接使用
- bean: 匿名函数托管的接口,自动装配对象别名,可以不用默认为首字母缩写的类名
 
- 特性:
- 匿名函数托管的接口方法,返回值可以不一致callback成功回调接收的值就是匿名函数返回的值,但回调函数返回的值必须与接口函数返回的值一致
- refs可以引用多个ref包括Bean,进行统一配置减少耦合度
 
@FuncLambda(classFile = OutMessage.class, refs = { "link-log" })
public String out(@FuncParameter("message") String message, @FuncParameter("args") String... args) {
    return FuncString.format(message, args);
}
全配置
@FuncConfiguration
public class LambdaConfig {
    @EnableLog
    @FuncLambda(classFile = OutMessage.class, refs = { "link-log" })
    public String out(@FuncParameter("message") String message, @FuncParameter("args") String... args) {
        return FuncString.format(message, args);
    }
    @EnableLog
    @FuncLambda(classFile = OutMessage.class, refs = { "link-log" })
    public String out(@FuncParameter("message") String message) {
        return FuncString.format(message + "/no");
    }
    @EnableLog
    @CallbackClass(DefaultCallback.class)
    @FuncLambda(classFile = HttpLink.class, refs = { "link-log" })
    public Map<String, String> link() {
        Map<String, String> map = new HashMap<>(10);
        map.put("百度", "http://www.baidu.com");
        map.put("BiliBili", "http://www.bilibili.com");
        map.put("localhost", "http://localhost:7000");
        map.put("博客", "https://www.cnblogs.com/yiur-bgy/p/15521428.html");
        return map;
    }
}
WEB 测试
@RestController 编写api
@RestController
public class ResultController {
    @Autowired
    public OutMessage outMessage;
    @Autowired
    public HttpLink httpLink;
    @RequestMapping("/replace")
    public String replace(String message, String... args) {
        return outMessage.out(message, args);
    }
    @RequestMapping("/replace/no")
    public String replace(String message) {
        return outMessage.out(message);
    }
    @RequestMapping("/hello/{message}")
    public String hello(@PathVariable("message") String message) {
        return outMessage.out(message);
    }
    @RequestMapping("/httpLink")
    public Object httpLink() {
        return httpLink.link();
    }
}
测试 api
- 测试成功回调
- [http://localhost:7000/replace?message=hello ?&args=func-spring-boot-starter](http://localhost:7000/replace?message=hello ?&args=func-spring-boot-starter)
- 返回:[ { "key": "replace", "value": "hello func-spring-boot-starter" } ]
 
- 测试失败回调
- [http://localhost:7000/replace?message=hello??&args=func-spring-boot-starter](http://localhost:7000/replace?message=hello ??&args=func-spring-boot-starter)
- 返回:The current parameter is inconsistent with the number of matching characters
 
- 其他测试
- http://localhost:7000/httpLink
- 返回:{"localhost":"http://localhost:7000","博客":"https://www.cnblogs.com/yiur-bgy/p/15521428.html","百度":"http://www.baidu.com","BiliBili":"http://www.bilibili.com"}
- http://localhost:7000/replace/no?message=hello
- 返回:[ { "key": "replace", "value": "hello/no" } ]
 
匿名函数托管 func-spring-boot-starter的更多相关文章
- func-spring-boot-starter 匿名函数托管
		func-spring-boot-starter 匿名函数托管 GitHub项目路径: https://github.com/yiurhub/func-spring-boot-starter Gite ... 
- Spring Boot (一): Spring Boot starter自定义
		前些日子在公司接触了spring boot和spring cloud,有感于其大大简化了spring的配置过程,十分方便使用者快速构建项目,而且拥有丰富的starter供开发者使用.但是由于其自动化配 ... 
- Spring Boot Starter 介绍
		http://www.baeldung.com/spring-boot-starters 作者:baeldung 译者:http://oopsguy.com 1.概述 依赖管理是任何复杂项目的关键部分 ... 
- spring -boot s-tarter 详解
		Starter POMs是可以包含到应用中的一个方便的依赖关系描述符集合.你可以获取所有Spring及相关技术的一站式服务,而不需要翻阅示例代码,拷贝粘贴大量的依赖描述符.例如,如果你想使用Sprin ... 
- SpringBoot 之Spring Boot Starter依赖包及作用
		Spring Boot 之Spring Boot Starter依赖包及作用 spring-boot-starter 这是Spring Boot的核心启动器,包含了自动配置.日志和YAML. spri ... 
- Spring boot starter pom的依赖关系说明
		Spring Boot 通过starter依赖为项目的依赖管理提供帮助.starter依赖起始就是特殊的maven依赖,利用了传递依赖解析,把常用库聚合在一起,组成了几个为特定功能而定制的依赖. sp ... 
- Spring Boot Starter列表
		转自:http://blog.sina.com.cn/s/blog_798f713f0102wiy5.html Spring Boot Starter 基本的一共有43种,具体如下: 1)spring ... 
- 创建自己的Spring Boot Starter
		抽取通用模块作为项目的一个spring boot starter.可参照mybatis的写法. IDEA创建Empty Project并添加如下2个module,一个基本maven模块,另一个引入sp ... 
- 自己写spring boot starter
		自己写spring boot starter 学习了:<spring boot实战>汪云飞著 6.5.4节 pom.xml <project xmlns="http://m ... 
随机推荐
- nodejs+koa+uniapp实现微信小程序登陆获取用户手机号及openId
			nodejs+koa+uniapp实现微信小程序登陆获取用户手机号及openId 前言: 我准备用nodejs+koa+uniapp实现一款餐饮点单小程序,以及nodejs+koa+vue实现后端管理 ... 
- CF1494A ABC String 题解
			Content 给定 \(T\) 个仅包含大写字母 A,B,C 的字符串 \(s\).问你是否能够通过将每个 A,B,C 换成 (,) 中的一个(同一个字母必须要换成同一个字符),使得最后得到的括号序 ... 
- href超级链接里加上javascript代码的,还有target问题
			href超级链接里加上javascript代码的,还有target问题 得把target="_blank"去掉才好用,在google浏览器有这个也没事,但是在Ie里有这个就不行了 
- c++设计模式概述之访问者
			代码写的不够规范,目的是为了缩短篇幅,实际中请注意. 参看: http://c.biancheng.net/view/1397.html 1.概述 类比生活中的场景,购物商场中的商品.顾客.收营员.商 ... 
- 【LeetCode】1417. 重新格式化字符串 Reformat The String
			作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 栈 日期 题目地址:https://leetcode- ... 
- 【LeetCode】457. Circular Array Loop 环形数组是否存在循环 解题报告(Python)
			作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题思路 快慢指针 代码 日期 题目地址:https://le ... 
- 【LeetCode】991. Broken Calculator 解题报告(Python)
			作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ... 
- 【LeetCode】52. N-Queens II 解题报告(Python & C+)
			作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 全排列函数 回溯法 日期 题目地址:https:// ... 
- Adversarial Training with Rectified Rejection
			目录 概 主要内容 rejection 实际使用 代码 Pang T., Zhang H., He D., Dong Y., Su H., Chen W., Zhu J., Liu T. Advers ... 
- <学习opencv>绘画和注释
			/*=========================================================================*/ // 绘画 和 注释 /*========= ... 
