Java 微服务框架 Redkale 入门介绍

Redkale是一个小巧但功能齐全的Java框架,可用于构建服务器或作为工具包。它提供了JSON序列化、二进制序列化、数据库操作、TCP/UDP服务及HTTP服务等功能。本文介绍了Redkale的目录结构、启动流程、开发调试方法、依赖注入机制以及从单点部署到微服务部署的各种架构方案,展示了其灵活的架构和易于扩展的特点。
摘要由CSDN通过智能技术生成

Redkale虽然只有1.xM大小,但是麻雀虽小五脏俱全。既可作为服务器使用,也可当工具包使用。作为独立的工具包提供以下功能:
1、convert包提供JSON的序列化和反序列化功能,类似Gson、Jackson
2、convert包提供Java对象二进制的序列化和反序列化功能,类似Protobuf。
3、source包提供很简便的数据库操作功能,类似JPA、Hibernate。
4、net包提供TCP/UDP服务功能, 类似Mina。
5、net.http提供HTTP服务, 类似Tomcat、Netty。
6、ResourceFactory提供轻量级的依赖注入功能, 类似Google Guice。

Redkale 服务器

Redkale作为服务器的目录如下:
bin   : 存放启动关闭脚本(start.sh、shutdown.sh、start.bat、shutdown.bat)
conf : 存放服务器所需配置文件:
application.xml: 服务配置文件 (必需);
logging.properties:日志配置文件 (可选);
persistence.xml:数据库配置文件 (可选);
lib    : 存放服务所依赖的第三方包,redkale.jar 放在此处。
logs : logging.properties 配置中默认的日志存放目录。
root : application.xml 配置中HTTP服务所需页面的默认根目录。

Redkale启动的流程如下:

1、加载 application.xml 并解析。
2、初始化 <resources> 节点中的资源。
3、解析所有的 <server> 节点。
4、初始化并启动所有<server> 节点的Server服务 (优先加载SNCP协议的Server)。
5、初始化单个Server:
5.1、扫描classpath加载所有可用的Service实现类(没有标记为@AutoLoad(false)的类)并实例化,然后相互依赖注入。
5.2、Service实例在依赖注入过程中加载所需的DataSource、CacheSource资源。
5.3、调用所有本地模式Service的init方法。
5.4、扫描classpath加载所有可用的Servlet实现类(没有标记为@AutoLoad(false)的类)并实例化 (优先实例化WebSocketServlet)。
5.5、给所有Servlet依赖注入所需的Service。
5.6、调用所有Servlet的init方法。
5.7、启动Server的服务监听。
6、启动进程本身的监听服务。

基于Redkale的开发与调试

基于Redkale创建一个Java应用程序工程(即使是Web项目也不要创建Java-Web工程),引用redkale.jar 并创建Redkale所需的几个目录和文件。一个普通的Web项目只需要编写业务层的Service和接入层的HttpServlet的代码。数据库DataSource通过配置文件进行设置。
编写完代码可以通过启动脚本进行调试, 也可以在IDE设置项目的主类为 org.redkale.boot.Application 或者工程内定义主类进行启动调试:

public final class Bootstrap {

    public static void main(String[] args) throws Exception {
        org.redkale.boot.Application.main(args);
    }
}

若需要调试单个Service,可以通过 Application.singleton 方法进行调试:

public static void main(String[] args) throws Exception {
        UserService service = Application.singleton(UserService.class);
        LoginBean bean = new LoginBean();
        bean.setAccount("myaccount");
        bean.setPassword("123456");
        System.out.println(service.login(bean));
    }

Application.singleton 运行流程与通过bin脚本启动的流程基本一致,区别在于singleton运行时不会启动Server和Application自身的服务监听。Redkale提倡接入层(Servlet)与业务层(Service)分开,Service在代码上不能依赖于Servlet,因此调试Service自身逻辑时不需要启动接入层服务(类似WebSocket依赖Servlet的功能除外)。

Redkale的依赖注入

Redkale内置的依赖注入实现很简单,只有三个类: javax.annotation.Resource、org.redkale.util.ResourceType、org.redkale.util.ResourceFactory,采用反射技术,由于依赖注入通常不会在频繁的操作中进行,因此性能要求不会很高。其中前两个是注解,ResourceFactory是主要操作类,主要提供注册和注入两个接口。ResourceFactory的依赖注入不仅提供其他依赖注入框架的常规功能,还能动态的自动更新通过inject注入的资源。

public class AService {

    @Resource(name = "property.id")
    private String id;

    @Resource(name = "property.id") //property.开头的资源名允许String自动转换成primitive数值类型
    private int intid;

    @Resource(name = "bigint")
    private BigInteger bigint;

    @Resource(name = "seqid")
    private int seqid;

    @Resource
    private ResourceTest.BService bservice;

    @Override
    public String toString() {
        return "{id:/"" + id + "/", intid: " + intid + ", bigint:" + bigint + "}";
    }

    /** 以下省略getter setter方法 */
}

public class BService {

    @Resource(name = "property.id")
    private String id;

    @Resource
    private AService aservice;

    private String name = "";

    @java.beans.ConstructorProperties({"name"})
    public BService(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "{name:/"" + name + "/", id: " + id + ", aserivce:" + aservice + "}";
    }

    /** 以下省略getter setter方法 */
}

public static void main(String[] args) throws Exception {
    ResourceFactory factory = ResourceFactory.root();
    factory.register("property.id", "2345"); //注入String类型的property.id
    AService aservice = new AService();
    BService bservice = new BService("eee");

    factory.register(aservice);  //放进Resource池内,默认的资源名name为""
    factory.register(bservice);  //放进Resource池内,默认的资源名name为""

    factory.inject(aservice);  //给aservice注入id、bservice,bigint没有资源,所以为null
    factory.inject(bservice);  //给bservice注入id、aservice
    System.out.println(aservice); //输出结果为:{id:"2345", intid:2345, bigint:null, bservice:{name:eee}}
    System.out.println(bservice); //输出结果为:{name:"eee", id:2345, aserivce:{id:"2345", intid:2345, bigint:null, bservice:{name:eee}}}

    factory.register("seqid", 200); //放进Resource池内, 同时ResourceFactory会自动更新aservice的seqid值
    System.out.println(factory.find("seqid", int.class));   //输出结果为:200
    factory.register("bigint", new BigInteger("66666")); //放进Resource池内, 同时ResourceFactory会自动更新aservice对象的bigint值   
    System.out.println(aservice); //输出结果为:{id:"2345", intid:2345, bigint:66666, bservice:{name:eee}}可以看出seqid与bigint值都已自动更新

    factory.register("property.id", "6789"); //更新Resource池内的id资源值, 同时ResourceFactory会自动更新aservice、bservice的id值
    System.out.println(aservice); //输出结果为:{id:"6789", intid:6789, bigint:66666, bservice:{name:eee}}
    System.out.println(bservice); //输出结果为:{name:"eee", id:6789, aserivce:{id:"6789", intid:6789, bigint:66666, bservice:{name:eee}}}

    bservice = new BService("ffff");
    factory.register(bservice);   //更新Resource池内name=""的BService资源, 同时ResourceFactory会自动更新aservice的bservice对象
    factory.inject(bservice);
    System.out.println(aservice); //输出结果为:{id:"6789", intid: 6789, bigint:66666, bservice:{name:ffff}}

}

如上例,通过ResourceFactory.inject注入的对象都会自动更新资源的变化,若不想自动更新可以使用带boolean autoSync参数的register系列方法(autoSync传false)注册新资源。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值