{"id":13841330,"url":"https://github.com/onblog/ProjectTree","last_synced_at":"2025-07-11T12:31:13.477Z","repository":{"id":45274991,"uuid":"169087231","full_name":"onblog/ProjectTree","owner":"onblog","description":"新人熟悉项目必备工具！基于AOP开发的一款方法调用链分析框架，简单到只需要一个注解，异步非阻塞，完美嵌入Spring Cloud、Dubbo项目！再也不用担心搞不懂项目！（欢迎Star，🚫禁止Fork）","archived":false,"fork":false,"pushed_at":"2024-10-03T18:06:33.000Z","size":746,"stargazers_count":208,"open_issues_count":3,"forks_count":52,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-10-30T17:55:10.206Z","etag":null,"topics":["java-8"],"latest_commit_sha":null,"homepage":"","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/onblog.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":"2019-02-04T14:04:25.000Z","updated_at":"2024-09-26T04:20:26.000Z","dependencies_parsed_at":"2022-09-26T21:50:28.074Z","dependency_job_id":null,"html_url":"https://github.com/onblog/ProjectTree","commit_stats":null,"previous_names":["yueshutong/spring-project-tree"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onblog%2FProjectTree","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onblog%2FProjectTree/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onblog%2FProjectTree/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onblog%2FProjectTree/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/onblog","download_url":"https://codeload.github.com/onblog/ProjectTree/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225720400,"owners_count":17513596,"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":["java-8"],"created_at":"2024-08-04T17:01:08.540Z","updated_at":"2024-11-21T11:30:37.959Z","avatar_url":"https://github.com/onblog.png","language":"Java","funding_links":[],"categories":["Java","Java (504)"],"sub_categories":[],"readme":"![](./picture/220619.png)\n\n很多新人进入一家新公司后，最头疼的就是如何快速了解公司的业务和项目架构。\n\n因为文档很少，没有文档，或者是文档严重落伍， 根本没法看；如果你碰到一个特别热心的老员工，事无巨细地给你讲，随时在你身边答疑解惑， 那简直是天大的好运气， 现实是大家都很忙，没人给你讲解。\n\n很快就要深入项目做开发了，怎么办呢？\n\n我在加入新公司后，就遇到了悲催的情况。于是，我就做了这款可视化流程分析插件！帮助更多入职新人快速熟悉业务。\n\n\n## Maven依赖\n\n直接在pom.xml引入依赖！\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.onblog\u003c/groupId\u003e\n  \u003cartifactId\u003eproject-tree-spring-boot-starter\u003c/artifactId\u003e\n  \u003cversion\u003e2.0.0.RELEASE\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n但前提是你已经引入如下依赖：\n\n```xml\n\u003cdependency\u003e\n   \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n   \u003cartifactId\u003espring-boot-starter-web\u003c/artifactId\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n   \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n   \u003cartifactId\u003espring-boot-starter-aop\u003c/artifactId\u003e\n\u003c/dependency\u003e\n```\n\n### Spring Boot Starter\n\n如果你的项目是Spring Boot，那么使用会非常简单，只需要一个注解即可。\n\n@EnableProjectTree(value = \"\")注解参数为[pointcut](https://www.baidu.com/baidu?isource=infinity\u0026iname=baidu\u0026itype=web\u0026tn=98012088_9_dg\u0026ch=7\u0026ie=utf-8\u0026wd=%40pointcut%20%E8%A1%A8%E8%BE%BE%E5%BC%8F)表达式，完整代码如下：\n\n```java\n@SpringBootApplication\n@EnableProjectTree(\"execution(* com.example.springboot.demo..*(..))\")\npublic class SpringbootApplication {\n\n    public static void main(String[] args) {\n        SpringApplication.run(SpringbootApplication.class, args);\n    }\n\n}\n```\n\nProject Tree不仅增加了对分布式接口的监控，还增加了pointcut表示式。\n\n### 访问ProjectTree\n\n启动你的项目，首先访问你项目的某个接口，使其执行被监控的方法。然后访问`localhost:8080/tree/project.html`查看网页。\n\n#### 接口说明\n\n| 接口                         | 说明                 |\n| ---------------------------- | -------------------- |\n| /tree/project.html         | 返回完整调用链视图     |\n| /tree/project.html?all=1    | 返回全部方法视图     |\n| /projecttree/all        | JSON形式的返回结果   |\n| /projecttree/{methodId}      | 对某一方法的JSON结果 |\n\n## 注意事项\n\n使用Shiro、Spring Securit等安全框架时，需要注意对此URL的权限控制。\n\n另外，方法调用链分析并不会监控自身对自身的方法调用，因为this.method()并不是调用的代理对象的method()方法。\n\n\n## 源码亮点\n\n1.如何降低对主流程的性能消耗？\n\n使用多线程实现异步非阻塞模型。\n\n2.为什么使用单例线程池？\n\n只有一个线程的线程池实际是队列+单线程，一个一个的执行任务，完全符合本框架的使需求，多则出错。\n\n3.为什么数据保存到内存？\n\n基于内存的数据读写，基于方法调用链分析进行选择性保存，占用内存极小。理论上说，从接口开始，有多少流程分支，就有多少条数据记录。\n\n4.如何实现方法调用分析？\n\n基于栈数据结构设计算法。\n\n5.如何解决多线程环境对算法的影响？\n\n通过ThreadId加Stack自定义数据结构“线程栈”实现线程隔离。\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonblog%2FProjectTree","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fonblog%2FProjectTree","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonblog%2FProjectTree/lists"}