千家信息网

如何用golang仿spring ioc/aop实现蓝图效果

发表于:2025-01-18 作者:千家信息网编辑
千家信息网最后更新 2025年01月18日,本篇内容主要讲解"如何用golang仿spring ioc/aop实现蓝图效果",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何用golang仿sprin
千家信息网最后更新 2025年01月18日如何用golang仿spring ioc/aop实现蓝图效果

本篇内容主要讲解"如何用golang仿spring ioc/aop实现蓝图效果",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何用golang仿spring ioc/aop实现蓝图效果"吧!

Spring

Spring的主要特性:1. 控制反转(Inversion of Control, IoC)2. 面向容器3. 面向切面(AspectOriented Programming, AOP)源码gitee地址:https://gitee.com/ioly/learning.gooop原文链接:https://my.oschina.net/ioly

目标

  • 参考spring常用注解,使用golang编写"基于注解的静态代码增强器/生成器"

    • 配置: ComponentScan,Configuration, Bean

    • Bean声明:Component, Service, Controller

    • Bean注入:Autowried

    • AOP注解:Before, After, Around, PointCut

子目标(Day 4)

  • 前两天都是在整外围接口,没说清楚到底要搞啥

  • 今天以@RestController为例,把项目目标理清楚:

    • 以gin框架为基础,描述一个订单CRUD服务

    • 以@RestController为例,手写增强前后的代码,描绘如何增强

    • 增强前,应当尽可能简洁,降低框架侵入性

    • 增强后,与框架很好的结合,把脏活累活默默干好

设计

  • OrderController: 订单服务控制器

  • OrderController_Enhanced:增强后的订单服务控制器

    • 添加SetOrderService方法以便依赖注入

    • 添加xxx_Enhanced方法,以集成到gin框架

    • 添加RegisterRestController方法,以注册到Bean容器

    • 添加init()方法,以便Bean容器引用

  • IOrderService:订单持久化服务接口

  • MockOrderService:订单持久化服务的实现,码略

  • dto/, entity/: 订单服务的实体类和数值类,码略

  • IBeanRegistry:bean注册表接口

  • IRestController:RESTFul控制器接口

  • IControllerRegistry:RESTFul控制器注册表及其默认实现

OrderController.go

订单服务控制器

package controllerimport (        "learning/gooop/spring/demo/order/dto"        "learning/gooop/spring/demo/order/entity"        "learning/gooop/spring/demo/order/service")// OrderController handles rest requests for CRUD orders// @RestController// @RequestMapping path=/ordertype OrderController struct {        @Autowried        orderService service.IOrderService}// Save create or update an order// @PostMappingfunc (me *OrderController) Save(head *entity.OrderHeadEntity, items []*entity.OrderItemEntity) error {        return me.orderService.Save(head, items)}// View gets order and order items// @GetMappingfunc (me *OrderController) View(orderID int) (error, *dto.OrderDTO) {        return me.orderService.Get(orderID)}// Query query order headers by custom conditions// @GetMappingfunc (me *OrderController) Query(customerID int, statusFlag int, dateFrom string, dateTo string, pageNO int, pageSize int) (error, []*dto.OrderHeadDTO) {        return me.orderService.Query(customerID, statusFlag, dateFrom, dateTo, pageNO, pageSize)}

OrderController_Enhanced.go

增强后的订单服务控制器

  • 添加SetOrderService方法以便依赖注入

  • 添加xxx_Enhanced方法,以集成到gin框架

  • 添加RegisterRestController方法,以注册到Bean容器

  • 添加init()方法,以便Bean容器引用

