# pm **Repository Path**: jianxinliu/pm ## Basic Information - **Project Name**: pm - **Description**: Prime Minister--用于学习的简易 Web 开发框架,使用类似 Spring Boot 的思想 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-01-28 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Prime Minister 这是一个用于学习的简易 MVC 框架,尽量基于 JDK 实现,最少依赖。 ## 功能: - 内置简易 Web 服务器,基于 NIO 实现。(待完善)(Server) - 内置内存数据库,也可能是对象存储(待实现)(Ship,DSO(data store object)) - 前端 Mock Server,基于配置的路由和响应(待实现) - json 解析器(待实现) - 日志打印(Almost Done) - yml 格式的配置文件的读取及应用 ### 简易 Web 服务器 基于 NIO 实现,实现了自己的路由,自己的注解。 ### 内存数据库(待实现) 类似 redis ,支持持久化,也可能是一个对象存储器,将对象直接持久化。分文件存放 ### 前端 Mock Server(待实现) - 基于配置的路由和响应,给前后端提供统一的交互接口。方便的切换到后端 Server. - 是前后端交互的协议(基于映射),能为前端和后端提供支持,为前段提供响应能力,为后端提供请求能力 - 提供 Web 界面 - 也可以作为微服务之间的 Mock Server. ### 日志打印(Almost Done) - 支持多种日志级别 - 支持模板解析和占位符解析 - 支持短类名 todo: - [] 日志输出地的选择,可以支持在配置文件中配置、 ### Config(Doing) - 默认部分配置 - yml 格式文件解析支持 - 配置注入 ## How to Start 将代码编译后打成 jar 包,作为依赖,之后便可像 Spring Boot 一样进行 Web 开发。 * 项目根目录的启动类。 ```java @App public class PmTestApplication { public static void main(String[] args) { PrimeMinister.run(); } } ``` * Controller 与依赖注入 ```java @URLMapping("/pm") @RestController() public class Controller { @Autowired private Service service; @URLMapping("/index") public String getIndex() { return "/html/index.html"; } @URLMapping("/hello") public String hello() { return service.hello(); } } ``` * 组件 ```java @Component() public class Service { public String hello() { return "{code:200,msg:'success',data:{a:3}}"; } } ``` ### 启动效果 1. 控制台输出 ``` 2019-03-29 21:08:04.245 INFO --- [c.m.p.c.Scanner ] : pmtest.Service 2019-03-29 21:08:04.297 INFO --- [c.m.p.c.Scanner ] : pmtest.PmTestApplication 2019-03-29 21:08:04.326 INFO --- [c.m.p.c.Scanner ] : pmtest.Controller 2019-03-29 21:08:04.354 INFO --- [c.m.p.c.Scanner ] : Mapped url:[/pm/index] to :pmtest.Controller.getIndex() 2019-03-29 21:08:04.356 INFO --- [c.m.p.c.Scanner ] : Mapped url:[/pm/hello] to :pmtest.Controller.hello() 2019-03-29 21:08:04.357 INFO --- [c.m.p.c.Scanner ] : Mapped url:[/pm/user] to :pmtest.Controller.getUser() 2019-03-29 21:08:04.362 INFO --- [c.m.p.c.Scanner ] : Mapped url:[/pm/index] to :pmtest.Controller.getIndex() 2019-03-29 21:08:04.362 INFO --- [c.m.p.c.Scanner ] : Mapped url:[/pm/hello] to :pmtest.Controller.hello() 2019-03-29 21:08:04.368 INFO --- [c.m.p.c.Scanner ] : Mapped url:[/pm/user] to :pmtest.Controller.getUser() 2019-03-29 21:08:04.400 INFO --- [c.m.p.s.HttpServer ] : Server listening on 127.0.0.1:8080.... ``` 2. 访问 ```shell ~$ curl http://localhost:8080/pm/index /html/index.html ``` 3. 错误打印 ``` 2019-03-29 21:24:17.809 INFO --- [c.m.p.c.Context ] : URL:/pm/hello 2019-03-29 21:24:17.811 ERROR --- [c.m.p.c.Context ] : Cause by: java.lang.reflect.InvocationTargetException 2019-03-29 21:24:17.811 ERROR --- [c.m.p.c.Context ] : 2019-03-29 21:24:17.812 ERROR --- [c.m.p.c.Context ] : sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:498) com.minister.pm.core.Context.letHandlerInvoke(Context.java:139) com.minister.pm.server.DispatchRequest.urlMapper(DispatchRequest.java:39) com.minister.pm.server.HttpServer.dispatchRequest(HttpServer.java:84) com.minister.pm.server.HttpServer.run(HttpServer.java:58) com.minister.pm.core.PrimeMinister.run(PrimeMinister.java:31) pmtest.PmTestApplication.main(PmTestApplication.java:16) ``` ## Samples ### log ```java Logger logger = Logger.getLogger(XXClass.class); logger.info("hello,{}","world"); // output like : 2019-03-29 21:24:17.809 INFO --- [c.m.p.c.Context ] : hello,world ``` ### config 支持 yml 格式的配置文件。配置读取例子: ```java @Configuration public class PMConfig { @Value(path = "server.port") public static String port; @Value(path = "banner") public static String defaultBanner; } // call PMConfig.port; ``` ``` ```