# vertx-framework **Repository Path**: javacoo/vertx-framework ## Basic Information - **Project Name**: vertx-framework - **Description**: 这是一个简单的响应式接口开发框架,基于对vertx的路由创建,服务注册,Verticle部署等基本操作的简单封装,让接口开发过程更接近于传统的开发模式,简化响应式接口开发流程,降低开发门槛。 框架目前接入了jdbc,redis,后续根据具体需要在接入其他组件,更多组件信息见:https://vertx.io/docs - **Primary Language**: Java - **License**: Not specified - **Default Branch**: feature - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2023-03-29 - **Last Updated**: 2024-11-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # vertx-framework #### 介绍 这是一个简单的响应式接口开发框架,基于对vertx的路由创建,服务注册,Verticle部署等基本操作的简单封装,让接口开发过程更接近于传统的开发模式,简化响应式接口开发流程,降低开发门槛。 框架目前接入了jdbc,redis,后续根据具体需要在接入其他组件,更多组件信息见:https://vertx.io/docs #### 软件架构 软件架构说明 #### 安装教程 1. 引入pom ```xml org.javacoo.vertx vertx-core 1.0 org.javacoo.vertx vertx-database 1.0 ``` #### 开发步骤 1. 配置文件: 主配置文件:application.yaml ```yaml server: port: 8080 contextPath: / redis: urls: - redis://127.0.0.1:6379/0 clientType: STANDALONE poolName: p-red poolCleanerInterval: 30000 maxPoolSize: 8 maxPoolWaiting: 32 password: 1239abcz vertx: eventLoopPoolSize: 2 workerPoolSize: 4 eventBusOptions: connectTimeout: 6000 vertxScan: routerPackage: test.api.rest servicePackage: test.api.service serviceInstances: 1 ``` 环境配置文件:application-cloud.yaml ```yaml env: cloud dataSource: driverClass: org.postgresql.Driver url: jdbc:postgresql://127.0.0.1:9000/test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8&tinyInt1isBit=false user: postgres password: 123456 maxPoolSize: 30 sqlConfig: init: SELECT 1=1 # 总览-根据区域查询学校 getSchoolsInfoByArea: SELECT t.xxmc schoolName, t.xxdz schoolAddress, t.xxbsm schoolCode, t.jgjd longitude, t.jgwd latitude FROM gis_school_location t WHERE t.xxbxlx = !{eduType} AND t.area_code LIKE !{queryAreaCode} LIMIT !{pageSize} OFFSET !{offset} ``` 2. 启动类 ```java public class ApiLauncher implements Launcher { private static final Logger LOGGER = LoggerFactory.getLogger(ApiLauncher.class); /** * 环境 */ private static String env = EnvEnum.CLOUD.getCode(); /** * 服务端口 */ private static int serverPort = Constant.HTTP_PORT; private Vertx vertx; @Override public void start() { Vertx tempVertx = Vertx.vertx(); // 加载配置 ConfigRetriever retriever = initConfigRetriever(tempVertx); retriever.getConfig(json -> { tempVertx.close(); if(json.succeeded()){ doStart(json); }else{ LOGGER.error("加载配置"); } }); } /** * 执行启动 *
  • * @author duanyong * @date 2023/3/31 21:26 * @param json * @return: void */ private void doStart(AsyncResult json){ JsonObject envConfig = json.result(); LOGGER.info("配置读取成功"); //默认读取dev开发环境配置 JsonObject vertxConfig = envConfig.getJsonObject("vertx"); Vertx mainVertx = Vertx.vertx(new VertxOptions(vertxConfig)); //初始化 VertxHolder.init(mainVertx); //配置保存在共享数据中 SharedData sharedData = mainVertx.sharedData(); LocalMap localMap = sharedData.getLocalMap("/"); localMap.put("env", env); localMap.put("envConfig", envConfig); //先初始化再发布Http服务 mainVertx.executeBlocking(p -> { //顺序不能乱 try { //初始化ConfigProperties ConfigPropertiesHolder.init(envConfig); //初始化RedisClientHolder RedisAPIHolder.init(mainVertx, envConfig, redisConnectionAsyncResult -> { if(redisConnectionAsyncResult.succeeded()){ LOGGER.info("redis初始化成功"); }else{ LOGGER.error("redis初始化失败",redisConnectionAsyncResult.cause()); } }); //初始化JDBCClient JDBCClientHolder.init(envConfig, ready -> { if (ready.succeeded()) { p.complete(); LOGGER.info("JDBCClient初始化成功"); } else { p.fail(ready.cause()); LOGGER.error("JDBCClient初始化失败",ready.cause()); } }); } catch (Exception e) { LOGGER.error("初始化失败:{}",e); p.fail(e); } }).onComplete(ar2 -> { if (ar2.succeeded()) { JsonObject vertxScanConfig = envConfig.getJsonObject("vertxScan"); JsonObject serverConfig = envConfig.getJsonObject("server"); if(EnvEnum.CLOUD.getCode().equals(env)){ serverPort = serverConfig.getInteger("port"); } LOGGER.info("准备启动服务,http服务端口:{}",serverPort); EventConsumerConfig eventConsumerConfig = new EventConsumerConfig(); Router router = new RouterHandlerFactory(vertxScanConfig.getString("routerPackage"), serverConfig.getString("contextPath")).createRouter(); DeployVertxServer.startDeploy(eventConsumerConfig.consumer(),router, vertxScanConfig.getString("servicePackage"), serverPort, vertxScanConfig.getInteger("serviceInstances")); } else { LOGGER.error(ar2.cause().getMessage(), ar2.cause()); } }); } @Override public void stop() { vertx.close(); } /** * 初始化ConfigRetriever *
  • * @author duanyong * @date 2023/3/27 22:08 * @param vertx * @return: ConfigRetriever */ private ConfigRetriever initConfigRetriever(Vertx vertx) { //初始化 ConfigRetrieverOptions options = initOptions(); //创建 return ConfigRetriever.create(vertx, options); } /** * 初始化ConfigRetrieverOptions *
  • * @author duanyong * @date 2023/3/27 23:08 * @return: ConfigRetrieverOptions */ private ConfigRetrieverOptions initOptions() { // 使用默认ConfigStore ConfigRetrieverOptions options = new ConfigRetrieverOptions().setIncludeDefaultStores(false); // 禁用配置刷新 options.setScanPeriod(-1); //加载主配置 options.addStore(new ConfigStoreOptions() .setType("file") .setFormat("yaml") .setOptional(true) .setConfig(new JsonObject().put("path", "application.yaml"))); String envFile = new StringBuilder("application-").append(env).append(".yaml").toString(); //加载环境配置 options.addStore(new ConfigStoreOptions() .setType("file") .setFormat("yaml") .setOptional(true) .setConfig(new JsonObject().put("path", envFile))); // 禁用缓存 options.getStores().forEach(store -> { store.getConfig().put("cache", "false"); }); return options; } public static void main(String[] args) { if (args.length >= 1 && !CONFIG_DEFAULT.equals(args[0])) { env = args[0]; } if (args.length >= 2 && !CONFIG_DEFAULT.equals(args[1])) { serverPort = Integer.valueOf(args[1]); } Launcher launcher = new GisApiLauncher(); launcher.start(); } } ``` 3. 编写服务 接口类:TestService ```java /** * 测试服务接口 *
  • * * @author duanyong * @version 1.0 * @date 2023/6/24 22:17 */ @ProxyGen @VertxGen public interface TestService { @GenIgnore static test.api.reactivex.service.TestService createRxProxy() { return new test.api.reactivex.service.TestService(AsyncServiceUtil.getAsyncServiceInstance(TestService.class)); } /** * 测试方法 *
  • * @author duanyong * @date 2023/6/24 22:47 * @param query * @param resultHandler * @return: OverviewService */ @Fluent TestService test(JsonObject query,Handler>> resultHandler); } ``` 实现类:TestServiceImpl ```java /** * 总览服务接口实现类 *
  • * * @author duanyong * @version 1.0 * @date 2023/6/24 23:20 */ public class TestServiceImpl extends BaseAsyncService implements TestService { protected ConfigProperties.SqlConfigProperties sqlConfig; protected JDBCClient dbClient; public OverviewServiceImpl() { sqlConfig = ConfigPropertiesHolder.getConfigProperties().getSqlConfig(); dbClient = JDBCClientHolder.getJDBCClient(); } @Override public TestService test(JsonObject query, Handler>> resultHandler) { String areaCode = getAreaCodePrefix(query); String eduType = query.getString("eduType"); Integer pageSize = query.getInteger("pageSize"); Integer pageNum = query.getInteger("pageNum"); JsonObject result = parseTemplateSQL(sqlConfig.getGetSchoolsInfoByArea(),query); String finalSql = result.getString(SQL_KEY); JsonArray data = result.getJsonArray(PARAM_KEY); String cacheKey = new StringBuilder("getSchoolsInfoByArea_").append(areaCode).append(eduType).append(pageSize).append(pageNum).toString(); loadListData(dbClient,resultHandler, finalSql, data, cacheKey); return this; } } ``` 4. 编写接口 ```java /** * 测试服务接口 *
  • * * @author duanyong * @version 1.0 * @date 2023/6/25 22:27 */ @RouteHandler public class TestApi extends BaseRestApi { /** * 测试服务 */ private TestService testService = test.api.service.TestService.createRxProxy(); /** * 测试 * @return */ @RouteMapping(value = "/api/test", method = RouteMethod.POST) public Handler test() { return ctx -> { JsonObject query = ctx.body().asJsonObject(); if (!validateJsonPageDocument(ctx, query, "areaCode","level")) { return; } testService.rxTest(query) .subscribe(totalList -> fireJsonResponse(ctx, new JsonResult(totalList)), t -> fireErrorJsonResponse(ctx, t.getMessage())); }; } } ``` 至此便完成整个开发流程 #### 参与贡献 #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)