首页 > 编程语言 >使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!

时间:2024-09-18 21:23:48浏览次数:11  
标签:码出 String void CRUD Callback bean new 回调 public

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_数据

整体回调机制流程如下图所示:

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_sed_02

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_数据_03

1.2 回调的结构

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_数据_04

1.3 回调的作用

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_System_05

2.回调的实现方式

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_数据_06

2.1 通过接口实现回调

java可以通过定义一个回调接口,包含需要回调的方法,然后在业务逻辑中通过传递接口的实现类,触发回调。示例如下:

// 1. 定义回调接口
interface Callback {
    void onComplete(String result);
}

// 2. 定义业务逻辑类,接受回调
class Task {
    public void execute(Callback callback) {
        // 模拟一些业务逻辑处理
        String result = "Task Completed!";
        // 回调通知调用方
        callback.onComplete(result);
    }
}

// 3. 使用回调
public class CallBackTest {
    public static void main(String[] args) {
        Task task = new Task();

        // 通过匿名类实现回调
        task.execute(new Callback() {
            @Override
            public void onComplete(String result) {
                System.out.println("Callback received: " + result);
            }
        });
    }
}

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_System_07


2.2 通过Lambda表达式实现回调(Java 8+)

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_数据_08

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_sed_09

2.3 异步回调

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_System_10

import java.util.concurrent.CompletableFuture;

interface Callback {
    void onComplete(String result);
}

class AsyncTask {
    public void executeAsync(Callback callback) {
        CompletableFuture.supplyAsync(() -> {
            // 模拟耗时任务
            try { Thread.sleep(2000); } catch (InterruptedException e) { }
            return "Task Completed!";
        }).thenAccept(callback::onComplete);  // 任务完成后回调
    }
}

public class CallBackTest {
    public static void main(String[] args) {
        AsyncTask task = new AsyncTask();
        
        // 异步回调,任务完成后调用
        task.executeAsync(result -> System.out.println("Async callback received: " + result));
        
        System.out.println("Main thread continues executing...");
    }
}

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_sed_11

2.4 支付异步回调

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_sed_12

@Controller
@RequestMapping("/api/mall/pay")
@Api("支付相关接口")
@Slf4j
public class PayController {
    @Resource
    private PayService payService;
    @Resource
    private WxPayConfig  wxPayConfig;

    @GetMapping(value="/create", produces = "text/html")
    @ApiOperation("发起支付")
    public ModelAndView create(@RequestParam("orderNo") String orderNo,
                               @RequestParam("payType") Integer payType) {
        // 发起支付,会传递回调通知接口地址
        PayResponse response = payService.create(orderNo, payType);
        // 支付方式不同,渲染就不同, WXPAY_NATIVE使用codeUrl,  ALIPAY_PC使用body
        Map<String, String> map = new HashMap<>();
        if (Objects.equals(payType, PayConstant.TYPE_WXPAY)) {
            map.put("codeUrl", response.getCodeUrl());
            map.put("orderNo", orderNo);
            map.put("returnUrl", wxPayConfig.getReturnUrl());
            return new ModelAndView("wxView", map);
        }else if (Objects.equals(payType, PayConstant.TYPE_ALIPAY)) {
            map.put("body", response.getBody());
            return new ModelAndView("alipayView", map);
        }
        throw new RuntimeException("暂不支持的支付类型");
    }

    @PostMapping("/notify")
    @ApiOperation("异步通知")
    @ResponseBody
    public String asyncNotify(@RequestBody String notifyData) {
        return payService.asyncNotify(notifyData);
    }
 }

配置文件:

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_System_13

可以看到在发起支付的时候把回调的通知接口地址给到支付平台,支付平台通过回调通知接口告知调用方支付成功与否,这种方式也是回调思想的体现。

3.回调机制在主流框架中的应用

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_sed_14

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_System_15

跟随代码进入到实现类AbstractBeanFactory,实现逻辑代码如下:

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_数据_16

