func-spring-boot-starter 匿名函式託管

Yiur發表於2022-03-31

func-spring-boot-starter 匿名函式託管

GitHub專案路徑:

https://github.com/yiurhub/func-spring-boot-starter

Gitee專案路徑:

https://gitee.com/yiur/func-spring-boot-starter

使用注意事項

推薦版本:

  1. spring-boot-starter 2.6.x

設計原理

匿名函式特性

匿名函式連結配置

Yaml

func-link:
    # 預設代理模式
    singleton: true
    # 預設開啟lambda模式
    lambda: true
    # 預設的callback回撥函式類
    call-back: org.func.spring.boot.component.callback.SimpleFuncCallback
    # logger 配置
    logger:
      # 預設false 不輸出日誌
      enable-log: false
      # 預設輸出日誌資訊 ${取當前匿名函式的公開資訊}
      message: "call method --> ${methodName}(${parameterSource})"
      # 日誌執行日誌格式化
      date-format: "yyyy-MM-dd HH:mm:ss"
      # 輸出日誌的檔名
      file-name: "simple"

JavaConfig

新增類註解@EnableFuncLambda

需要注入FuncLinkFactory工廠類,生產預設FuncLink連結類

新增連結的方法為setObject(key, Object) 鏈式程式設計 泛型約束 Lambda

​ key: {Spring Bean Name}?{功能連結 | 外掛}

​ object: ${功能連結類| 外掛類}

FuncLink推薦Lambda操作

詳細內容請看專案:

https://gitee.com/yiur/func-spring-boot-starter/tree/main/func-web-simple
@Configuration
@EnableFuncLambda("com.simple.web.lambda")
public class FuncLinkConfig {

    @Autowired
    public FuncLinkFactory funcLinkFactory;

    @Bean
    public FuncLink funcLink() {
        return funcLinkFactory.build()
                .<FuncLogger>setObject("logger:log", (set, log) -> "logger => ${methodName}\r\n");
    }

}

嚴格型別託管

開發推薦嚴格型別託管,有程式碼提示,開發效率更高,在Web專案中,可以託管整個Servcie

配合Mybaits,Redis等框架一起使用

1、定義介面

用於SpringBoot自動注入funcLink代理的HttpLink類

public interface HttpLink {

    Object link();

}

2、代理類代理介面方法

@FuncBean(link = "funcLink Bean Name")

新增類註解@FuncBean宣告這是一個匿名函式代理類

新增方法註解@FuncLambda宣告這是一個代理方法

如果有引數請加上引數註解@FuncParameter("引數名")

@Component
@FuncBean
public class FuncLinkHosting implements HttpLink {

    @Override
    @FuncLambda(classFile = HttpLink.class)
    public Map<String, String> link() {
        Map<String, String> map = new HashMap<>(10);
        map.put("GitHub", "https://github.com/yiurhub");
        map.put("Gitee", "https://gitee.com/yiur");
        map.put("部落格", "https://www.cnblogs.com/yiur-bgy");
        return map;
    }

}

鬆散型別託管

開發使用不推薦,後續2.x估計廢用,可讀性不高

1、定義介面

新增類註解@Component,用於SpringBoot自動注入funcLink代理的HttpLink類,SpringBoot外掛提升

@Component
public interface HttpLink {

    Object link();

}

2、代理類代理介面方法

@FuncBean(link = "funcLink Bean Name")

鬆散型別託管需要注意的事項:

  1. 代理方法返回值與介面不一樣,介面返回值必須得是Object

新增類註解@FuncBean宣告這是一個匿名函式代理類

新增方法註解@FuncLambda宣告這是一個代理方法

如果有引數請加上引數註解@FuncParameter("引數名")

@FuncBean
public class FuncLinkHosting {

