Giiwa轻量级分布式应用框架

联合创作 · 2023-09-20 07:10

Giiwa 是一个 Java Web 的快速开发框架。


模块化:模块化开发,模块之间可以复用和重载。最大化地复用代码和资源,使得构建跨项目之间的模块更加容易。


快速开发:直观简单的程序入口出口,更容易开发和维护。避免冗重设计模式,更加快速的构建模块,快速开发和部署。


轻量级分布式:并行对等分布式计算节点关系。更容易从一个节点扩展到N个节点,构建可伸缩的分布式并行计算环境。


MVC开发


简洁的MVC,更加简单程序逻辑。


后台支持Java开发,View支持Velocity, Thymeleaf, FreeMaker,HTML等。系统提供文件仓库,支持前后端代码完全分离开发。


请参考:Controller


样例程序:https://www.giisoo.com/helo/test?name=ttttt



//org.giiwa.app.web.helo.java
//helo.java
package org.giiwa.app.web;

import org.giiwa.framework.web.Controller;
import org.giiwa.framework.web.Path;

public class helo extends Controller {

@Path(path = "test")
public void test() {

String name = this.getString("name");
this.set("name", name);

this.show("/helo.html");

}

}
//end of helo.java

// /view/helo.html
//helo.html
<!DOCTYPE html>
<html>
<body>
名字:&!name
</body>
</html>
//end of helo.html

高效数据库操作


优化的数据库访问设计,更加简单高效。


请参考: BeanBeanDAOHelper.WHelper.V


支持内嵌数据库,Postgresql,Mysql,Oracle,和MongoDB数据库,支持大数据量的高效访问,提供统一API。



//org.giiwa.demo.bean.Demo.java
//begin of the Demo Bean
package org.giiwa.demo.bean;

import org.giiwa.dao.Bean;
import org.giiwa.dao.BeanDAO;
import org.giiwa.dao.Table;
import org.giiwa.dao.Helper.V;
import org.giiwa.dao.Column;
import org.giiwa.dao.UID;
import org.giiwa.dao.X;

/**
* Demo bean
*
* @author joe
*
*/
// mapping the table name in database
@Table(name = "tbl_demo")
public class Demo extends Bean {

/**
*
*/
private static final long serialVersionUID = 1L;

// define a DAO for each Bean
public static final BeanDAO<Long , Demo> dao = BeanDAO.create(Demo.class);

// mapping the column and field
@Column(name = X.ID)
long id;

@Column(name = "name")
String name;

public long getId() {
return id;
}

public String getName() {
return name;
}

// ------------

// insert a data in database
public static long create(V v) {
/**
* generate a unique id in distribute system
*/
long id = UID.next("demo.id");
try {
while (dao.exists(id)) {
id = UID.next("demo.id");
}
dao.insert(v.force(X.ID, id));
return id;
} catch (Exception e1) {
log.error(e1.getMessage(), e1);
}
return -1;
}

}
// end of the Demo Bean

//org.giiwa.demo.web.admin.demo.java
//begin of the Controller
package org.giiwa.demo.web.admin;

import org.giiwa.dao.Beans;
import org.giiwa.dao.X;
import org.giiwa.json.JSON;
import org.giiwa.dao.Helper.V;
import org.giiwa.dao.Helper.W;
import org.giiwa.demo.bean.Demo;
import org.giiwa.web.Controller;
import org.giiwa.web.Path;

public class demo extends Controller {

@Path(login = true, access = "access.demo.admin")
public void onGet() {
// get the parameters from the request
int s = this.getInt("s");
int n = this.getInt("n", 10);

// create the query condition
W q = W.create();
String name = this.getString("name");

if (!X.isEmpty(name)) {
q.and("name", name, W.OP.like);
this.set("name", name);
}

// load data from database
Beans<Demo> bs = Demo.dao.load(q, s, n);

// set the data in the controller
this.set(bs, s, n);

// show (print) the list HTML page
this.show("/admin/demo.index.html");
}

@Path(path = "detail", login = true, access = "access.demo.admin")
public void detail() {
// get the parameter from the request
long id = this.getLong("id");

// load data from the database
Demo d = Demo.dao.load(id);

// set the data in controller
this.set("b", d);
this.set("id", id);

// show (print) the detail HTML page
this.show("/admin/demo.detail.html");
}

@Path(path = "delete", login = true, access = "access.demo.admin")
public void delete() {
// get the parameter from the request
long id = this.getLong("id");

// delete the data from the database
Demo.dao.delete(id);

// response (print) the json to response
this.response(JSON.create().append(X.STATE, 200).append(X.MESSAGE, lang.get("delete.success")));
}

@Path(path = "create", login = true, access = "access.demo.admin")
public void create() {

// is POST method?
if (method.isPost()) {

// create the value object
V v = V.create();
v.set("name", this.getString("name"));

// insert the data into database
Demo.create(v);

// response(print) the json to response
this.response(JSON.create().append(X.STATE, 200).append(X.MESSAGE, lang.get("save.success")));
return;
}

// show (print) the create HTML page
this.show("/admin/demo.create.html");
}

// web api: /admin/demo/edit?id=
@Path(path = "edit", login = true, access = "access.demo.admin")
public void edit() {
// get the parameter from the request
long id = this.getLong("id");

// is POST method?
if (method.isPost()) {

// create the value object
V v = V.create();
v.set("name", this.getString("name"));

// update the data in database
Demo.dao.update(id, v);

// response (print) the json to response
this.response(JSON.create().append(X.STATE, 200).append(X.MESSAGE, lang.get("save.success")));
return;
}

// load the data from the database
Demo d = Demo.dao.load(id);

// set the data in Controller
this.set(d.getJSON());
this.set("id", id);

// show (print) the edit HTML page
this.show("/admin/demo.edit.html");
}

}
// end of the Controller