package controllerimport (        "github.com/gin-gonic/gin"        "learning/gooop/spring/demo/framework/bean/controller"        "learning/gooop/spring/demo/order/dto"        "learning/gooop/spring/demo/order/entity"        "learning/gooop/spring/demo/order/service"        "net/http")// OrderController_Enhanced handles rest requests for CRUD orders// RestController// RequestMapping path=/ordertype OrderController_Enhanced struct {        // Autowired        orderService service.IOrderService}// SetOrderService is auto generated setter method for injecting service.IOrderService into me.orderServicefunc (me *OrderController_Enhanced) SetOrderService(it interface{}) {        me.orderService = it.(service.IOrderService)}// Save create or update an order// PostMappingfunc (me *OrderController_Enhanced) Save(head *entity.OrderHeadEntity, items []*entity.OrderItemEntity) error {        return me.orderService.Save(head, items)}// OrderController_Save_ParamsDTO is auto generated struct for wrapping parameters of OrderController.Savetype OrderController_Save_ParamsDTO struct {        Order *entity.OrderHeadEntity        Items []*entity.OrderItemEntity}// View_Enhanced is the enhanced version of Savefunc (me *OrderController_Enhanced) Save_Enhanced(c *gin.Context) {        r := new(OrderController_Save_ParamsDTO)        e := c.BindJSON(r)        if e != nil {                c.JSON(http.StatusBadRequest, gin.H{"ok": false, "error": e.Error()})                return        }        e = me.Save(r.Order, r.Items)        if e != nil {                c.JSON(http.StatusInternalServerError, gin.H{"ok": false, "error": e.Error()})                return        }        c.JSON(http.StatusOK, gin.H{"ok": true})}// View gets order and order items// GetMappingfunc (me *OrderController_Enhanced) View(orderID int) (error, *dto.OrderDTO) {        return me.orderService.Get(orderID)}// View_Enhanced is the enhanced version of Viewfunc (me *OrderController_Enhanced) View_Enhanced(c *gin.Context) {        id := c.GetInt("id")        e, d := me.View(id)        if e != nil {                c.JSON(http.StatusInternalServerError, gin.H{"ok": false, "error": e.Error()})        }        c.JSON(http.StatusOK, d)}// Query query order headers by custom conditions// GetMappingfunc (me *OrderController_Enhanced) Query(customerID int, statusFlag int, dateFrom string, dateTo string, pageNO int, pageSize int) (error, []*dto.OrderHeadDTO) {        return me.orderService.Query(customerID, statusFlag, dateFrom, dateTo, pageNO, pageSize)}// OrderController_Query_ParamsDTO is auto generated struct for wrapping parameters of PagedQuerytype OrderController_Query_ParamsDTO struct {        CustomerID int        StatusFlag int        DateFrom   string        DateTO     string        PageNO     int        PageSize   int}// Query_Enhanced is the enhanced version of PagedQueryfunc (me *OrderController_Enhanced) Query_Enhanced(c *gin.Context) {        r := new(OrderController_Query_ParamsDTO)        e := c.Bind(r)        if e != nil {                c.JSON(http.StatusBadRequest, gin.H{"ok": false, "error": e.Error()})                return        }        e, d := me.Query(r.CustomerID, r.StatusFlag, r.DateFrom, r.DateTO, r.PageNO, r.PageSize)        if e != nil {                c.JSON(http.StatusInternalServerError, gin.H{"ok": false, "error": e.Error()})                return        }        c.JSON(http.StatusOK, gin.H{"ok": true, "data": d})}// RegisterRestController is auto generated to implements controller.IRestController interfacefunc (me *OrderController_Enhanced) RegisterRestController(r *gin.Engine) {        r.POST("/order/save", me.Save_Enhanced)        r.GET("/order/view", me.View_Enhanced)        r.GET("/order/query", me.Query_Enhanced)}// init is auto generated to register OrderController_Enhanced into controller.ControllerRegistryfunc init() {        it := new(OrderController_Enhanced)        controller.ControllerRegistry.Register(it)}

IOrderService.go

订单持久化服务接口

package serviceimport (        "learning/gooop/spring/demo/order/dto"        "learning/gooop/spring/demo/order/entity")type IOrderService interface {        Save(head *entity.OrderHeadEntity, items []*entity.OrderItemEntity) error        Get(orderID int) (error, *dto.OrderDTO)        Query(customerID int, statusFlag int, dateFrom string, dateTo string, pageNO int, pageSize int) (error, []*dto.OrderHeadDTO)}

IBeanRegistry.go

bean注册表接口

package beantype IBeanRegistry interface {        All() []interface{}}

IRestController.go

RESTFul控制器接口

package controllerimport "github.com/gin-gonic/gin"type IRestController interface {        RegisterRestController(r *gin.Engine)}

IControllerRegistry.go

RESTFul控制器注册表及其默认实现

package controllerimport (        "github.com/gin-gonic/gin"        "learning/gooop/spring/demo/framework/bean"        "sync")type IControllerRegistry interface {        bean.IBeanRegistry        Register(it IRestController)        Apply(r *gin.Engine)}type tDefaultControllerRegistry struct {        rwmutex *sync.RWMutex        items   []IRestController}func (me *tDefaultControllerRegistry) All() []interface{} {        me.rwmutex.RLock()        defer me.rwmutex.RUnlock()        all := make([]interface{}, len(me.items))        for i, it := range me.items {                all[i] = it        }        return all}func (me *tDefaultControllerRegistry) Register(it IRestController) {        me.rwmutex.Lock()        defer me.rwmutex.Unlock()        me.items = append(me.items, it)}func (me *tDefaultControllerRegistry) Apply(r *gin.Engine) {        me.rwmutex.RLock()        defer me.rwmutex.RLock()        for _, it := range me.items {                it.RegisterRestController(r)        }}func newDefaultControllerRegistry() IControllerRegistry {        return &tDefaultControllerRegistry{                new(sync.RWMutex),                []IRestController{},        }}var ControllerRegistry = newDefaultControllerRegistry()

到此,相信大家对"如何用golang仿spring ioc/aop实现蓝图效果"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0