#doGetBean()就是获取bean的核心逻辑所在(ps: Spring框架里面do开头的都是真正实现逻辑的地方),下面是单例bean的创建核心逻辑:

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_sed_17

注意,注意,注意,这里的#getSingleton()方法调用使用了函数式参数传递,典型的函数式编程,这就意味着后续会来执行回调方法#createBean()

接下来看看#getSingleton():

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(beanName, "Bean name must not be null");
   // 对单例缓存对象map加锁
   synchronized (this.singletonObjects) {
      // 从缓存中获取
      Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null) {
         .....
         // 单例bean创建前置处理,标记当前bean在创建中
         beforeSingletonCreation(beanName);
         boolean newSingleton = false;
         boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
         if (recordSuppressedExceptions) {
            this.suppressedExceptions = new LinkedHashSet<>();
         }
         try {
            // 初始化 bean
            // 这个过程其实是调用 createBean() 方法
            // singletonFactory由回调方法产生
            singletonObject = singletonFactory.getObject();
            newSingleton = true;
         }
         .....
         finally {
            if (recordSuppressedExceptions) {
               this.suppressedExceptions = null;
            }
            // 单例bean创建后置处理,标记当前bean不在创建中
            afterSingletonCreation(beanName);
         }
         // 加入缓存
         if (newSingleton) {
            addSingleton(beanName, singletonObject);
         }
      }
      return singletonObject;
   }
}

你会发现该方法的第二个参数ObjectFactory是一个函数式接口,执行到代码singletonObject = singletonFactory.getObject()的时候会回调执行#createBean()来创建bean对象。

这就是Spring框架bean工厂容器核心逻辑生成bean的写法,可见回调和函数式编程的实用性。

4.回调机制在业务系统开发中实战

做过金融行业的大概都知道,这么多银行和金融平台的信贷数据格式都是不一样的,这时候加入有一个系统需要对接各个银行或者金融平台的数据就很麻烦了,总不能一家银行一家银行地去硬编码实现吧!!!

数据对接的流程大体是固定的:通过调银行接口或者访问银行数据文件获取源数据,然后进行清洗转换成业务系统需要的格式数据,导入业务系统,记录日志

这里变换的就是数据转换,我们将它抽取出来通过函数式编程进行封装,然后使用 Lambda 来简化代码使用,从而完美应对不同银行的数据转换,做到灵活不失优雅,下面是代码封装和简单示例:

// 定义转换数据的函数式接口
@FunctionalInterface
public interface DataTransformer<T, R> {
    R transform(T input);
}

// 逻辑处理类
public class DataProcessor<T, R> {
    public R processData(T data, DataTransformer<T, R> transformer) {
        return transformer.transform(data);
    }
}

// 使用场景
public class DataProcessor<T, R> {
    public static <T, R> R processData(T data, DataTransformer<T, R> transformer) {
        return transformer.transform(data);
    }

    public static void main(String[] args) {
        // 简单示例1
        Integer length = DataProcessor.processData("Hello", String::length);
        System.out.println(length); // 输出 5
       
        // 示例2:从person转换为student
        Person person = new Person();
        person.setName("zhang san");
        person.setAge(18);
        Student student = DataProcessor.processData(person, DataProcessor::convertToStudent);
        System.out.println(student);
    }

    private static Student convertToStudent(Person person) {
        Student student = new Student();
        student.setName(person.getName());
        student.setAge(person.getAge());
        return student;
    }
}

5.总结

使用回调机制Callback和函数式编程码出优雅结构化代码!拒绝一直写CRUD!!!_数据_18


最后说一句(求关注!别白嫖!)

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记  就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!






标签:码出,String,void,CRUD,Callback,bean,new,回调,public
From: https://blog.51cto.com/u_16502039/12048683

