一个C#开发编写Java框架的心路历程(一)

简介: 本文主要描述我作为一个C#开发者,在编写Java框架时的一些心得感悟。因为我是C#的开发者,所以,在编写Java框架时,或多或少会带入一些C#的固有观念,所以,这也是一个C#观念与Java观念碰撞的一个框架。02

01

  前言    


本文主要描述我作为一个C#开发者,在编写Java框架时的一些心得感悟。

因为我是C#的开发者,所以,在编写Java框架时,或多或少会带入一些C#的固有观念,所以,这也是一个C#观念与Java观念碰撞的一个框架。


02

Java与C#的一些小区别


反射:
在C#中反射可以只用类名反射,Java中必须是完全限定名;在C#中反射是在内存或DLL类库中查找文件,一个方法就搞定了,在Java中则需要手写扫描文件夹或扫描Jar包的文件,然后找到名称一样的文件再反射。命名空间:在C#中命名空间+类名是类,在Java中命名空间+类名是命名空间,即,Java中会出现Import某一个类的完全限定名。

for循环:在C#中有for循环和foreach循环,在Java中for循环支持foreach模式,如:

for(Kiba_User u : ul)



03

Java之Spring脉络简介

对于C#开发而言,Java开发的脉络实在是清奇的不得了,因为Java使用了大量的依赖注入和控制反转,从而让它的结构非常的反人类。但这也是有一定的历史原因的,因为它的开源语言,所以,大家在扩展框架时,都等于在做二次开发,因为依赖注入和控制反转是二次开发最好的模式,所以,它就越积累越多,最后它彻底的变成了控制反转的完全体,也就说,它在反人类的路上一去不反复了(注意,Java开发者通常认为他们才是正常开发,为了避免冲突,请不要当面说他们反人类)。

下面我使用C#的描述的方式来勾勒一下Java之Spring的脉络,如下图:


20.png


因为,java很多对象都是用注解标识,然后在解析时实例化的,为了统一代码,所以,java形成了一种新的标准,实例化对象都用注解。


04

准备工作

本框架因为是学习框架,所以有些设计会常规的java不同,框架中不会使用类似@Service这样的注解,但会使用@Data,因为Java中写属性确实有点费劲。

下面我们进行准备工作。

开发工具:IDEA。

项目框架:Spring。

JDK:1.8。

ORM:Mybatis。

首先我们创建一个Spring的Web项目——k_framework,这里只做WebApi的介绍。

然后我们编辑Pom.xml引入所需的Jar包,依赖如下:


 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc8</artifactId>
            <version>12.1.0.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency> 
  </dependencies>


PS:这里使用的数据库是Oracle,然后我们的包管理工具Maven居然不能下载oracle的jar包。。。所以我们只能去官网下载,然后在CMD里,使用Maven提供的命令安装这个jar包。

然后结合Java的Spring框架的特质,设计一个项目结构,并在包k_framework下面实现。

项目结构设计如下:

22.png


系统约定如下:

DTO类名后缀需为Command和Query,标记命令用于处理的业务为增删改、或查询。

DTO类必须在同一包下,且类名不得重复。

前台页面必须定义一个同名的,属性一致的Javascript的DTO类。

业务域类名=DTO的类名+Handler。

业务域类使用Excute函数处理业务。

关于结构

关于配置类与工具类:设计时,我们尽量让控制器使用配置类,让业务域使用工具类。当然,特殊情况下也可以一起使用。

关于业务域:Java中通常使用Service来命名处理业务的包,但因为有时候我们会把部署的Web项目也称为服务,比如微服务项目里每个WebApi都是服务,所以,这里为了避免歧义,使用域来命名处理业务的包。

关于数据库映射:在C#项目里,我们是先建立映射,然后用仓储通过泛型来处理数据库数据,但在Mybatis里,需要使用映射的对象来处理数据库数据,即,每处理一个表,就要建立一个这个表的映射对象实例。

关于数据库实体和数据库扩展实体:顾名思义,数据库扩展实体是数据库实体的扩展,可以的简单把它理解为视图实体。

注:在C#中,图中的这些大类的结构,通常会搞一个类库项目来单独处理,因为在C#中共享使用一个启动项目的配置文件,并且C#的项目文件在VS中管理起来非常简单便捷,但Java的项目文件pom.xml并不是特别灵活,所以,这里我们就在一个项目里做结构。

整体结构图如下:

23.png


05

代码实现——逻辑

工具类

首先,我们先建立工具类。