    @FuncLambda(classFile = HttpLink.class)
    public Map<String, String> link() {
        Map<String, String> map = new HashMap<>(10);
        map.put("GitHub", "https://github.com/yiurhub");
        map.put("Gitee", "https://gitee.com/yiur");
        map.put("部落格", "https://www.cnblogs.com/yiur-bgy");
        return map;
    }

}

@FuncLogger

新增方法註解@FuncLogger開啟方法執行完後的輸出日誌,優先順序比配置檔案高

@FuncLogger引數
name: 生成的日誌檔名,預設為func-link

​ suffix: 生成的日誌檔案字尾名,預設為log

​ path: 生成的日誌檔案存放絕對路徑路徑,預設當前專案下的log資料夾下

@FuncBean
public class FuncLinkHosting implements HttpLink {

    @Override
    @FuncLogger
    @FuncLambda(classFile = HttpLink.class)
    public Map<String, String> link() {
        Map<String, String> map = new HashMap<>(10);
        map.put("GitHub", "https://github.com/yiurhub");
        map.put("Gitee", "https://gitee.com/yiur");
        map.put("部落格", "https://www.cnblogs.com/yiur-bgy");
        return map;
    }

}

應用

Logger 日誌功能連結,根據執行方法繫結的Bean或者ref,執行此功能

在繫結的方法中執行完後,則會輸出日誌,獲取執行的方法資訊

連結

FuncLogger

​ 功能連結為: "${Bean Name}:log"

程式碼

@Configuration
@EnableFuncLambda("com.simple.web.lambda")
public class FuncLinkConfig {

    @Autowired
    public FuncLinkFactory funcLinkFactory;

    @Bean
    public FuncLink funcLink() {
        return funcLinkFactory.build()
                .<FuncLogger>setObject("httpLink:log", (set, log) -> "logger => ${methodName}\r\n");
    }

}

@FuncCallback 註解實現

新增方法註解@FuncCallback繫結方法執行後的回撥函式

成功執行回撥: then(T result)

失敗執行回撥: error(Throwable e)

public class DefaultCallback implements FuncCallback {

    @Override
    public Object then(Object data) { return data; }

    @Override
    public Object error(Throwable error) {
        return error.getMessage();
    }

}
@FuncBean
public class FuncLinkHosting implements HttpLink {

    @Override
    @FuncCallback(DefaultCallback.class)
    @FuncLambda(classFile = HttpLink.class)
    public Map<String, String> link() {
        Map<String, String> map = new HashMap<>(10);
        map.put("GitHub", "https://github.com/yiurhub");
        map.put("Gitee", "https://gitee.com/yiur");
        map.put("部落格", "https://www.cnblogs.com/yiur-bgy");
        return map;
    }

}

應用

Callback 方法執行完回撥功能連結,根據執行方法繫結的Bean或者ref,執行此功能

在Web專案Service層中返回方法執行的結果,能做到服務熔斷操作

連結

FuncCallback<T, R>約束引數值和返回值,執行優先順序: 1

​ 功能連結為: "${Bean Name}:callback"

FuncCallbackThen<T, R>約束引數值和返回值,執行優先順序: 2

​ 功能連結為: "${Bean Name}:callback-then"

FuncCallbackError<R>約束返回值,執行優先順序: 2

​ 功能連結為: "${Bean Name}:callback-error"

程式碼

@Configuration
@EnableFuncLambda("com.simple.web.lambda")
public class FuncLinkConfig {

    @Autowired
    public FuncLinkFactory funcLinkFactory;

    @Bean("simple")
    public FuncLink funcLink() {
        return funcLinkFactory.build()
                // httpLink
                .<FuncCallback<Map<String, String>, Object>>setObject("httpLink:callback", new FuncCallback<Map<String, String>, Object>() {
                    @Override
                    public Object then(Map<String, String> result) {
                        return result;
                    }

                    @Override
                    public Object error(Throwable throwable) {
                        return throwable;
                    }
                })
                .<FuncCallbackThen<Map<String, String>, Object>>setObject("httpLink:callback-then", result -> result)
                .<FuncCallbackError<Object>>setObject("httpLink:callback-error", throwable -> throwable);
    }

}