相关文章

  • WEB-API+.NET+CRUD+SSMS(VS2022)
    1.使用VS2022创建一个web-api项目,根目录如下:其中TestCode.cs写model实体类,Controller编写控制器2.实体类Item,编写对应的属性点击查看代码publicclassItem{[Required]publicintId{get;set;}[Required]publicintFieldID{get;set;}......
  • java程序员入行科目一之CRUD轻松入门教程(一)
    之前在操作MySQL的时候,都是采用Navicat,或者cmd黑窗口。无论使用什么方式和MySQL交互,大致步骤是这样的建立连接,需要输入用户名和密码编写SQL语句,和数据库进行交互这个连接方式不会变,但是现在需要基于Java语言去和MySQL进行一波在实际开发中,当用户要对数据进行一些......
  • 全网最适合入门的面向对象编程教程:47 Python函数方法与接口-回调函数Callback
    全网最适合入门的面向对象编程教程:47Python函数方法与接口-回调函数Callback摘要:回调函数是编程中一种非常常见的模式,用于将函数作为参数传递给其他函数或方法。这种模式在Python中广泛应用于事件处理、异步编程、函数式编程等场景。原文链接:FreakStudio的博客往......
  • DeAdmin 不仅仅是可以一键完成crud操作的后台管理系统
    在后台管理系统中,crud是常见的需求,即使每次都是cv操作都是一个不小的工作量。在DeAdmin中内置了一键操作的功能,完成后修改部分模型属性,再调整下列表及表单的展示信息即可快速完成。功能介绍后端1.首先会创建文章和分类的模型记录,包含了文字模块的常用字段信息2.分别创建......
  • React 中 useCallback 钩子的依赖项问题
    报错:The'getMergeMap'functionmakesthedependenciesofuseCallbackHook(atline192)changeoneveryrender.MoveitinsidetheuseCallbackcallback.Alternatively,wrapthedefinitionof'getMergeMap'initsownuseCallback()Hook.......
  • CRUD最佳实践PasteForm及项目模板的制作视频,让重复的CRUD更加简单直接[附带源码和视频
    关说不练假把式,在上一,二篇中介绍了我心目中的CRUD的样子基于之前的理念,我开发了一个命名为PasteTemplate的项目,这个项目呢后续会转化成项目模板,转化成项目模板后,后续需要开发新的项目就可以基于这个模板创建,这样就不要copy一个旧的项目,然后删删删,改改改,重命名等操作了强迫症,一......
  • Android BLE & BluetoothGattCallback.onServicesDiscovered不回调或部分回调解决
    A.如题,调用BluetoothGatt.discoverServices()返回true了,但是一直没走到onServicesDiscovered回调中,用Ble调试蓝牙助手测试了,也是一样的情况,所以应该是外设的问题,但是ios的没问题,蓝牙处理还是有差别,网上有一种方式说是延迟去多discoverServices几次,可能可以找到,尝试了一下还是不行......
  • 创建一个SpringBoot项目,实现简单的CRUD功能和分页查询
    背景本博文主要是创建了一个新的SpringBoot项目,实现基本的增删改查,分页查询,带条件的分页查询功能。是方便初学者学习后端项目的一个比较清晰明了的实践代码,读者可根据博文,从自己动手创建一个新的SpringBoot项目,到使用PostMan测试基本请求,完完全全实践一遍,写出自己的代码,或者实现......
  • 支持多种前后端组合的代码生成项目,终于不用写CRUD了
    介绍抽取若依RuoYi-Vue的代码生成,目前支持Mybatis、Mybaits-plus的后端代码生成,前端支持element-ui与vue、AntDesignofVue以及html的代码,可以自由组合导出预览,可以通过导入mysql脚本的方式来创建表进行代码生成,可以导出数据字典,后续会持续更新。功能支持mybatis、mybaits-plus的......
  • 成品短视频源码出售,如何实现大文件秒传?
    成品短视频源码出售,如何实现大文件秒传?大文件秒传逻辑梗概客户端上传文件时,先提交文件的哈希值,服务端根据哈希值查询文件是否已经上传,如果已上传,则直接返回已上传状态客户端收到已上传状态后,直接跳过上传过程优势分析提高上传效率:秒传可以提高上传效率,因为文件已经......