因为是简单实现,所以我们只建立三个最基础的工具类,ReflexHelper、StringHelper、FileHelper。(在java中通常工具类命名会以util结尾,这里我保持c#的命名风格)

控制器

定义CommandController类,Get和Post两个函数,用于处理全部的Get和Post请求。函数接受两个参数,命令类型和命令的Json内容,然后通过命令类型发射调用业务域。

代码如下:

@RestController
@RequestMapping("/Command")
public class CommandController
{ 
    @Autowired
    private SqlSession sqlSession; 
    @RequestMapping(value = "/Get", method = RequestMethod.GET)
    @ResponseBody
    public BaseResult Get(String commandName,String commandJson) throws Exception {  
        Set<Class<?>> classes = ReflexHelper.getClasses("com.kiba.k_framework.dto");
        String newName ="";
        for(Class c:classes){
            String fullName = c.getName();
            System.out.println(fullName);
            String className = fullName.substring(fullName.lastIndexOf(".")+1,fullName.length());
            System.out.println(className);
            if(className.equals(commandName)) {
                newName = fullName.replace(".dto.", ".domain.") + "Handler";
                System.out.println(newName);
                break;
            }
        }
        Class<?> clazz = Class.forName(newName);
        Method method = clazz.getMethod("Excute", String.class,SqlSession.class);
        BaseResult ret = (BaseResult)method.invoke(clazz.newInstance(), commandJson,sqlSession);
        return ret;
    }
    @PostMapping(value = "/Post")
    @ResponseBody
    public BaseResult Post(String commandName,String commandJson) throws Exception {
        System.out.println(commandName);
        Set<Class<?>> classes = ReflexHelper.getClasses("com.kiba.k_framework.dto");
        String newName ="";
        for(Class c:classes){
            String fullName = c.getName();
            System.out.println(fullName);
            String className = fullName.substring(fullName.lastIndexOf(".")+1,fullName.length());
            System.out.println(className);
            if(className.equals(commandName)) {
                newName = fullName.replace(".dto.", ".domain.") + "Handler";
                System.out.println(newName);
                break;
            }
        } 
        Class<?> clazz = Class.forName(newName);
        Method method = clazz.getMethod("Excute", String.class,SqlSession.class);
        BaseResult ret = (BaseResult) method.invoke(clazz.newInstance(), commandJson,sqlSession);
        return ret;
    }  
}


如上代码所示,Controller接受到的请求,会被直接发送到业务域处理,也就是说,理论上,这里写完了,就再也不用关注了。

注1:代码一开始使用注解@Autowired实例化了sqlSession,这个对象是mybatis的内部对象,后面会把它发送到业务域,业务域里通过它获取mapper对象,这是因为,我们的业务域是反射调用的,所以在业务里@Autowired注解将失效,它将无法对继承BaseMapper的接口进行实例化。

注2:使用这种结构,我们的AOP除了可以使用@Aspect注解,还可以直接写在Controller里了。

注3:并不是所有项目和团队组成都适用这个的框架。

相关文章
|
12天前
|
Java API Maven
如何使用Java开发抖音API接口?
在数字化时代,社交媒体平台如抖音成为生活的重要部分。本文详细介绍了如何用Java开发抖音API接口,从创建开发者账号、申请API权限、准备开发环境,到编写代码、测试运行及注意事项,全面覆盖了整个开发流程。
56 10
|
16天前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
|
16天前
|
前端开发 JavaScript 安全
C#一分钟浅谈:Blazor WebAssembly 开发
Blazor WebAssembly 是一个客户端框架,允许开发者使用C#和Razor语法构建Web应用。本文介绍了Blazor WebAssembly的基本概念、常见问题及解决方案,包括路由配置、数据绑定、异步操作、状态管理和性能优化等方面的内容,并分享了一些易错点及如何避免的方法。希望这些内容能帮助你在Blazor WebAssembly开发中少走弯路,提高开发效率。
88 51
|
25天前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
25天前
|
消息中间件 Java 数据库连接
Java 反射最全详解 ,框架设计必掌握!
本文详细解析Java反射机制,包括反射的概念、用途、实现原理及应用场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Java 反射最全详解 ,框架设计必掌握!
|
14天前
|
开发框架 缓存 .NET
C# 一分钟浅谈:Blazor Server 端开发
Blazor Server 是基于 ASP.NET Core 的框架,允许使用 C# 和 Razor 语法构建交互式 Web 应用。本文介绍 Blazor Server 的基本概念、快速入门、常见问题及解决方案,帮助开发者快速上手。涵盖创建应用、基本组件、数据绑定、状态管理、跨组件通信、错误处理和性能优化等内容。
29 1
|
15天前
|
缓存 C# 开发者
C# 一分钟浅谈:Blazor Server 端开发
本文介绍了 Blazor Server,一种基于 .NET 的 Web 开发模型,允许使用 C# 和 Razor 语法构建交互式 Web 应用。文章从基础概念、创建应用、常见问题及解决方案、易错点及避免方法等方面详细讲解,帮助开发者快速上手并提高开发效率。
39 2
|
18天前
|
SQL 安全 Java
安全问题已经成为软件开发中不可忽视的重要议题。对于使用Java语言开发的应用程序来说,安全性更是至关重要
在当今网络环境下,Java应用的安全性至关重要。本文深入探讨了Java安全编程的最佳实践,包括代码审查、输入验证、输出编码、访问控制和加密技术等,帮助开发者构建安全可靠的应用。通过掌握相关技术和工具,开发者可以有效防范安全威胁,确保应用的安全性。
37 4
|
20天前
|
缓存 监控 Java
如何运用JAVA开发API接口?
本文详细介绍了如何使用Java开发API接口,涵盖创建、实现、测试和部署接口的关键步骤。同时,讨论了接口的安全性设计和设计原则,帮助开发者构建高效、安全、易于维护的API接口。
49 4
|
24天前
|
测试技术 Go C#
C#一分钟浅谈:ReSharper 插件增强开发效率
【10月更文挑战第25天】ReSharper 是 JetBrains 开发的一款 Visual Studio 插件,旨在提高 .NET 开发者的生产力。它通过代码分析、重构、导航等功能,帮助开发者避免常见错误,提升代码质量和开发效率。本文将通过具体代码案例,详细介绍 ReSharper 的常见功能及其应用。
37 1