應用

Life 方法執行前後回撥功能連結,根據執行方法繫結的Bean或者ref,執行此功能

方法執行前會先執行start方法,用來檢查引數

方法執行後會執行end方法,用來檢查返回值

連結

FuncLife<T, R>約束引數值和返回值,執行優先順序: 1

​ 功能連結為: "${Bean Name}:life"

FuncLifeStart約束引數值和返回值,執行優先順序: 2

​ 功能連結為: "${Bean Name}:life-start"

FuncLifeEnd<T, R>約束返回值,執行優先順序: 2

​ 功能連結為: "${Bean Name}:life-end"

程式碼

@Configuration
@EnableFuncLambda("com.simple.web.lambda")
public class FuncLinkConfig {

    @Autowired
    public FuncLinkFactory funcLinkFactory;

    @Bean("simple")
    public FuncLink funcLink() {
        return funcLinkFactory.build()
                // httpLink
                .<FuncLife<Object, Object>>setObject("httpLink:life", new FuncLife<Object, Object>() {
                    @Override
                    public Map<String, Object> start(Map<String, Object> args) {
                        return args;
                    }

                    @Override
                    public Object end(Object result) {
                        return result;
                    }
                })
                .<FuncLifeStart>setObject("httpLink:life-start", args -> args)
                .<FuncLifeEnd<Object, Object>>setObject("httpLink:life-end", result -> result);
    }

}

1.1.3.RELEASE 更新

func-spring-boot-starter-1.1.2.RELEASE 依賴

<!--func-->
<dependency>
    <groupId>io.github.yiurhub</groupId>
    <artifactId>func-spring-boot-starter</artifactId>
    <version>1.1.3.RELEASE</version>
</dependency>

新增匿名函式連結自定義實現功能

AbstractFuncLifePlugin

public class SimpleLifePlugin extends AbstractFuncLifePlugin {

    public SimpleLifePlugin() {
    }

    public SimpleLifePlugin(String beanName, String[] refs, FuncLink funcLink, FuncCallbackPlugin funcCallbackPlugin) {
        super(beanName, refs, funcLink, funcCallbackPlugin);
    }
    
}

AbstractFuncCallbackPlugin

public class SimpleCallbackPlugin extends AbstractFuncCallbackPlugin {

    public SimpleCallbackPlugin() {
    }

    public SimpleCallbackPlugin(String beanName, String[] refs, FuncLink funcLink, FuncProperties funcProperties, FuncLoggerPlugin funcLoggerPlugin) {
        super(beanName, refs, funcLink, funcProperties, funcLoggerPlugin);
    }
    
}

AbstractFuncLoggerPlugin

public class SimpleLoggerPlugin extends AbstractFuncLoggerPlugin {

    public SimpleLoggerPlugin() {
    }

    public SimpleLoggerPlugin(String beanName, String[] refs, FuncLink funcLink, FuncProperties funcProperties) {
        super(beanName, refs, funcLink, funcProperties);
    }
    
}
@Configuration
@EnableFuncLambda("com.simple.web.lambda")
public class FuncLinkConfig {

    @Autowired
    public FuncLinkFactory funcLinkFactory;

    @Bean("simple")
    public FuncLink funcLink() {
        return funcLinkFactory.build()
                // httpLink
                .setObject("httpLink:FuncLifePlugin", SimpleLifePlugin.class)
                .setObject("httpLink:FuncCallbackPlugin", SimpleCallbackPlugin.class)
                .setObject("httpLink:FuncLoggerPlugin", SimpleLoggerPlugin.class)
    }

}

API更改

註解更改

@FuncConfiguration 改為 @FuncBean

@EnableLog 改為 @FuncLogger

CallbackClass 改為 @FuncCallback

相關文章