{"id":22202060,"url":"https://github.com/syfxlin/xkjava","last_synced_at":"2025-07-27T04:31:28.960Z","repository":{"id":39018250,"uuid":"267590163","full_name":"syfxlin/xkjava","owner":"syfxlin","description":"📐 一个轻量的 Java 框架","archived":false,"fork":false,"pushed_at":"2023-01-06T14:49:24.000Z","size":3521,"stargazers_count":4,"open_issues_count":24,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-07-30T19:15:23.396Z","etag":null,"topics":["aspect","fast-route","ioc","java","java-framework","spring","web-framework"],"latest_commit_sha":null,"homepage":"https://ixk.me","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/syfxlin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-28T12:56:38.000Z","updated_at":"2023-03-17T12:25:33.000Z","dependencies_parsed_at":"2023-02-06T05:32:07.929Z","dependency_job_id":null,"html_url":"https://github.com/syfxlin/xkjava","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/syfxlin%2Fxkjava","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/syfxlin%2Fxkjava/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/syfxlin%2Fxkjava/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/syfxlin%2Fxkjava/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/syfxlin","download_url":"https://codeload.github.com/syfxlin/xkjava/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227760017,"owners_count":17815626,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aspect","fast-route","ioc","java","java-framework","spring","web-framework"],"created_at":"2024-12-02T16:12:13.700Z","updated_at":"2024-12-02T16:12:14.359Z","avatar_url":"https://github.com/syfxlin.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# XK-Java\n\n\u003e 一个轻量的 Java 框架\n\n## 描述 Description\n\n本项目开发的动机同 [XK-PHP](https://github.com/syfxlin/xkphp) 一样，是一个为了熟悉对应的语言开发而开发的项目，由于先前也没有开发 Java\n项目的经验，也没有开发过常驻内存的项目，所以本项目中可能会有很多不合理的设计，存在线程不安全的情况，或者有许多缺陷和漏洞，同 XK-PHP\n一样，本项目不建议用于生产环境，仅用于学习就可以啦，若您有更好的建议或者发现不足的地方欢迎反馈。\n\n项目是依照先前的 XK-PHP 的架构开发的，所以可能会有一些设计并不遵循 Java 的规范。\n\n接口设计大部分是参考自 XK-PHP，不过也参考了 Spring 的部分设计，比如注解，切面，DispatchServlet 等等。\n\n集成了一个 IoC 容器和添加了 Aop 的支持，IoC 容器中并不实际存储实例，实例通过 Context 的实现类进行管理，类似于 Spring 的 BeanFactory，如\nApplicationContext 和 RequestContext，这样就可以动态的添加拥有不同特性的 Context，比如 RequestContext 是线程安全的，从\nHttpServletRequest 里使用 Attribute 进行存储的，而且可以动态的删除和创建，而 ApplicationContext 则没有这些功能，只是一个简单的 Map 存储容器。\n\nBinding 和 Alias 直接存储于 IoC 容器中，为了保证 Request 作用域实例的线程安全，实例化后的对象并未存储于 IoC 容器（Binding）中而是存储于不同的 Context\n中，当通过 `Binding.getSource()` 的时候，实际上是到对应的 Context 中 `getSource()`。拿 Request 作用域的实例举例吧，在 IoC 启动的时候会将\nRequest 作用域的实例绑定到 IoC 容器中，但是并不进行实例化，当首次使用的时候才会实例化。在请求结束的时候会清空 RequestContext，当下次请求到来的时候，由于\nRequestContext 被清空了，相当于 Request 作用域的实例被重置为非实例化的状态，此时会再次实例化。这样就保证了在每次请求的时候都能保证 Request 作用域的线程安全。\n\n由于 Java 是常驻内存的，不同于 PHP 每次请求都重新加载容器，所以 Java 需要考虑到不同客户端请求间的线程安全，不同线程间独立的实例存储于 RequestContext，如\nRequest，Response 等，然后通过 ObjectFactory 动态代理的方式通过 getObject 从 RequestContext\n动态获取该线程下的实例。RequestContext 使用 ThreadLocal 保证线程安全。\n\nIoC\n容器支持集合注入，延迟加载和泛型注入，其中容器只包含了基础的绑定、生产、调用和存储实例的功能，注入处理和前置后置处理均是可装配的，可以自定义注入器，默认的注入器可以支持大部分场景，如果有无法实现的场景可以使用自定义注入器，不过需要注意线程安全。\n\n注入的范围包括字段，方法，构造器。构造器注入无需使用 @Autowired 注解。字段注入如果有 WriteMethod 则无需使用 @Autowired 注解，否则你需要在字段上添加\n@Autowired 注解。方法注入分为两种，一种是类似于 Spring 的 Aware 接口，用于对象实例化后立即注入，此情形下你需要添加 @Autowired\n注解；还有一种是普通的方法，普通的方法如果使用 Container.call 的方法调用则会自动注入，无需使用 @Autowired 注解。\n\n注入的时候容器会自动进行类型转换，如果查找不到依赖则会注入该类型的默认值，如果是集合、Map、ObjectFactory、ObjectProvider。\n\n集成中间件处理器，可以很方便的对请求和响应进行拦截，预处理，后处理等。过滤器，监听器，Servlet 目前已集成到框架中，对应的注解是\n@Filter，@Listener，@Servlet。被这些注解标记的 Servlet 注解会被容器托管，所以支持自动注入和其他组件的特性，同时也可以使用 @Order 来进行排序。\n\n请求和响应扩展自 Jetty 的 Request 和 Response，添加了一些类似 Laravel 的接口，并内置 RequestBody 到 JsonNode 的转换功能。\n\n新版的处理流程已经更新，可以自由添加参数解析器、返回值处理器、前置异常处理器、后置异常处理器、响应转换器，请求流程与 Spring 类似。\n\n在控制器中，请求中的参数会自动注入到方法中，无需使用注解标注，同时也支持自动封装成对象，同 Spring MVC 封装的对象也支持嵌套，你只需定义好参数的名称，并使用点分隔即可。\n\n最新的版本重构了 Response 的部分，添加了 HttpResult 一系列的响应对象，你可以直接返回这些对象，后续的中间件会把这些对象转换成对应的响应。使用的方式也很简单，你可以使用\nResult 抽象类中的一系列静态方法，也可以 new 出来，新版新增了 InputStream 和 File 类型的响应对象，支持超大文件下载。\n\n添加了很多同 Spring 的注解，不过有一些小改动，注解大部分都支持通过 @Order 进行排序，同时注解也可以使用 @AliasFor\n使用别名，同时提供一个通用的注解处理抽象类，如果需要处理自定义注解可以通过继承该类快速实现。\n\n支持组合注解（注解继承），子注解设置的值如果设置了 @AliasFor 到父注解，则在获取的时候会进行一次扫描，扫描时会将子注解的值同步到父注解上。原本的修改的方式是通过反射修改\nmemberValues，所以会造成值留存的现象。现在已经通过 JDK 代理实现了对注解的克隆，所有的修改均在克隆对象上进行操作，不影响源对象，不会造成值留存现象了。\n\n除了组合注解，框架还支持条件注解，所以也支持了自动配置，只不过目前没有完善的可更换注解。\n\n目前框架已经将大部分组件使用注解进行加载和配置，替换和修改组件变得更加容易了，不用再为各种依赖头疼。\n\n支持 AspectJ 切面，需要经过 IoC 容器处理后才能生效，同时需要实现 Advice 接口，可以直接继承自 AbstractAdvice，从容器中 Make 或者 Call，以及绑定到容器的\nBean 都可以注入切面。切面实现使用的是 Cglib。\n\n路由是参考 PHP 的 FastRoute 制作而成的，RouteCollector 会将 Handler 封装成集成了中间件的 RouteHandler，然后依照静态路由或动态路由的方式存入到\nstaticRoutes 或 variableRoutes。路由匹配的方式采用的是和 FastRoute 一样的匹配方式，在路由调度器创建的时候，RouteGenerator\n会将所有动态路由的表达式合成成一个路由表达式，在匹配的时候就只需要进行一次匹配，可以在一定程度上提高路由的匹配速度。\n\n支持使用注解开启事务，不过做的很简单，可能会有一些问题。\n\n替换了 Jetty 自带的 ErrorHandler，改用支持动态响应 HTML 和 JSON 数据内容的 ErrorHandler。\n\n最新版去掉了门面，改用 Helper 静态方法，你可以使用静态导入的方式使用这些 Helper 方法。\n\nORM 使用的是 Mybatis Plus，视图采用 Thymeleaf, FreeMarker 渲染，HttpServer 采用 Jetty，参数验证使用的是\nHibernateValidator（由于后续才引入的 HuTool，就懒得改了），类型转换器和一些其他工具使用的是 HuTool，数据源使用的是 HikariCP，JSON 库采用的是\nJackson，由于 Java 默认不会保留参数名称，加编译选项在我这出现时好时坏的情况，所以本项目直接采用了 ASM 来获取参数名称。使用 SpringEL（第三方库，去除了 Spring Core\n依赖） 来解析 @Value 的表达式。\n\n添加了 @PostConstruct 和 @PreDestroy 的支持\n\n添加了 @DataBind 和 WebDataBinder 的支持，@DataBind 用于标注传入参数的名称或前缀，如 GET 请求参数为\nname=name1\u0026user.name=name2，如果在 @DataBind 中设置名称为 user，那么会使用 WebDataBinder 注入，注入的值就是\nname2。若注入的不是请求参数而是绑定到容器的对象，那么会使用 DefaultDataBinder 注入，注入值是在容器中指定名称的对象或值。\n\n@Autowired 和 @DataBind 都已经支持设置 required，一旦无法找到注入的对象或值，那么就会抛出 NullPointerException。\n\n同时添加了 @Valid 校验注解，使用方式和 Spring 差不多，目前只支持在参数上使用，在参数上添加该注解，容器在注入后就会使用 HibernateValidator\n对对象进行验证，如果验证失败会将信息封装到 ValidResult 和 ValidGroup 中，如果有多个错误，那么 ValidResult 只会保留最后一个。同 Spring\n一样，如果注入的参数不包含 ValidResult 或 ValidGroup（在 Spring 中是 BindingResult），一旦校验失败则会抛出\nValidException。如果注入的参数中包含 ValidResult 或 ValidGroup，那么在校验失败的时候，容器不会抛出 ValidException，此时就需要在\nController 中进行错误处理。\n\n新版新增了缓存、异步任务、定时任务，均支持使用注解开启。同时也适配了 @Enable 注解，可以按需进行启动。\n\n## 特性 Feature\n\n- 组合注解 \u0026 注解别名\n- Aop 切面，支持 AspectJ 表达式\n- IoC 容器\n- 依赖注入，依赖查找，注入来源包括配置文件，容器等\n- Servlet 组件支持注入（过滤器，监听器，Servlet）\n- 声明式事务\n- 加载不同环境配置\n- 命令行配置\n- 声明式缓存，Redis \u0026 内存（初步支持）\n- 条件注解\n- @Enable 注解按需加载模块\n- 多种 Bean 作用域\n- SpEl 支持\n- CORS 过滤器\n- 大文件响应，支持断点续传，多线程（初步支持）\n- 线程安全对象（利用动态代理从线程安全容器获取对象），用于单例对象注入请求作用域对象的线程安全\n- 自定义注入器和 Bean 处理器\n- 泛型注入，集合对象注入，懒加载注入（简单支持）\n- 中间件（拦截器）\n- 声明式异步任务，声明式定时任务\n- FreeMarker \u0026 Thymeleaf 支持\n- Mybatis-Plus 支持\n- Jetty 支持\n- FastRoute 快速路由\n- 异步控制器（初步支持）\n- 集成测试 \u0026 单元测试，支持声明式 Http 请求，测试类注入\n- CSRF 中间件\n- 声明式参数验证\n- 实际参数名称获取\n- 销毁对象前处理（@PreDestroy）\n- 自动配置（部分支持，目前已支持模块自动配置）\n- 延迟响应\n- 事件（初步支持）\n- WebSocket（初步支持）\n- WebFlux（Project Reactor）（初步支持）\n\n## TODO\n\n- 添加完整的 Test Case\n- 多级缓存\n- 统一资源加载\n- 国际化支持\n\n## 文档 Doc\n\n暂无\n\n## 维护者 Maintainer\n\nXK-Java 由 [Otstar Lin](https://ixk.me/)\n和下列 [贡献者](https://github.com/syfxlin/xkjava/graphs/contributors) 的帮助下撰写和维护。\n\n\u003e Otstar Lin - [Personal Website](https://ixk.me/) · [Blog](https://blog.ixk.me/) · [Github](https://github.com/syfxlin)\n\n## 许可证 License\n\n![License](https://img.shields.io/github/license/syfxlin/xkjava.svg?style=flat-square)\n\n根据 Apache License 2.0 许可证开源。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsyfxlin%2Fxkjava","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsyfxlin%2Fxkjava","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsyfxlin%2Fxkjava/lists"}