模块管理


模块化开发,轻松创建模块工程文件,生成模块样例文件。


包含完整的模块生命周期管理,应用模块可以添加自己的处理逻辑在模块生命周期各个阶段。


请参考: IListenerIFilter



//module.xml
<?xml version="1.0" encoding="UTF-8"?>

<module version="1.0">
<id>652</id>
<name>demo</name>
<package>org.giiwa.demo.web</package>
<version>1.0</version>
<build>0</build>
<enabled>true</enabled>
<readme>demo</readme>
<listener>
<!--add module listener here, please refer IListener interface-->
<class>org.giiwa.demo.web.DemoListener</class>
</listener>
<filter>
<!--TODO, please refer web.IFilter, eg. <pattern>/user/login</pattern>,<class>org.giiwa.demo.web.UserFiler</class>-->
</filter>
<required>
<!--add all required modules here-->
<module name="default" minversion="1.6.1901131542"
maxversion="1.6.*" />
</required>
<key>MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKWDm99lG8Oy5b93ptb+v0lrI2O4PK4oujb4pHfq9FUJiFECe/lotkgEpjwT+4Q2LmUJpTBRSpEAGrAJfxidGgOs6kxUtEBSEfPvkifUDCmKzsvOd3R4dbfBiF0qDSxiwBV9PWwXg1TBYio345yJIRosO1JETnLdgPk/6zokMDvLAgMBAAECgYEAm6rKQTNRB6AMISYhzndN5XlUkYdH2u0HJoh39ykNn6UVhkt12j83oUhuKHcKyXBD9lc5+9WY8gNNFl/4H2gye9tEJQ5CAVoUdky79kVtkB55Aa+io0cGNA/xmhsRnpZB/ZRazBZ4dIeRoEfLWM0Ki/zr6H2VFFi737jIUlf/8DECQQDN/ZvJ/aNe6AugNaLIryZpBzIrBa2xxyK/REnpFVJGeNq84hb6n8TqZVCkk9nTTBazCptcWjuod8mJwMITANJNAkEAzbJeLjtg5r8EWza6na8kIB871ouKJdxYwr88hrx0A9aClcrYpFvA8rbgQ76Z1QJjV3dQfP38Bg+0g6MK3AFidwJAS7CBWwIw0oGvK+opa1Y4ZeU4AOjwPt+uG9uq0NN9zNlBfqAQ03x7balWrXKKWoKd4KHoHlIlk6yYSF6ksTjfDQJABV+TdkG21lBHHNrhJR1eJDisp34drb+D0hKM0jg6D5+a6a7S2fhLoguE8EAaZKYbUj2brKg13TKr1IR91CF1IQJASVILcBNP83XF/WHny5YacSalyxTdTihIISV6Jw42KFEcgIQ85iqKhZFOhibZYq9w45/XXZPgr4vP64ScUXq3iA==</key>
</module>
//end of the module.xml

//org.giiwa.demo.web.DemoListener.java
//begin of the DemoListener
package org.giiwa.demo.web;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.giiwa.demo.task.TestTask;
import org.giiwa.bean.License;
import org.giiwa.web.IListener;
import org.giiwa.web.Module;

public class DemoListener implements IListener {

static Log log = LogFactory.getLog(DemoListener.class);

@Override
public void onStart(Configuration conf, Module m) {
log.info("webdemo is starting ...");

// set the license of this module
m.setLicense(License.LICENSE.free,
"f3VOF0UAnJPBRlucnMpWXrn/7q9cbeY2VVXsphwE/iLJGPB1+1hUUHLdZOLWEafPm6hbOkvXAK9xGZuNCyTBczpib+NNizqqhLis4eODBQYHLePmEYJDdMwnDi+Z8TMNOL/uCm6rverY06qWzedJ6IWdq5ev8LJ5mUkI8gHrhcg=");

// start a test task here
TestTask.start();

}

@Override
public void onStop() {
log.info("webdemo is stopping ...");

// stop the test tasj
TestTask.stop();

}

@Override
public void uninstall(Configuration conf, Module m) {
//uninstall the module
}

@Override
public void upgrade(Configuration conf, Module m) {
//upgrade the module
}

}
// end of the DemoListener

分布式并行计算


轻量级分布式计算平台,从1个节点到n个节点任意扩展,节点之间都为对等关系,没有主从区别。


分布式计算环境包括:高速缓存,消息系统,分布式锁,分布式文件系统,分布式计算任务。


请参考: TaskMQCacheGlobal.getLock



//org.giiwa.demo.task.TestTask.java
//begin of the TestTask
package org.giiwa.demo.task;

import java.util.Arrays;

import org.giiwa.bean.X;
import org.giiwa.task.Task;

public class TestTask extends Task {

/**
*
*/
private static final long serialVersionUID = 1L;

public static TestTask inst = new TestTask();

private boolean stop = false;

@Override
public String getName() {
// the task name, MUST global unique in JVM
return "test.tsk";
}

@Override
public void onFinish() {
// re-run this task at a minute alter
if (!stop) {
this.schedule(X.AMINUTE);
}
}

@Override
public void onExecute() {
// do something
try {
// mapreduce, create sub task for the stream and dispatch the task to each node
// and each core
Task.mapreduce(Arrays.asList(1, 2, 3, 4), e -> {
return e * 100;
}, e -> {
System.out.println(e);
});
} catch (Exception e1) {
e1.printStackTrace();
}
}

public static void start() {
inst.stop = false;
inst.schedule(0);
}

public static void stop() {
inst.stop = true;
inst.stop(true);
}

}
//end of the TestTask

 

浏览 38
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报