插件使用说明

This commit is contained in:
ruying408
2024-07-13 20:41:03 +08:00
parent e55777b80c
commit aa2222709b
56 changed files with 640 additions and 342 deletions
+22 -22
View File
@@ -1,58 +1,58 @@
{
"hash": "d712c44c",
"configHash": "04b05d57",
"lockfileHash": "10c85a81",
"browserHash": "e5d017df",
"hash": "d9b86bd3",
"configHash": "e63c5cfc",
"lockfileHash": "c55b7bf4",
"browserHash": "045a2561",
"optimized": {
"vue": {
"src": "../../../node_modules/.pnpm/vue@3.4.31/node_modules/vue/dist/vue.runtime.esm-bundler.js",
"src": "../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
"file": "vue.js",
"fileHash": "f9c29b17",
"fileHash": "bd97c188",
"needsInterop": false
},
"vitepress > @vue/devtools-api": {
"src": "../../../node_modules/.pnpm/@vue+devtools-api@7.3.5/node_modules/@vue/devtools-api/dist/index.js",
"src": "../../../node_modules/@vue/devtools-api/dist/index.js",
"file": "vitepress___@vue_devtools-api.js",
"fileHash": "a1f0d505",
"fileHash": "ac0f4af7",
"needsInterop": false
},
"vitepress > @vueuse/core": {
"src": "../../../node_modules/.pnpm/@vueuse+core@10.11.0_vue@3.4.31/node_modules/@vueuse/core/index.mjs",
"src": "../../../node_modules/@vueuse/core/index.mjs",
"file": "vitepress___@vueuse_core.js",
"fileHash": "906d8118",
"fileHash": "551b7fb3",
"needsInterop": false
},
"vitepress > @vueuse/integrations/useFocusTrap": {
"src": "../../../node_modules/.pnpm/@vueuse+integrations@10.11.0_focus-trap@7.5.4_vue@3.4.31/node_modules/@vueuse/integrations/useFocusTrap.mjs",
"src": "../../../node_modules/@vueuse/integrations/useFocusTrap.mjs",
"file": "vitepress___@vueuse_integrations_useFocusTrap.js",
"fileHash": "2a3348f0",
"fileHash": "8937181e",
"needsInterop": false
},
"vitepress > mark.js/src/vanilla.js": {
"src": "../../../node_modules/.pnpm/mark.js@8.11.1/node_modules/mark.js/src/vanilla.js",
"src": "../../../node_modules/mark.js/src/vanilla.js",
"file": "vitepress___mark__js_src_vanilla__js.js",
"fileHash": "943e4b2c",
"fileHash": "4d49e387",
"needsInterop": false
},
"vitepress > minisearch": {
"src": "../../../node_modules/.pnpm/minisearch@6.3.0/node_modules/minisearch/dist/es/index.js",
"src": "../../../node_modules/minisearch/dist/es/index.js",
"file": "vitepress___minisearch.js",
"fileHash": "415e26a7",
"fileHash": "9eb5370b",
"needsInterop": false
},
"medium-zoom": {
"src": "../../../node_modules/.pnpm/medium-zoom@1.1.0/node_modules/medium-zoom/dist/medium-zoom.esm.js",
"src": "../../../node_modules/medium-zoom/dist/medium-zoom.esm.js",
"file": "medium-zoom.js",
"fileHash": "10651d0b",
"fileHash": "82de3862",
"needsInterop": false
}
},
"chunks": {
"chunk-7WWQ3R2W": {
"file": "chunk-7WWQ3R2W.js"
"chunk-GK7ZRSPS": {
"file": "chunk-GK7ZRSPS.js"
},
"chunk-CGFDJW4T": {
"file": "chunk-CGFDJW4T.js"
"chunk-XPVHNUZ4": {
"file": "chunk-XPVHNUZ4.js"
}
}
}
@@ -33,9 +33,9 @@ import {
version,
watch,
watchEffect
} from "./chunk-CGFDJW4T.js";
} from "./chunk-XPVHNUZ4.js";
// node_modules/.pnpm/vitepress@1.3.0_@algolia+client-search@4.24.0_postcss@8.4.39_search-insights@2.15.0/node_modules/vitepress/lib/vue-demi.mjs
// node_modules/vitepress/lib/vue-demi.mjs
var isVue2 = false;
var isVue3 = true;
function set(target, key, val) {
@@ -55,7 +55,7 @@ function del(target, key) {
delete target[key];
}
// node_modules/.pnpm/@vueuse+shared@10.11.0_vue@3.4.31/node_modules/@vueuse/shared/index.mjs
// node_modules/@vueuse/shared/index.mjs
function computedEager(fn, options) {
var _a;
const result = shallowRef();
@@ -1552,7 +1552,7 @@ function whenever(source, cb, options) {
return stop;
}
// node_modules/.pnpm/@vueuse+core@10.11.0_vue@3.4.31/node_modules/@vueuse/core/index.mjs
// node_modules/@vueuse/core/index.mjs
function computedAsync(evaluationCallback, initialState, optionsOrRef) {
let options;
if (isRef(optionsOrRef)) {
@@ -9169,4 +9169,4 @@ vitepress/lib/vue-demi.mjs:
* @license MIT
*)
*/
//# sourceMappingURL=chunk-7WWQ3R2W.js.map
//# sourceMappingURL=chunk-GK7ZRSPS.js.map
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
// node_modules/.pnpm/@vue+shared@3.4.31/node_modules/@vue/shared/dist/shared.esm-bundler.js
// node_modules/@vue/shared/dist/shared.esm-bundler.js
function makeMap(str, expectsLowerCase) {
const set2 = new Set(str.split(","));
return expectsLowerCase ? (val) => set2.has(val.toLowerCase()) : (val) => set2.has(val);
@@ -288,7 +288,7 @@ var stringifySymbol = (v, i = "") => {
);
};
// node_modules/.pnpm/@vue+reactivity@3.4.31/node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js
// node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js
function warn(msg, ...args) {
console.warn(`[Vue warn] ${msg}`, ...args);
}
@@ -1476,7 +1476,7 @@ var TriggerOpTypes = {
"CLEAR": "clear"
};
// node_modules/.pnpm/@vue+runtime-core@3.4.31/node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js
// node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js
var stack = [];
function pushWarningContext(vnode) {
stack.push(vnode);
@@ -9626,7 +9626,7 @@ var resolveFilter = null;
var compatUtils = null;
var DeprecationTypes = null;
// node_modules/.pnpm/@vue+runtime-dom@3.4.31/node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js
// node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js
var svgNS = "http://www.w3.org/2000/svg";
var mathmlNS = "http://www.w3.org/1998/Math/MathML";
var doc = typeof document !== "undefined" ? document : null;
@@ -11219,7 +11219,7 @@ var initDirectivesForSSR = () => {
}
};
// node_modules/.pnpm/vue@3.4.31/node_modules/vue/dist/vue.runtime.esm-bundler.js
// node_modules/vue/dist/vue.runtime.esm-bundler.js
function initDev() {
{
initCustomFormatter();
@@ -11437,4 +11437,4 @@ vue/dist/vue.runtime.esm-bundler.js:
* @license MIT
**)
*/
//# sourceMappingURL=chunk-CGFDJW4T.js.map
//# sourceMappingURL=chunk-XPVHNUZ4.js.map
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,4 +1,4 @@
// node_modules/.pnpm/medium-zoom@1.1.0/node_modules/medium-zoom/dist/medium-zoom.esm.js
// node_modules/medium-zoom/dist/medium-zoom.esm.js
var _extends = Object.assign || function(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
File diff suppressed because one or more lines are too long
+5 -5
View File
@@ -1,4 +1,4 @@
// node_modules/.pnpm/@vue+devtools-shared@7.3.5/node_modules/@vue/devtools-shared/dist/index.js
// node_modules/@vue/devtools-shared/dist/index.js
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -254,7 +254,7 @@ function isUrlString(str) {
var deepClone = (0, import_rfdc.default)({ circles: true });
init_esm_shims();
// node_modules/.pnpm/hookable@5.5.3/node_modules/hookable/dist/index.mjs
// node_modules/hookable/dist/index.mjs
function flatHooks(configHooks, hooks2 = {}, parentName) {
for (const key in configHooks) {
const subHook = configHooks[key];
@@ -459,7 +459,7 @@ function createHooks() {
return new Hookable();
}
// node_modules/.pnpm/perfect-debounce@1.0.0/node_modules/perfect-debounce/dist/index.mjs
// node_modules/perfect-debounce/dist/index.mjs
var DEBOUNCE_DEFAULTS = {
trailing: true
};
@@ -516,11 +516,11 @@ async function _applyPromised(fn, _this, args) {
return await fn.apply(_this, args);
}
// node_modules/.pnpm/birpc@0.2.17/node_modules/birpc/dist/index.mjs
// node_modules/birpc/dist/index.mjs
var { clearTimeout: clearTimeout2, setTimeout: setTimeout2 } = globalThis;
var random = Math.random.bind(Math);
// node_modules/.pnpm/@vue+devtools-kit@7.3.5/node_modules/@vue/devtools-kit/dist/index.js
// node_modules/@vue/devtools-kit/dist/index.js
var __create2 = Object.create;
var __defProp2 = Object.defineProperty;
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -273,8 +273,8 @@ import {
watchTriggerable,
watchWithFilter,
whenever
} from "./chunk-7WWQ3R2W.js";
import "./chunk-CGFDJW4T.js";
} from "./chunk-GK7ZRSPS.js";
import "./chunk-XPVHNUZ4.js";
export {
DefaultMagicKeysAliasMap,
StorageSerializers,
@@ -1,13 +1,13 @@
import {
tryOnScopeDispose,
unrefElement
} from "./chunk-7WWQ3R2W.js";
} from "./chunk-GK7ZRSPS.js";
import {
ref,
watch
} from "./chunk-CGFDJW4T.js";
} from "./chunk-XPVHNUZ4.js";
// node_modules/.pnpm/tabbable@6.2.0/node_modules/tabbable/dist/index.esm.js
// node_modules/tabbable/dist/index.esm.js
var candidateSelectors = ["input:not([inert])", "select:not([inert])", "textarea:not([inert])", "a[href]:not([inert])", "button:not([inert])", "[tabindex]:not(slot):not([inert])", "audio[controls]:not([inert])", "video[controls]:not([inert])", '[contenteditable]:not([contenteditable="false"]):not([inert])', "details>summary:first-of-type:not([inert])", "details:not([inert])"];
var candidateSelector = candidateSelectors.join(",");
var NoElement = typeof Element === "undefined";
@@ -338,7 +338,7 @@ var isFocusable = function isFocusable2(node, options) {
return isNodeMatchingSelectorFocusable(options, node);
};
// node_modules/.pnpm/focus-trap@7.5.4/node_modules/focus-trap/dist/focus-trap.esm.js
// node_modules/focus-trap/dist/focus-trap.esm.js
function ownKeys(e, r) {
var t = Object.keys(e);
if (Object.getOwnPropertySymbols) {
@@ -1018,7 +1018,7 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
return trap;
};
// node_modules/.pnpm/@vueuse+integrations@10.11.0_focus-trap@7.5.4_vue@3.4.31/node_modules/@vueuse/integrations/useFocusTrap.mjs
// node_modules/@vueuse/integrations/useFocusTrap.mjs
function useFocusTrap(target, options = {}) {
let trap;
const { immediate, ...focusTrapOptions } = options;
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
// node_modules/.pnpm/mark.js@8.11.1/node_modules/mark.js/src/lib/domiterator.js
// node_modules/mark.js/src/lib/domiterator.js
var DOMIterator = class _DOMIterator {
/**
* @param {HTMLElement|HTMLElement[]|NodeList|string} ctx - The context DOM
@@ -494,7 +494,7 @@ var DOMIterator = class _DOMIterator {
*/
};
// node_modules/.pnpm/mark.js@8.11.1/node_modules/mark.js/src/lib/mark.js
// node_modules/mark.js/src/lib/mark.js
var Mark = class {
// eslint-disable-line no-unused-vars
/**
@@ -1638,7 +1638,7 @@ var Mark = class {
}
};
// node_modules/.pnpm/mark.js@8.11.1/node_modules/mark.js/src/vanilla.js
// node_modules/mark.js/src/vanilla.js
function Mark2(ctx) {
const instance = new Mark(ctx);
this.mark = (sv, opt) => {
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,4 +1,4 @@
// node_modules/.pnpm/minisearch@6.3.0/node_modules/minisearch/dist/es/index.js
// node_modules/minisearch/dist/es/index.js
var __assign = function() {
__assign = Object.assign || function __assign2(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -158,7 +158,7 @@ import {
withMemo,
withModifiers,
withScopeId
} from "./chunk-CGFDJW4T.js";
} from "./chunk-XPVHNUZ4.js";
export {
BaseTransition,
BaseTransitionPropsValidators,
+3 -3
View File
@@ -6,16 +6,16 @@
<title>404 | Cool Admin</title>
<meta name="description" content="Not Found">
<meta name="generator" content="VitePress v1.3.0">
<link rel="preload stylesheet" href="/assets/style.CoKMOhgV.css" as="style">
<link rel="preload stylesheet" href="/assets/style.8kWPK1kv.css" as="style">
<script type="module" src="/assets/app.Vqm78vzn.js"></script>
<script type="module" src="/assets/app.BbEPPFnZ.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
</head>
<body>
<div id="app"></div>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"index.md\":\"CAVf4Oqs\",\"readme.md\":\"OcZ1dgrk\",\"src_about_index.md\":\"BcF27jYK\",\"src_guide_ai.md\":\"Gsy5t_8S\",\"src_guide_cache.md\":\"BOJv_Che\",\"src_guide_controller.md\":\"r2nPGOST\",\"src_guide_exception.md\":\"m-_TuVSi\",\"src_guide_flow.md\":\"DerjmfqW\",\"src_guide_generatorcode.md\":\"vZguykgt\",\"src_guide_initdata.md\":\"CSiXmFuQ\",\"src_guide_plugin.md\":\"YnHghnwg\",\"src_guide_quick.md\":\"Dd-HcOh7\",\"src_guide_security.md\":\"BubSrMYS\",\"src_guide_springboot3.md\":\"_tGrFUv8\",\"src_guide_swagger.md\":\"BS_bARv2\",\"src_guide_upload.md\":\"Bq5siQ0E\",\"src_introduce_index.md\":\"DvEK5WJI\",\"src_introduce_show.md\":\"DSZevIGP\",\"src_introduce_src.md\":\"pd2vUss-\",\"src_question_commonquestion.md\":\"CeHvXEMU\",\"src_todo_plan.md\":\"bhlKWKsq\",\"src_todo_update.md\":\"qtvh9HZG\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Cool Admin\",\"description\":\"一个很酷的后台管理系统开发框架\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"logo\":\"/logo.png\",\"search\":{\"provider\":\"local\"},\"footer\":{\"message\":\"COOL为开发者而生\",\"copyright\":\"<a href=\\\"https://beian.miit.gov.cn\\\">Copyright © COOL | 闽ICP备2024042701号</a>\"},\"docFooter\":{\"prev\":\"上一页\",\"next\":\"下一页\"},\"outline\":{\"label\":\"页面导航\"},\"lastUpdated\":{\"text\":\"最后更新于\",\"formatOptions\":{\"dateStyle\":\"short\",\"timeStyle\":\"medium\"}},\"langMenuLabel\":\"多语言\",\"returnToTopLabel\":\"回到顶部\",\"sidebarMenuLabel\":\"菜单\",\"darkModeSwitchLabel\":\"主题\",\"lightModeSwitchTitle\":\"切换到浅色模式\",\"darkModeSwitchTitle\":\"切换到深色模式\",\"editLink\":{\"text\":\"在GitHub上编辑\",\"pattern\":\"https://github.com/cool-team-official/cool-admin-java-docs/blob/main/:path\"},\"nav\":[{\"text\":\"介绍\",\"link\":\"/src/introduce/index.md\",\"noIcon\":false},{\"text\":\"教程\",\"link\":\"/src/guide/quick.md\"},{\"text\":\"🔥插件市场\",\"link\":\"https://cool-js.com/plugin/list.html\"},{\"text\":\"交流合作\",\"link\":\"/src/about/index.md\"},{\"text\":\"v7.1.0\",\"items\":[{\"text\":\"更新日志\",\"link\":\"/src/todo/update.md\"},{\"text\":\"版本计划\",\"link\":\"/src/todo/plan.md\"}]},{\"text\":\"更多\",\"items\":[{\"text\":\"Cool Admin(Nodejs版)\",\"link\":\"https://cool-js.com\"},{\"text\":\"Uni(基于uni-app跨端移动端开发)\",\"link\":\"https://cool-js.com/uni/introduce.html\"}]}],\"sidebar\":[{\"text\":\"介绍\",\"items\":[{\"text\":\"简介\",\"link\":\"/src/introduce/index.md\"},{\"text\":\"演示\",\"link\":\"/src/introduce/show.md\"},{\"text\":\"源码\",\"link\":\"/src/introduce/src.md\"}]},{\"text\":\"教程\",\"items\":[{\"text\":\"快速开始\",\"link\":\"/src/guide/quick.md\"},{\"text\":\"Ai编码\",\"link\":\"/src/guide/ai.md\"},{\"text\":\"Ai流程编排\",\"link\":\"/src/guide/flow.md\"},{\"text\":\"扩展插件\",\"link\":\"/src/guide/plugin.md\"},{\"text\":\"核心\",\"items\":[{\"text\":\"Spring Boot3\",\"link\":\"/src/guide/springboot3.md\"},{\"text\":\"控制器(controller)\",\"link\":\"/src/guide/controller.md\"},{\"text\":\"缓存\",\"link\":\"/src/guide/cache.md\"},{\"text\":\"文件上传\",\"link\":\"/src/guide/upload.md\"},{\"text\":\"统一异常\",\"link\":\"/src/guide/exception.md\"},{\"text\":\"权限校验\",\"link\":\"/src/guide/security.md\"},{\"text\":\"数据初始化\",\"link\":\"/src/guide/initData.md\"},{\"text\":\"代码生成\",\"link\":\"/src/guide/generatorCode.md\"},{\"text\":\"swagger 文档\",\"link\":\"/src/guide/swagger.md\"}]}]},{\"text\":\"计划&更新\",\"items\":[{\"text\":\"更新\",\"link\":\"/src/todo/update.md\"},{\"text\":\"计划\",\"link\":\"/src/todo/plan.md\"}]},{\"text\":\"常见问题\",\"link\":\"/src/question/commonQuestion.md\"},{\"text\":\"交流合作\",\"link\":\"/src/about/index.md\"}],\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/cool-team-official/cool-admin-java\"}]},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"index.md\":\"CAVf4Oqs\",\"readme.md\":\"BXdrAVTM\",\"src_about_index.md\":\"BcF27jYK\",\"src_guide_ai.md\":\"Gsy5t_8S\",\"src_guide_cache.md\":\"BOJv_Che\",\"src_guide_controller.md\":\"r2nPGOST\",\"src_guide_exception.md\":\"m-_TuVSi\",\"src_guide_flow.md\":\"DPOXSEzV\",\"src_guide_generatorcode.md\":\"vZguykgt\",\"src_guide_initdata.md\":\"CSiXmFuQ\",\"src_guide_plugin.md\":\"jVCi1KWQ\",\"src_guide_quick.md\":\"Dd-HcOh7\",\"src_guide_security.md\":\"BubSrMYS\",\"src_guide_springboot3.md\":\"_tGrFUv8\",\"src_guide_swagger.md\":\"BS_bARv2\",\"src_guide_upload.md\":\"Bq5siQ0E\",\"src_introduce_index.md\":\"CXfKVW0H\",\"src_introduce_show.md\":\"DSZevIGP\",\"src_introduce_src.md\":\"pd2vUss-\",\"src_question_commonquestion.md\":\"CeHvXEMU\",\"src_todo_plan.md\":\"bhlKWKsq\",\"src_todo_update.md\":\"qtvh9HZG\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Cool Admin\",\"description\":\"一个很酷的后台管理系统开发框架\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"logo\":\"/logo.png\",\"search\":{\"provider\":\"local\"},\"footer\":{\"message\":\"COOL为开发者而生\",\"copyright\":\"<a href=\\\"https://beian.miit.gov.cn\\\">Copyright © COOL | 闽ICP备2024042701号</a>\"},\"docFooter\":{\"prev\":\"上一页\",\"next\":\"下一页\"},\"outline\":{\"label\":\"页面导航\"},\"lastUpdated\":{\"text\":\"最后更新于\",\"formatOptions\":{\"dateStyle\":\"short\",\"timeStyle\":\"medium\"}},\"langMenuLabel\":\"多语言\",\"returnToTopLabel\":\"回到顶部\",\"sidebarMenuLabel\":\"菜单\",\"darkModeSwitchLabel\":\"主题\",\"lightModeSwitchTitle\":\"切换到浅色模式\",\"darkModeSwitchTitle\":\"切换到深色模式\",\"editLink\":{\"text\":\"在GitHub上编辑\",\"pattern\":\"https://github.com/cool-team-official/cool-admin-java-docs/blob/main/:path\"},\"nav\":[{\"text\":\"介绍\",\"link\":\"/src/introduce/index.md\",\"noIcon\":false},{\"text\":\"教程\",\"link\":\"/src/guide/quick.md\"},{\"text\":\"🔥插件市场\",\"link\":\"https://cool-js.com/plugin/list.html\"},{\"text\":\"交流合作\",\"link\":\"/src/about/index.md\"},{\"text\":\"v7.1.0\",\"items\":[{\"text\":\"更新日志\",\"link\":\"/src/todo/update.md\"},{\"text\":\"版本计划\",\"link\":\"/src/todo/plan.md\"}]},{\"text\":\"更多\",\"items\":[{\"text\":\"Cool Admin(Nodejs版)\",\"link\":\"https://cool-js.com\"},{\"text\":\"Uni(基于uni-app跨端移动端开发)\",\"link\":\"https://cool-js.com/uni/introduce.html\"}]}],\"sidebar\":[{\"text\":\"介绍\",\"items\":[{\"text\":\"简介\",\"link\":\"/src/introduce/index.md\"},{\"text\":\"演示\",\"link\":\"/src/introduce/show.md\"},{\"text\":\"源码\",\"link\":\"/src/introduce/src.md\"}]},{\"text\":\"教程\",\"items\":[{\"text\":\"快速开始\",\"link\":\"/src/guide/quick.md\"},{\"text\":\"Ai编码\",\"link\":\"/src/guide/ai.md\"},{\"text\":\"Ai流程编排\",\"link\":\"/src/guide/flow.md\"},{\"text\":\"扩展插件\",\"link\":\"/src/guide/plugin.md\"},{\"text\":\"核心\",\"items\":[{\"text\":\"Spring Boot3\",\"link\":\"/src/guide/springboot3.md\"},{\"text\":\"控制器(controller)\",\"link\":\"/src/guide/controller.md\"},{\"text\":\"缓存\",\"link\":\"/src/guide/cache.md\"},{\"text\":\"文件上传\",\"link\":\"/src/guide/upload.md\"},{\"text\":\"统一异常\",\"link\":\"/src/guide/exception.md\"},{\"text\":\"权限校验\",\"link\":\"/src/guide/security.md\"},{\"text\":\"数据初始化\",\"link\":\"/src/guide/initData.md\"},{\"text\":\"代码生成\",\"link\":\"/src/guide/generatorCode.md\"},{\"text\":\"swagger 文档\",\"link\":\"/src/guide/swagger.md\"}]}]},{\"text\":\"计划&更新\",\"items\":[{\"text\":\"更新\",\"link\":\"/src/todo/update.md\"},{\"text\":\"计划\",\"link\":\"/src/todo/plan.md\"}]},{\"text\":\"常见问题\",\"link\":\"/src/question/commonQuestion.md\"},{\"text\":\"交流合作\",\"link\":\"/src/about/index.md\"}],\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/cool-team-official/cool-admin-java\"}]},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
</body>
</html>
+6 -6
View File
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{_ as a,c as e,o as t,a4 as o}from"./chunks/framework.BZ5u8Vj7.js";const f=JSON.parse('{"title":"介绍","description":"","frontmatter":{},"headers":[],"relativePath":"README.md","filePath":"README.md","lastUpdated":1720594161000}'),r={name:"README.md"},l=o('<h1 id="介绍" tabindex="-1">介绍 <a class="header-anchor" href="#介绍" aria-label="Permalink to &quot;介绍&quot;">​</a></h1><p>这是 Cool Admin(Java 版)的在线文档仓库,我们会尽力完善文档。也希望广大开发者粉丝帮助完善文档,积极提交<a href="https://github.com/cool-team-official/cool-admin-java-docs/pulls" target="_blank" rel="noreferrer">Pull requests</a>,共同参与开源,你的贡献可能给其他人代码巨大的帮助</p><h1 id="地址" tabindex="-1">地址 <a class="header-anchor" href="#地址" aria-label="Permalink to &quot;地址&quot;">​</a></h1><ul><li><p>文档:<a href="https://java.cool-admin.com" target="_blank" rel="noreferrer">https://java.cool-admin.com</a></p></li><li><p>官网:<a href="https://cool-js.com" target="_blank" rel="noreferrer">https://cool-js.com</a></p></li></ul>',4),s=[l];function c(n,i,_,d,h,p){return t(),e("div",null,s)}const u=a(r,[["render",c]]);export{f as __pageData,u as default};
import{_ as a,c as e,o as t,a4 as o}from"./chunks/framework.BZ5u8Vj7.js";const f=JSON.parse('{"title":"介绍","description":"","frontmatter":{},"headers":[],"relativePath":"README.md","filePath":"README.md","lastUpdated":1720848653000}'),r={name:"README.md"},l=o('<h1 id="介绍" tabindex="-1">介绍 <a class="header-anchor" href="#介绍" aria-label="Permalink to &quot;介绍&quot;">​</a></h1><p>这是 Cool Admin(Java 版)的在线文档仓库,我们会尽力完善文档。也希望广大开发者粉丝帮助完善文档,积极提交<a href="https://github.com/cool-team-official/cool-admin-java-docs/pulls" target="_blank" rel="noreferrer">Pull requests</a>,共同参与开源,你的贡献可能给其他人代码巨大的帮助</p><h1 id="地址" tabindex="-1">地址 <a class="header-anchor" href="#地址" aria-label="Permalink to &quot;地址&quot;">​</a></h1><ul><li><p>文档:<a href="https://java.cool-admin.com" target="_blank" rel="noreferrer">https://java.cool-admin.com</a></p></li><li><p>官网:<a href="https://cool-admin.com" target="_blank" rel="noreferrer">https://cool-admin.com</a></p></li></ul>',4),c=[l];function n(s,i,_,d,h,p){return t(),e("div",null,c)}const u=a(r,[["render",n]]);export{f as __pageData,u as default};
@@ -1 +1 @@
import{_ as a,c as e,o as t,a4 as o}from"./chunks/framework.BZ5u8Vj7.js";const f=JSON.parse('{"title":"介绍","description":"","frontmatter":{},"headers":[],"relativePath":"README.md","filePath":"README.md","lastUpdated":1720594161000}'),r={name:"README.md"},l=o("",4),s=[l];function c(n,i,_,d,h,p){return t(),e("div",null,s)}const u=a(r,[["render",c]]);export{f as __pageData,u as default};
import{_ as a,c as e,o as t,a4 as o}from"./chunks/framework.BZ5u8Vj7.js";const f=JSON.parse('{"title":"介绍","description":"","frontmatter":{},"headers":[],"relativePath":"README.md","filePath":"README.md","lastUpdated":1720848653000}'),r={name:"README.md"},l=o("",4),c=[l];function n(s,i,_,d,h,p){return t(),e("div",null,c)}const u=a(r,[["render",n]]);export{f as __pageData,u as default};
@@ -1 +1 @@
import{U as o,ab as p,ac as u,ad as l,ae as c,af as f,ag as d,ah as m,ai as h,aj as g,ak as A,d as P,u as v,y,x as w,al as C,am as R,an as b,ao as E}from"./chunks/framework.BZ5u8Vj7.js";import{R as S}from"./chunks/theme.JaXF9rxx.js";function i(e){if(e.extends){const a=i(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=i(S),T=P({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=v();return y(()=>{w(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),R(),b(),s.setup&&s.setup(),()=>E(s.Layout)}});async function _(){globalThis.__VITEPRESS__=!0;const e=x(),a=j();a.provide(u,e);const t=l(e.route);return a.provide(c,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function j(){return h(T)}function x(){let e=o,a;return g(t=>{let n=A(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=import(n)),o&&(e=!1),r},s.NotFound)}o&&_().then(({app:e,router:a,data:t})=>{a.go().then(()=>{p(a.route,t.site),e.mount("#app")})});export{_ as createApp};
import{U as o,ab as p,ac as u,ad as l,ae as c,af as f,ag as d,ah as m,ai as h,aj as g,ak as A,d as P,u as v,y,x as w,al as C,am as R,an as b,ao as E}from"./chunks/framework.BZ5u8Vj7.js";import{R as S}from"./chunks/theme.BlfWphLu.js";function i(e){if(e.extends){const a=i(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=i(S),T=P({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=v();return y(()=>{w(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),R(),b(),s.setup&&s.setup(),()=>E(s.Layout)}});async function _(){globalThis.__VITEPRESS__=!0;const e=x(),a=j();a.provide(u,e);const t=l(e.route);return a.provide(c,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function j(){return h(T)}function x(){let e=o,a;return g(t=>{let n=A(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=import(n)),o&&(e=!1),r},s.NotFound)}o&&_().then(({app:e,router:a,data:t})=>{a.go().then(()=>{p(a.route,t.site),e.mount("#app")})});export{_ as createApp};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{_ as a,c as e,o as t,a4 as i,a9 as o}from"./chunks/framework.BZ5u8Vj7.js";const A=JSON.parse('{"title":"Ai 流程编排","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/flow.md","filePath":"src/guide/flow.md","lastUpdated":1720593505000}'),r={name:"src/guide/flow.md"},s=i('<h1 id="ai-流程编排" tabindex="-1">Ai 流程编排 <a class="header-anchor" href="#ai-流程编排" aria-label="Permalink to &quot;Ai 流程编排&quot;">​</a></h1><p>coming soon!!!</p><p><a href="https://www.bilibili.com/video/BV1i1421r7ri/" target="_blank" rel="noreferrer">nodejs 版本视频演示</a></p><p>开发 Ai 应用必备!!!</p><p>随着 Ai 的火热,很多应用希望接入 Ai 的能力,但是每次都是用代码手搓,容易把我们累死,而是也非常不灵活。</p><p>于是我们面向开发者和软件开发公司,做了一个 Ai 流程编排功能,结合知识库,通过拖动配置,很容易就能完成一个 Ai 的核心流程。</p><p>因此如果你需要开发 Ai 相关应用,这个可能会给你带来巨大的帮助。</p><p><img src="'+o+'" alt="流程编排" data-zoomable=""></p><div class="warning custom-block"><p class="custom-block-title">注意</p><p>Ai 流程编排+知识库需要单独购买,预售 999 元</p></div>',9),c=[s];function p(_,l,n,d,m,f){return t(),e("div",null,c)}const u=a(r,[["render",p]]);export{A as __pageData,u as default};
import{_ as a,c as e,o as t,a4 as i,a9 as o}from"./chunks/framework.BZ5u8Vj7.js";const A=JSON.parse('{"title":"Ai 流程编排","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/flow.md","filePath":"src/guide/flow.md","lastUpdated":1720847903000}'),r={name:"src/guide/flow.md"},s=i('<h1 id="ai-流程编排" tabindex="-1">Ai 流程编排 <a class="header-anchor" href="#ai-流程编排" aria-label="Permalink to &quot;Ai 流程编排&quot;">​</a></h1><p>coming soon!!!</p><p><a href="https://www.bilibili.com/video/BV1i1421r7ri/" target="_blank" rel="noreferrer">nodejs 版本视频演示</a></p><p>开发 Ai 应用必备!!!</p><p>随着 Ai 的火热,很多应用希望接入 Ai 的能力,但是每次都是用代码手搓,容易把我们累死,而是也非常不灵活。</p><p>于是我们面向开发者和软件开发公司,做了一个 Ai 流程编排功能,结合知识库,通过拖动配置,很容易就能完成一个 Ai 的核心流程。</p><p>因此如果你需要开发 Ai 相关应用,这个可能会给你带来巨大的帮助。</p><p><img src="'+o+'" alt="流程编排" data-zoomable=""></p><div class="warning custom-block"><p class="custom-block-title">注意</p><p>Ai 流程编排+知识库需要单独购买,预售 999 元</p></div>',9),c=[s];function p(_,l,n,d,m,f){return t(),e("div",null,c)}const u=a(r,[["render",p]]);export{A as __pageData,u as default};
@@ -1 +1 @@
import{_ as a,c as e,o as t,a4 as i,a9 as o}from"./chunks/framework.BZ5u8Vj7.js";const A=JSON.parse('{"title":"Ai 流程编排","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/flow.md","filePath":"src/guide/flow.md","lastUpdated":1720593505000}'),r={name:"src/guide/flow.md"},s=i("",9),c=[s];function p(_,l,n,d,m,f){return t(),e("div",null,c)}const u=a(r,[["render",p]]);export{A as __pageData,u as default};
import{_ as a,c as e,o as t,a4 as i,a9 as o}from"./chunks/framework.BZ5u8Vj7.js";const A=JSON.parse('{"title":"Ai 流程编排","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/flow.md","filePath":"src/guide/flow.md","lastUpdated":1720847903000}'),r={name:"src/guide/flow.md"},s=i("",9),c=[s];function p(_,l,n,d,m,f){return t(),e("div",null,c)}const u=a(r,[["render",p]]);export{A as __pageData,u as default};
@@ -1,65 +1,145 @@
import{_ as s,c as i,o as a,a4 as n}from"./chunks/framework.BZ5u8Vj7.js";const y=JSON.parse('{"title":"扩展插件","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/plugin.md","filePath":"src/guide/plugin.md","lastUpdated":1720593505000}'),l={name:"src/guide/plugin.md"},t=n(`<h1 id="扩展插件" tabindex="-1">扩展插件 <a class="header-anchor" href="#扩展插件" aria-label="Permalink to &quot;扩展插件&quot;">​</a></h1><p>为了丰富系统功能,我们提供了插件系统,可以通过插件的方式来扩展系统功能。</p><p>而不用一味地堆功能,导致系统臃肿。你可以自己开发插件,也可以使用别人开发的插件。 或者通过官网<a href="https://cool-js.com/plugin/list.html" target="_blank" rel="noreferrer">下载插件</a>。</p><h2 id="使用插件" tabindex="-1">使用插件 <a class="header-anchor" href="#使用插件" aria-label="Permalink to &quot;使用插件&quot;">​</a></h2><h3 id="_1、安装" tabindex="-1">1、安装 <a class="header-anchor" href="#_1、安装" aria-label="Permalink to &quot;1、安装&quot;">​</a></h3><p>首先下载插件包,然后在系统中安装插件包。插件包可以通过官网<a href="https://cool-js.com/plugin/list.html" target="_blank" rel="noreferrer">下载插件</a>。</p><p>打开后台管理系统,点击左侧菜单扩展管理-&gt;插件管理,点击+按钮,选择插件包进行安装。</p><h3 id="_2、调用" tabindex="-1">2、调用 <a class="header-anchor" href="#_2、调用" aria-label="Permalink to &quot;2、调用&quot;">​</a></h3><p>安装插件之后,就可以在代码中调用插件的方法了。</p><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">package</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> com.cool.core;</span></span>
import{_ as s,c as i,o as a,a4 as n}from"./chunks/framework.BZ5u8Vj7.js";const y=JSON.parse('{"title":"扩展插件","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/plugin.md","filePath":"src/guide/plugin.md","lastUpdated":1720593505000}'),l={name:"src/guide/plugin.md"},p=n(`<h1 id="扩展插件" tabindex="-1">扩展插件 <a class="header-anchor" href="#扩展插件" aria-label="Permalink to &quot;扩展插件&quot;">​</a></h1><p>为了丰富系统功能,我们提供了插件系统,可以通过插件的方式来扩展系统功能。</p><p>而不用一味地堆功能,导致系统臃肿。你可以自己开发插件,也可以使用别人开发的插件。 或者通过官网<a href="https://cool-js.com/plugin/list.html" target="_blank" rel="noreferrer">下载插件</a>。</p><h2 id="使用插件" tabindex="-1">使用插件 <a class="header-anchor" href="#使用插件" aria-label="Permalink to &quot;使用插件&quot;">​</a></h2><h3 id="_1、安装" tabindex="-1">1、安装 <a class="header-anchor" href="#_1、安装" aria-label="Permalink to &quot;1、安装&quot;">​</a></h3><p>首先下载插件包,然后在系统中安装插件包。插件包可以通过官网<a href="https://cool-js.com/plugin/list.html" target="_blank" rel="noreferrer">下载插件</a>。</p><p>打开后台管理系统,点击左侧菜单扩展管理-&gt;插件管理,点击+按钮,选择插件包进行安装。</p><p>开发调试过程可使用指定目录,通过访问接口直接加载,无需再后台手动上传,方便调试</p><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">package</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> com.cool.core.base.controller;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> cn.hutool.core.util.ObjUtil;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> com.cool.core.plugin.service.CoolPluginService;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> jakarta.annotation.Resource;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> com.cool.core.util.ConvertUtil;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> com.cool.core.util.CoolPluginInvokers;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> java.io.File;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> lombok.RequiredArgsConstructor;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> org.springframework.stereotype.Controller;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> org.springframework.web.bind.annotation.PostMapping;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> org.springframework.web.bind.annotation.RequestMapping;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> org.springframework.web.bind.annotation.RequestParam;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> org.springframework.web.bind.annotation.RestController;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">RestController</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> JarLoaderController</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> org.springframework.web.bind.annotation.ResponseBody;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> org.springframework.web.multipart.MultipartFile;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">Resource</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CoolPluginService coolPluginService;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">Controller</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">RequiredArgsConstructor</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> CommonController</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">PostMapping</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;/loadJar/invokeMethod&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> String </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">invokeMethod</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">RequestParam</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> String </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">className</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">RequestParam</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> String </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">methodName</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">[] params </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">];</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> params[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">] </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;COOL&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Object result </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> coolPluginService.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">invokePlugin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;demoCoolPlugin&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, params);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> System.out.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">println</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(result);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;Dynamic method invoked successfully! Result: &quot;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> result;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> final</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CoolPluginService coolPluginService;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * 指定目录加载插件</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">PostMapping</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;/testPlugin/reload&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">ResponseBody</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> String </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">reload</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 替换掉自己插件编译的路径,无需在页面上上传</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> File file </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> File</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;/Users/mac/work/cool_new/cool-admin-java-plugin/target/my_cool_plugin.cool&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> MultipartFile multipartFile </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ConvertUtil.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">convertToMultipartFile</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(file);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> coolPluginService.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">install</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(multipartFile, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;reload Success&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>运行结果</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>2024-06-29T03:14:54.610+08:00 INFO 9158 --- [cool-admin-java] [nio-8001-exec-5] c.c.c.plugin.service.CoolPluginService : 调用插件类: demo-plugin, 方法: invokePlugin 参数: [[COOL, COOL1]]</span></span>
<span class="line"><span>汉字:COOL,拼音:COOL</span></span>
<span class="line"><span>2024-06-29T03:14:54.621+08:00 INFO 9158 --- [cool-admin-java] [nio-8001-exec-5] com.cool.core.plugin.BaseCoolPlugin : 调用主应用: coolCache, 方法: get 参数: [verify:img:4fd03504-47ac-4b57-b8e4-3c64059230d0]</span></span>
<span class="line"><span>缓存结果:vQV3</span></span></code></pre></div><p>对应插件内的方法</p><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">package</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> com.cool.plugin;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h3 id="_2、调用" tabindex="-1">2、调用 <a class="header-anchor" href="#_2、调用" aria-label="Permalink to &quot;2、调用&quot;">​</a></h3><p>安装插件之后,就可以在代码中调用插件的方法了。</p><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">package</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> com.cool.core.base.controller;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> cn.hutool.core.util.ObjUtil;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> com.cool.core.util.CoolPluginInvokers;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> lombok.RequiredArgsConstructor;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> org.springframework.stereotype.Controller;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> org.springframework.web.bind.annotation.PostMapping;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> org.springframework.web.bind.annotation.RequestMapping;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> org.springframework.web.bind.annotation.RequestParam;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> org.springframework.web.bind.annotation.ResponseBody;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">Controller</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">RequiredArgsConstructor</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> CommonController</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">PostMapping</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;/testPlugin/invokeMethod&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">ResponseBody</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> String </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">invokeMethod</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">RequestParam</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> String </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">key</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">RequestParam</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> String </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">methodName</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Object result </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (ObjUtil.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">isEmpty</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(methodName)) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> result </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CoolPluginInvokers.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">invokePlugin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(key);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">else</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> result </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CoolPluginInvokers.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">invokePlugin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(key, methodName);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> System.out.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">println</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(result);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;invokeMethod Result: &quot;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> result;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>运行结果</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>2024-07-13T20:01:18.543+08:00 INFO 32615 --- [cool-admin-java] [nio-8001-exec-5] com.cool.core.util.CoolPluginInvokers : 调用插件类: test, 方法: invokePlugin 参数: []</span></span>
<span class="line"><span>Hello invokePlugin</span></span>
<span class="line"><span>2024-07-13T20:01:18.543+08:00 DEBUG 32615 --- [cool-admin-java] [ task-5] c.c.m.b.m.sys.BaseSysLogMapper.insert : ==&gt; Preparing: INSERT INTO \`base_sys_log\`(\`action\`, \`ip\`, \`params\`, \`create_time\`, \`update_time\`) VALUES (?, ?, ?, now(), now())</span></span>
<span class="line"><span>2024-07-13T20:01:18.544+08:00 DEBUG 32615 --- [cool-admin-java] [ task-5] c.c.m.b.m.sys.BaseSysLogMapper.insert : ==&gt; Parameters: /testPlugin/invokeMethod(String), 127.0.0.1(String), {&quot;key&quot;:&quot;test&quot;}(String)</span></span>
<span class="line"><span>2024-07-13T20:01:18.554+08:00 DEBUG 32615 --- [cool-admin-java] [ task-5] c.c.m.b.m.sys.BaseSysLogMapper.insert : &lt;== Updates: 1</span></span>
<span class="line"><span>2024-07-13T20:01:18.557+08:00 INFO 32615 --- [cool-admin-java] [nio-8001-exec-5] com.cool.core.plugin.BaseCoolPlugin : 调用主应用: coolCache, 方法: set</span></span>
<span class="line"><span>2024-07-13T20:01:18.558+08:00 INFO 32615 --- [cool-admin-java] [nio-8001-exec-5] com.cool.core.plugin.BaseCoolPlugin : 调用主应用: coolCache, 方法: get</span></span>
<span class="line"><span>缓存结果:一个项目用COOL就够了</span></span>
<span class="line"><span>2024-07-13T20:01:18.559+08:00 INFO 32615 --- [cool-admin-java] [nio-8001-exec-5] com.cool.core.plugin.BaseCoolPlugin : 调用主应用: coolPluginService, 方法: getInstance</span></span>
<span class="line"><span>2024-07-13T20:01:18.564+08:00 INFO 32615 --- [cool-admin-java] [nio-8001-exec-5] com.cool.core.plugin.BaseCoolPlugin : 调用其他插件aliyun-oss, 方法: invokePlugin</span></span>
<span class="line"><span>{OSSAccessKeyId=LTAI5t8xtPD99YzSJQCC, signature=krlJ0Uv96TBliAgPJI/KyI=, success_action_status=200, host=https://xxx.oss-cn-hangzhou.aliyuncs.com, policy=eyJleHB0wNy0xM1QxMjowMTo0OC41NjVaIiwiY29uZGl0aW9ucyI6W1siY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsNTI0Mjg4MDBdXX0=}</span></span>
<span class="line"><span> ______ ___ ___ _____ _ ______ ____ ____ _____ ____ _____</span></span>
<span class="line"><span> .&#39; ___ | .&#39; \`. .&#39; \`.|_ _| V7.x / \\ |_ _ \`.|_ \\ / _||_ _||_ \\|_ _|</span></span>
<span class="line"><span>/ .&#39; \\_|/ .-. \\/ .-. \\ | | ______ / _ \\ | | \`. \\ | \\/ | | | | \\ | |</span></span>
<span class="line"><span>| | | | | || | | | | | _|______|/ ___ \\ | | | | | |\\ /| | | | | |\\ \\| |</span></span>
<span class="line"><span>\\ \`.___.&#39;\\\\ \`-&#39; /\\ \`-&#39; /_| |__/ | _/ / \\ \\_ _| |_.&#39; /_| |_\\/_| |_ _| |_ _| |_\\ |_</span></span>
<span class="line"><span> \`.____ .&#39; \`.___.&#39; \`.___.&#39;|________| |____| |____||______.&#39;|_____||_____||_____||_____|\\____|</span></span>
<span class="line"><span>:: https://java.cool-admin.com ::</span></span>
<span class="line"><span>Hello invokePlugin</span></span></code></pre></div><p>对应插件内的方法</p><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">package</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> com.cool.plugin;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> cn.hutool.core.io.IoUtil;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> cn.hutool.core.util.StrUtil;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> com.cool.core.annotation.CoolPlugin;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> com.cool.core.plugin.BaseCoolPlugin;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> net.sourceforge.pinyin4j.PinyinHelper;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> net.sourceforge.pinyin4j.format.HanyuPinyinToneType;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> java.io.InputStream;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> lombok.extern.slf4j.Slf4j;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">/**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * - 类必须要有 @CoolPlugin 注解,一个插件jar有且只能有一个类被 @CoolPlugin 注解</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * - 类必须继承 BaseCoolPlugin, 并实现 invokePlugin 插件方法</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * - 类必须继承 BaseCoolPlugin, 并实现 invokePlugin</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * 插件方法</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">Slf4j</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">CoolPlugin</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> DemoCoolPlugin</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> extends</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> BaseCoolPlugin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> MyCoolPlugin</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> extends</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> BaseCoolPlugin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">Override</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Object </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">invokePlugin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(String... </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">params</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> String chineseChar </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> params[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]; </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 汉字字符</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> HanyuPinyinOutputFormat format </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> HanyuPinyinOutputFormat</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> format.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setToneType</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(HanyuPinyinToneType.WITHOUT_TONE); </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 不带声调</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">Override</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Object </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">invokePlugin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(String... </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">params</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> System.out.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">println</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;Hello invokePlugin&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> useCache</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> usePlugin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getParentResource</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;Hello invokePlugin&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> String pinyin </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> pinyin </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> PinyinHelper.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">toHanyuPinyinString</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(chineseChar, format, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (BadHanyuPinyinOutputFormatCombination </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">e</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> throw</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> RuntimeException</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(e);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> System.out.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">println</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;汉字:&quot;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> chineseChar </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">+</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;,拼音:&quot;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> pinyin);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Object cache </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> invokeMain</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;coolCache&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;get&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;verify:img:4fd03504-47ac-4b57-b8e4-3c64059230d0&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> System.out.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">println</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;缓存结果:&quot;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> cache);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> String.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">format</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;hello,%s 我是插件&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, chineseChar);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * 使用缓存,使用cool-admin的缓存,开发的时候只是模拟</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> private</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> useCache</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 调用主应用设置缓存</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> invokeMain</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;coolCache&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;set&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;a&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;一个项目用COOL就够了&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 调用主应用获取缓存</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Object cache </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> invokeMain</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;coolCache&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;get&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;a&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> System.out.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">println</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;缓存结果:&quot;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> cache);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * 调用其他插件</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> private</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> usePlugin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 获得其他插件,开发的时候无法调试,只有安装到cool-admin中才能调试 xxx 为插件key</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Object result </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> invokeOtherPlugin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;aliyun-oss&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;invokePlugin&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> System.out.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">println</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(result);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * 获取主应用resources目录下的资源文件</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> private</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getParentResource</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ClassLoader classLoader </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getClass</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getClassLoader</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ClassLoader parentClassLoader </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> classLoader.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getParent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 获取主应用resources下的 banner.txt 文件内容</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> InputStream inputStream </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> parentClassLoader.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getResourceAsStream</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;banner.txt&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> System.out.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">println</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(StrUtil.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">str</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(IoUtil.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">readBytes</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(inputStream), </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;UTF-8&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">));</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>其中我们可以在插件包里通过 invokeMain 方法去调用主应用的一些对象方法</p><p>比如 coolCache 缓存对象, 通过反射实现</p><p>在加载jar包时会想该插件注入ApplicationContext,使得可以在插件中获取主应用中的bean</p><h3 id="_3、配置" tabindex="-1">3、配置 <a class="header-anchor" href="#_3、配置" aria-label="Permalink to &quot;3、配置&quot;">​</a></h3><p>有时候开发时的配置和生产环境的配置是不一样的,我们可以通过配置文件来实现。</p><p>例如原本的配置文件是这样的</p><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;appId&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;xxxxx&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;appSecret&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;xxxxx&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;filePath&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;classpath:cool/xxx.txt&quot;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>其中 classpath 为到resources资源目录下查找文件</p><h2 id="开发插件" tabindex="-1">开发插件 <a class="header-anchor" href="#开发插件" aria-label="Permalink to &quot;开发插件&quot;">​</a></h2><h3 id="_1、脚手架" tabindex="-1">1、脚手架 <a class="header-anchor" href="#_1、脚手架" aria-label="Permalink to &quot;1、脚手架&quot;">​</a></h3><p>为了方便开发插件和统一插件开发规范,我们提供了插件脚手架,可以快速开发我们的插件。</p><h3 id="_2、目录结构" tabindex="-1">2、目录结构 <a class="header-anchor" href="#_2、目录结构" aria-label="Permalink to &quot;2、目录结构&quot;">​</a></h3><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>.</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;filePath&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;banner.txt&quot;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>其中 banner.txt 为主应用resources资源目录下的文件,路径可以自己指定,范围在resources下</p><h2 id="开发插件" tabindex="-1">开发插件 <a class="header-anchor" href="#开发插件" aria-label="Permalink to &quot;开发插件&quot;">​</a></h2><h3 id="_1、脚手架" tabindex="-1">1、脚手架 <a class="header-anchor" href="#_1、脚手架" aria-label="Permalink to &quot;1、脚手架&quot;">​</a></h3><p>为了方便开发插件和统一插件开发规范,我们提供了插件脚手架,可以快速开发我们的插件。</p><h3 id="_2、目录结构" tabindex="-1">2、目录结构 <a class="header-anchor" href="#_2、目录结构" aria-label="Permalink to &quot;2、目录结构&quot;">​</a></h3><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>.</span></span>
<span class="line"><span>main</span></span>
<span class="line"><span>├─ java</span></span>
<span class="line"><span>│ └─ com.cool</span></span>
@@ -67,10 +147,14 @@ import{_ as s,c as i,o as a,a4 as n}from"./chunks/framework.BZ5u8Vj7.js";const y
<span class="line"><span>│ │ ├─ annotation </span></span>
<span class="line"><span>│ │ └─ ...</span></span>
<span class="line"><span>│ └─ plugin </span></span>
<span class="line"><span>│ └─ ...插件包,插件类放在这个包下</span></span>
<span class="line"><span>│ └─ MyCoolPlugin 插件包,插件类放在这个包下,在打包的时候选择要打包的插件,加上@CoolPlugin注解</span></span>
<span class="line"><span>├─ resources</span></span>
<span class="line"><span>│ └─ plugin.json 插件信息配置文件</span></span>
<span class="line"><span>└──pom.xml</span></span></code></pre></div><h3 id="_3、开发过程" tabindex="-1">3、开发过程 <a class="header-anchor" href="#_3、开发过程" aria-label="Permalink to &quot;3、开发过程&quot;">​</a></h3><ul><li>配置插件信息(plugin.json)</li></ul><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
<span class="line"><span>test</span></span>
<span class="line"><span>│</span></span>
<span class="line"><span>│─ java</span></span>
<span class="line"><span>│ └─ com.cool.plugin</span></span>
<span class="line"><span>│ └─ MyCoolPluginTest 插件运行测试类</span></span></code></pre></div><h3 id="_3、开发过程" tabindex="-1">3、开发过程 <a class="header-anchor" href="#_3、开发过程" aria-label="Permalink to &quot;3、开发过程&quot;">​</a></h3><ul><li>配置插件信息(plugin.json)</li></ul><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;name&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;测试&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;key&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;demo-plugin&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;hook&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
@@ -115,11 +199,20 @@ import{_ as s,c as i,o as a,a4 as n}from"./chunks/framework.BZ5u8Vj7.js";const y
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Object cache </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> invokeMain</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;coolCache&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;get&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;verify:img:4fd03504-47ac-4b57-b8e4-3c64059230d0&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> String.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">format</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;hello,%s 我是插件&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, chineseChar);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><ul><li>类必须要有 @CoolPlugin 注解,一个插件jar有且只能有一个类被 @CoolPlugin 注解</li><li>类必须继承 BaseCoolPlugin, 并实现 invokePlugin 插件方法 满足以上条件,在插件导入时才能被识别到。</li></ul><p>在开发过程中如果需要引入第三方类库,可使用maven引入依赖,如我们这边示例使用到了中文转拼音</p><div class="language-xml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">xml</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">dependency</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><ul><li>类必须要有 @CoolPlugin 注解,一个插件jar有且只能有一个类被 @CoolPlugin 注解</li><li>类必须继承 BaseCoolPlugin, 并实现 invokePlugin 插件方法 满足以上条件,在插件导入时才能被识别到。<br> 在提供的插件脚手架中已经应用了常用的依赖如hutool等<br> 在开发过程中如果需要引入第三方类库,可使用maven引入依赖,如我们这边示例使用到了中文转拼音</li></ul><div class="language-xml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">xml</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">dependency</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">groupId</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;cn.hutool&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">groupId</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">artifactId</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;hutool-all&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">artifactId</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">version</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;5.8.26&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">version</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">dependency</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">&lt;!--***以上包在主应用已经引入,避免插件过大不会在打入jar包中***--&gt;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">&lt;!--***为了开发插件如果引入了主应用已经有的maven依赖可以在下面的 maven-shade-plugin 中排除掉不打入jar***--&gt;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">&lt;!--以下包会打入jar,主应用没有这些依赖,不然调用时会报错--&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">dependency</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">groupId</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;com.belerweb&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">groupId</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">artifactId</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;pinyin4j&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">artifactId</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">version</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;2.5.0&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">version</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">dependency</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span></code></pre></div><p>在我们脚手架上你可以发现,我们还引入了其他包 springframework、hutool 等,这会使得打包结果很臃肿,这边使用到了 maven-shade-plugin maven插件可以在打包的时候将在我们 cool-admin-java 主应用项目已经有的依赖给排除掉,避免打包结果过大</p><div class="language-xml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">xml</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">build</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">dependency</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span></code></pre></div><p>在我们脚手架上你可以发现,我们还引入了其他包 springframework、hutool 等,这会使得打包结果很臃肿,这边使用到了 maven-shade-plugin maven插件可以在打包的时候将在我们 cool-admin-java 主应用项目已经有的依赖给排除掉,避免打包结果过大</p><div class="language-xml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">xml</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">&lt;!--***为了开发插件如果引入了主应用已经有的maven依赖可以在下面的 maven-shade-plugin 中排除掉不打入jar***--&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">build</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">plugins</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">plugin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">groupId</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;org.apache.maven.plugins&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">groupId</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
@@ -172,5 +265,7 @@ import{_ as s,c as i,o as a,a4 as n}from"./chunks/framework.BZ5u8Vj7.js";const y
<span class="line"><span>[INFO] Excluding org.slf4j:slf4j-api:jar:2.0.13 from the shaded jar.</span></span>
<span class="line"><span>[INFO] Excluding org.projectlombok:lombok:jar:1.18.32 from the shaded jar.</span></span>
<span class="line"><span>[INFO] Excluding cn.hutool:hutool-core:jar:5.8.26 from the shaded jar.</span></span>
<span class="line"><span>[INFO] Excluding cn.hutool:hutool-json:jar:5.8.26 from the shaded jar.</span></span></code></pre></div><h2 id="打包" tabindex="-1">打包 <a class="header-anchor" href="#打包" aria-label="Permalink to &quot;打包&quot;">​</a></h2><p>打包命令</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>mvn clean package</span></span></code></pre></div><p>打包结果, 在 target目录下 .cool后缀的文件,就是我们的插件包</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>target/cool-admin-java-plugin-1.0-SNAPSHOT.cool</span></span></code></pre></div><h2 id="安装插件" tabindex="-1">安装插件 <a class="header-anchor" href="#安装插件" aria-label="Permalink to &quot;安装插件&quot;">​</a></h2><p>在后台插件管理页面,安装插件将打包好的.cool文件上传。</p><h2 id="实现原理" tabindex="-1">实现原理 <a class="header-anchor" href="#实现原理" aria-label="Permalink to &quot;实现原理&quot;">​</a></h2><ul><li>动态加载 Jar 包</li></ul><blockquote><p>实现动态加载的技术方案<br> 在 SpringBoot 中实现动态加载 Jar 包: URLClassLoader 是 Java 标准库中提供的一个类加载器,它可以加载指定的 URL 资源,包括本地文件系统、远程服务器和 JAR 文件等。<br> 通过 URLClassLoader,我们可以在运行时动态地加载外部的 Jar 包或类。</p></blockquote><ul><li>优势:</li></ul><blockquote><p>1、灵活性高:可以动态指定 Jar 包的位置和版本。<br> 2、可控性强:可以通过代码控制加载、卸载和替换 Jar 包。</p></blockquote><p>实现方法:</p><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">URL jarUrl </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> URL</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;jar:file:&quot;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> +</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> File</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(jarFilePath).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getAbsolutePath</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">+</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;!/&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">DynamicJarClassLoader dynamicJarClassLoader </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> DynamicJarClassLoader</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">new</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> URL</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">[]{jarUrl}, Thread.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">currentThread</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getContextClassLoader</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">());</span></span></code></pre></div><p>动态加载 Jar 包具有以下几个显著的优势:</p><ul><li>1、灵活性: 动态加载允许应用程序在运行时根据需求加载、卸载和替换 Jar 包或其内部的类和资源,提供了极大的灵活性。</li><li>2、可维护性: 通过动态加载,可以将应用程序的核心逻辑和配置分离,使得代码更加清晰、模块化,提高了代码的可维护性。</li><li>3、热更新: 动态加载使得应用程序能够在不停机的情况下进行热更新,大大提高了系统的可用性和稳定性。</li><li>4、扩展性: 通过动态加载,可以轻松地添加新的功能模块或服务,实现应用程序的快速扩展和升级。</li></ul>`,59),h=[t];function p(k,e,E,r,d,g){return a(),i("div",null,h)}const c=s(l,[["render",p]]);export{y as __pageData,c as default};
<span class="line"><span>[INFO] Excluding cn.hutool:hutool-json:jar:5.8.26 from the shaded jar.</span></span></code></pre></div><h2 id="打包" tabindex="-1">打包 <a class="header-anchor" href="#打包" aria-label="Permalink to &quot;打包&quot;">​</a></h2><p>打包命令</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>mvn clean package</span></span></code></pre></div><p>打包结果, 在 target目录下 .cool后缀的文件,就是我们的插件包</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>target/cool-admin-java-plugin-1.0-SNAPSHOT.cool</span></span></code></pre></div><p>其中对应的包名称 可在pom.xml中的properties里指定</p><div class="language-xml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">xml</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">properties</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">cool.plugin.name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;my_cool_plugin&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">cool.plugin.name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">properties</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span></code></pre></div><p>最终打出的包为: my_cool_plugin.cool</p><h2 id="安装插件" tabindex="-1">安装插件 <a class="header-anchor" href="#安装插件" aria-label="Permalink to &quot;安装插件&quot;">​</a></h2><p>在后台插件管理页面,安装插件将打包好的.cool文件上传。</p><h2 id="实现原理" tabindex="-1">实现原理 <a class="header-anchor" href="#实现原理" aria-label="Permalink to &quot;实现原理&quot;">​</a></h2><ul><li>动态加载 Jar 包</li></ul><blockquote><p>实现动态加载的技术方案<br> 在 SpringBoot 中实现动态加载 Jar 包: URLClassLoader 是 Java 标准库中提供的一个类加载器,它可以加载指定的 URL 资源,包括本地文件系统、远程服务器和 JAR 文件等。<br> 通过 URLClassLoader,我们可以在运行时动态地加载外部的 Jar 包或类。</p></blockquote><ul><li>优势:</li></ul><blockquote><p>1、灵活性高:可以动态指定 Jar 包的位置和版本。<br> 2、可控性强:可以通过代码控制加载、卸载和替换 Jar 包。</p></blockquote><p>实现方法:</p><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">URL jarUrl </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> URL</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;jar:file:&quot;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> +</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> File</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(jarFilePath).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getAbsolutePath</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">+</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;!/&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">DynamicJarClassLoader dynamicJarClassLoader </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> DynamicJarClassLoader</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">new</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> URL</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">[]{jarUrl}, Thread.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">currentThread</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getContextClassLoader</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">());</span></span></code></pre></div><p>动态加载 Jar 包具有以下几个显著的优势:</p><ul><li>1、灵活性: 动态加载允许应用程序在运行时根据需求加载、卸载和替换 Jar 包或其内部的类和资源,提供了极大的灵活性。</li><li>2、可维护性: 通过动态加载,可以将应用程序的核心逻辑和配置分离,使得代码更加清晰、模块化,提高了代码的可维护性。</li><li>3、热更新: 动态加载使得应用程序能够在不停机的情况下进行热更新,大大提高了系统的可用性和稳定性。</li><li>4、扩展性: 通过动态加载,可以轻松地添加新的功能模块或服务,实现应用程序的快速扩展和升级。</li></ul>`,63),t=[p];function h(k,e,E,r,g,d){return a(),i("div",null,t)}const c=s(l,[["render",h]]);export{y as __pageData,c as default};
@@ -1 +1 @@
import{_ as s,c as i,o as a,a4 as n}from"./chunks/framework.BZ5u8Vj7.js";const y=JSON.parse('{"title":"扩展插件","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/plugin.md","filePath":"src/guide/plugin.md","lastUpdated":1720593505000}'),l={name:"src/guide/plugin.md"},t=n("",59),h=[t];function p(k,e,E,r,d,g){return a(),i("div",null,h)}const c=s(l,[["render",p]]);export{y as __pageData,c as default};
import{_ as s,c as i,o as a,a4 as n}from"./chunks/framework.BZ5u8Vj7.js";const y=JSON.parse('{"title":"扩展插件","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/plugin.md","filePath":"src/guide/plugin.md","lastUpdated":1720593505000}'),l={name:"src/guide/plugin.md"},p=n("",63),t=[p];function h(k,e,E,r,g,d){return a(),i("div",null,t)}const c=s(l,[["render",h]]);export{y as __pageData,c as default};
@@ -1 +1 @@
import{_ as l,c as a,o as e,a4 as t,aa as i,a9 as o}from"./chunks/framework.BZ5u8Vj7.js";const f=JSON.parse('{"title":"简介","description":"","frontmatter":{},"headers":[],"relativePath":"src/introduce/index.md","filePath":"src/introduce/index.md","lastUpdated":1720593505000}'),r={name:"src/introduce/index.md"},n=t('<h1 id="简介" tabindex="-1">简介 <a class="header-anchor" href="#简介" aria-label="Permalink to &quot;简介&quot;">​</a></h1><p><img src="'+i+'" alt="" data-zoomable=""></p><h2 id="技术选型" tabindex="-1">技术选型 <a class="header-anchor" href="#技术选型" aria-label="Permalink to &quot;技术选型&quot;">​</a></h2><p>1、系统环境</p><ul><li>Java Jdk &gt;= 17 选择 graalvm</li><li>Mysql &gt;= 5.7</li><li>Maven &gt;= 3.0</li></ul><p>2、主要框架</p><ul><li>Spring Boot 3.2.5</li><li>Spring Framework 6.1.6</li><li>Mybatis Flex 1.9.3(新版本替换: Mybatis Plus)</li><li>Auto Table 1.7.4</li><li>Spring Doc 2.5.0</li></ul><h2 id="为什么选择-cool-admin" tabindex="-1">为什么选择 Cool Admin? <a class="header-anchor" href="#为什么选择-cool-admin" aria-label="Permalink to &quot;为什么选择 Cool Admin?&quot;">​</a></h2><p>随着技术不断地发展,特别是最近 Ai 相关的技术发展,以往的框架已经越来越不能满足现代化的开发需求。</p><p>Cool Admin 做为后来者有后发优势,主要特点:</p><ul><li>Ai 编码,从页面到后端代码,部分功能实现零代码;</li><li>Ai 流程编排,专门为 Ai 开发设计的,Ai 开发几乎不用写代码,只需拖一拖即可;</li><li>扩展插件,可插拔,如支付、短信这类功能的插件可以通过后台动态安装卸载,灵活又不臃肿;</li><li>代码简洁,不像一般代码生成器生成一堆冗余代码,Cool 只需极少编码即可实现大部分需求;</li><li>......</li></ul><p><img src="'+i+'" alt="" data-zoomable=""></p><p><img src="'+o+'" alt="" data-zoomable=""></p><h2 id="内置功能" tabindex="-1">内置功能 <a class="header-anchor" href="#内置功能" aria-label="Permalink to &quot;内置功能&quot;">​</a></h2><ul><li>用户管理:呈现公司组织部门树形结构,用户是系统操作者,该功能主要完成系统用户配置。</li><li>菜单管理:配置系统菜单,操作权限标识等。</li><li>角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。</li><li>参数管理:对系统动态配置常用参数。</li><li>字典管理:对系统中经常使用的一些较为固定的数据进行维护。</li><li>请求日志:接口的请求入参日志,便于问题排查。</li><li>操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。</li><li>定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。</li><li>文件管理:支持静态资源文件上传云端进行云管理。</li><li>数据回收站:数据有 30 天的保留,支持回滚操作。</li><li>前后端插件:支持动态安装、卸载插件,实现功能可插拔。(后端插件开发中...)</li></ul>',15),s=[n];function d(c,p,_,m,h,u){return e(),a("div",null,s)}const x=l(r,[["render",d]]);export{f as __pageData,x as default};
import{_ as l,c as a,o as e,a4 as t,aa as i,a9 as o}from"./chunks/framework.BZ5u8Vj7.js";const f=JSON.parse('{"title":"简介","description":"","frontmatter":{},"headers":[],"relativePath":"src/introduce/index.md","filePath":"src/introduce/index.md","lastUpdated":1720847903000}'),r={name:"src/introduce/index.md"},n=t('<h1 id="简介" tabindex="-1">简介 <a class="header-anchor" href="#简介" aria-label="Permalink to &quot;简介&quot;">​</a></h1><p><img src="'+i+'" alt="" data-zoomable=""></p><h2 id="技术选型" tabindex="-1">技术选型 <a class="header-anchor" href="#技术选型" aria-label="Permalink to &quot;技术选型&quot;">​</a></h2><p>1、系统环境</p><ul><li>Java Jdk &gt;= 17 选择 graalvm</li><li>Mysql &gt;= 5.7</li><li>Maven &gt;= 3.0</li></ul><p>2、主要框架</p><ul><li>Spring Boot 3.2.5</li><li>Spring Framework 6.1.6</li><li>Mybatis Flex 1.9.3(新版本替换: Mybatis Plus)</li><li>Auto Table 1.7.4</li><li>Spring Doc 2.5.0</li></ul><h2 id="为什么选择-cool-admin" tabindex="-1">为什么选择 Cool Admin? <a class="header-anchor" href="#为什么选择-cool-admin" aria-label="Permalink to &quot;为什么选择 Cool Admin?&quot;">​</a></h2><p>随着技术不断地发展,特别是最近 Ai 相关的技术发展,以往的框架已经越来越不能满足现代化的开发需求。</p><p>Cool Admin 做为后来者有后发优势,主要特点:</p><ul><li>Ai 编码,从页面到后端代码,部分功能实现零代码;</li><li>Ai 流程编排,专门为 Ai 开发设计的,Ai 开发几乎不用写代码,只需拖一拖即可;</li><li>扩展插件,可插拔,如支付、短信这类功能的插件可以通过后台动态安装卸载,灵活又不臃肿;</li><li>代码简洁,不像一般代码生成器生成一堆冗余代码,Cool 只需极少编码即可实现大部分需求;</li><li>......</li></ul><p><img src="'+i+'" alt="" data-zoomable=""></p><p><img src="'+o+'" alt="" data-zoomable=""></p><h2 id="内置功能" tabindex="-1">内置功能 <a class="header-anchor" href="#内置功能" aria-label="Permalink to &quot;内置功能&quot;">​</a></h2><ul><li>用户管理:呈现公司组织部门树形结构,用户是系统操作者,该功能主要完成系统用户配置。</li><li>菜单管理:配置系统菜单,操作权限标识等。</li><li>角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。</li><li>参数管理:对系统动态配置常用参数。</li><li>字典管理:对系统中经常使用的一些较为固定的数据进行维护。</li><li>请求日志:接口的请求入参日志,便于问题排查。</li><li>操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。</li><li>定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。</li><li>文件管理:支持静态资源文件上传云端进行云管理。</li><li>数据回收站:数据有 30 天的保留,支持回滚操作。</li><li>前后端插件:支持动态安装、卸载插件,实现功能可插拔。(后端插件开发中...)</li></ul>',15),s=[n];function d(c,p,_,m,h,u){return e(),a("div",null,s)}const x=l(r,[["render",d]]);export{f as __pageData,x as default};
@@ -1 +1 @@
import{_ as l,c as a,o as e,a4 as t,aa as i,a9 as o}from"./chunks/framework.BZ5u8Vj7.js";const f=JSON.parse('{"title":"简介","description":"","frontmatter":{},"headers":[],"relativePath":"src/introduce/index.md","filePath":"src/introduce/index.md","lastUpdated":1720593505000}'),r={name:"src/introduce/index.md"},n=t("",15),s=[n];function d(c,p,_,m,h,u){return e(),a("div",null,s)}const x=l(r,[["render",d]]);export{f as __pageData,x as default};
import{_ as l,c as a,o as e,a4 as t,aa as i,a9 as o}from"./chunks/framework.BZ5u8Vj7.js";const f=JSON.parse('{"title":"简介","description":"","frontmatter":{},"headers":[],"relativePath":"src/introduce/index.md","filePath":"src/introduce/index.md","lastUpdated":1720847903000}'),r={name:"src/introduce/index.md"},n=t("",15),s=[n];function d(c,p,_,m,h,u){return e(),a("div",null,s)}const x=l(r,[["render",d]]);export{f as __pageData,x as default};
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"index.md":"CAVf4Oqs","readme.md":"OcZ1dgrk","src_about_index.md":"BcF27jYK","src_guide_ai.md":"Gsy5t_8S","src_guide_cache.md":"BOJv_Che","src_guide_controller.md":"r2nPGOST","src_guide_exception.md":"m-_TuVSi","src_guide_flow.md":"DerjmfqW","src_guide_generatorcode.md":"vZguykgt","src_guide_initdata.md":"CSiXmFuQ","src_guide_plugin.md":"YnHghnwg","src_guide_quick.md":"Dd-HcOh7","src_guide_security.md":"BubSrMYS","src_guide_springboot3.md":"_tGrFUv8","src_guide_swagger.md":"BS_bARv2","src_guide_upload.md":"Bq5siQ0E","src_introduce_index.md":"DvEK5WJI","src_introduce_show.md":"DSZevIGP","src_introduce_src.md":"pd2vUss-","src_question_commonquestion.md":"CeHvXEMU","src_todo_plan.md":"bhlKWKsq","src_todo_update.md":"qtvh9HZG"}
{"index.md":"CAVf4Oqs","readme.md":"BXdrAVTM","src_about_index.md":"BcF27jYK","src_guide_ai.md":"Gsy5t_8S","src_guide_cache.md":"BOJv_Che","src_guide_controller.md":"r2nPGOST","src_guide_exception.md":"m-_TuVSi","src_guide_flow.md":"DPOXSEzV","src_guide_generatorcode.md":"vZguykgt","src_guide_initdata.md":"CSiXmFuQ","src_guide_plugin.md":"jVCi1KWQ","src_guide_quick.md":"Dd-HcOh7","src_guide_security.md":"BubSrMYS","src_guide_springboot3.md":"_tGrFUv8","src_guide_swagger.md":"BS_bARv2","src_guide_upload.md":"Bq5siQ0E","src_introduce_index.md":"CXfKVW0H","src_introduce_show.md":"DSZevIGP","src_introduce_src.md":"pd2vUss-","src_question_commonquestion.md":"CeHvXEMU","src_todo_plan.md":"bhlKWKsq","src_todo_update.md":"qtvh9HZG"}
+5 -5
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+5 -5
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+148 -53
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+5 -5
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+156 -48
View File
@@ -9,41 +9,102 @@
### 1、安装
首先下载插件包,然后在系统中安装插件包。插件包可以通过官网[下载插件](https://cool-js.com/plugin/list.html)。
打开后台管理系统,点击左侧菜单扩展管理->插件管理,点击+按钮,选择插件包进行安装。
打开后台管理系统,点击左侧菜单扩展管理->插件管理,点击+按钮,选择插件包进行安装。
开发调试过程可使用指定目录,通过访问接口直接加载,无需再后台手动上传,方便调试
```java
package com.cool.core.base.controller;
import cn.hutool.core.util.ObjUtil;
import com.cool.core.plugin.service.CoolPluginService;
import com.cool.core.util.ConvertUtil;
import com.cool.core.util.CoolPluginInvokers;
import java.io.File;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
@Controller
@RequiredArgsConstructor
public class CommonController {
final private CoolPluginService coolPluginService;
/**
* 指定目录加载插件
*/
@PostMapping("/testPlugin/reload")
@ResponseBody
public String reload() {
// 替换掉自己插件编译的路径,无需在页面上上传
File file = new File(
"/Users/mac/work/cool_new/cool-admin-java-plugin/target/my_cool_plugin.cool");
MultipartFile multipartFile = ConvertUtil.convertToMultipartFile(file);
coolPluginService.install(multipartFile, true);
return "reload Success";
}
}
```
### 2、调用
安装插件之后,就可以在代码中调用插件的方法了。
```java
package com.cool.core;
package com.cool.core.base.controller;
import com.cool.core.plugin.service.CoolPluginService;
import jakarta.annotation.Resource;
import cn.hutool.core.util.ObjUtil;
import com.cool.core.util.CoolPluginInvokers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class JarLoaderController {
import org.springframework.web.bind.annotation.ResponseBody;
@Resource
private CoolPluginService coolPluginService;
@Controller
@RequiredArgsConstructor
public class CommonController {
@PostMapping("/loadJar/invokeMethod")
public String invokeMethod(@RequestParam String className, @RequestParam String methodName) {
String[] params = new String[1];
params[0] = "COOL";
Object result = coolPluginService.invokePlugin("demoCoolPlugin", params);
System.out.println(result);
return "Dynamic method invoked successfully! Result: " + result;
@PostMapping("/testPlugin/invokeMethod")
@ResponseBody
public String invokeMethod(@RequestParam String key, @RequestParam String methodName) {
Object result = null;
if (ObjUtil.isEmpty(methodName)) {
result = CoolPluginInvokers.invokePlugin(key);
} else {
result = CoolPluginInvokers.invokePlugin(key, methodName);
}
System.out.println(result);
return "invokeMethod Result: " + result;
}
}
```
运行结果
```
2024-06-29T03:14:54.610+08:00 INFO 9158 --- [cool-admin-java] [nio-8001-exec-5] c.c.c.plugin.service.CoolPluginService : 调用插件类: demo-plugin, 方法: invokePlugin 参数: [[COOL, COOL1]]
汉字:COOL,拼音:COOL
2024-06-29T03:14:54.621+08:00 INFO 9158 --- [cool-admin-java] [nio-8001-exec-5] com.cool.core.plugin.BaseCoolPlugin : 调用主应用: coolCache, 方法: get 参数: [verify:img:4fd03504-47ac-4b57-b8e4-3c64059230d0]
缓存结果:vQV3
2024-07-13T20:01:18.543+08:00 INFO 32615 --- [cool-admin-java] [nio-8001-exec-5] com.cool.core.util.CoolPluginInvokers : 调用插件类: test, 方法: invokePlugin 参数: []
Hello invokePlugin
2024-07-13T20:01:18.543+08:00 DEBUG 32615 --- [cool-admin-java] [ task-5] c.c.m.b.m.sys.BaseSysLogMapper.insert : ==> Preparing: INSERT INTO `base_sys_log`(`action`, `ip`, `params`, `create_time`, `update_time`) VALUES (?, ?, ?, now(), now())
2024-07-13T20:01:18.544+08:00 DEBUG 32615 --- [cool-admin-java] [ task-5] c.c.m.b.m.sys.BaseSysLogMapper.insert : ==> Parameters: /testPlugin/invokeMethod(String), 127.0.0.1(String), {"key":"test"}(String)
2024-07-13T20:01:18.554+08:00 DEBUG 32615 --- [cool-admin-java] [ task-5] c.c.m.b.m.sys.BaseSysLogMapper.insert : <== Updates: 1
2024-07-13T20:01:18.557+08:00 INFO 32615 --- [cool-admin-java] [nio-8001-exec-5] com.cool.core.plugin.BaseCoolPlugin : 调用主应用: coolCache, 方法: set
2024-07-13T20:01:18.558+08:00 INFO 32615 --- [cool-admin-java] [nio-8001-exec-5] com.cool.core.plugin.BaseCoolPlugin : 调用主应用: coolCache, 方法: get
缓存结果:一个项目用COOL就够了
2024-07-13T20:01:18.559+08:00 INFO 32615 --- [cool-admin-java] [nio-8001-exec-5] com.cool.core.plugin.BaseCoolPlugin : 调用主应用: coolPluginService, 方法: getInstance
2024-07-13T20:01:18.564+08:00 INFO 32615 --- [cool-admin-java] [nio-8001-exec-5] com.cool.core.plugin.BaseCoolPlugin : 调用其他插件aliyun-oss, 方法: invokePlugin
{OSSAccessKeyId=LTAI5t8xtPD99YzSJQCC, signature=krlJ0Uv96TBliAgPJI/KyI=, success_action_status=200, host=https://xxx.oss-cn-hangzhou.aliyuncs.com, policy=eyJleHB0wNy0xM1QxMjowMTo0OC41NjVaIiwiY29uZGl0aW9ucyI6W1siY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsNTI0Mjg4MDBdXX0=}
______ ___ ___ _____ _ ______ ____ ____ _____ ____ _____
.' ___ | .' `. .' `.|_ _| V7.x / \ |_ _ `.|_ \ / _||_ _||_ \|_ _|
/ .' \_|/ .-. \/ .-. \ | | ______ / _ \ | | `. \ | \/ | | | | \ | |
| | | | | || | | | | | _|______|/ ___ \ | | | | | |\ /| | | | | |\ \| |
\ `.___.'\\ `-' /\ `-' /_| |__/ | _/ / \ \_ _| |_.' /_| |_\/_| |_ _| |_ _| |_\ |_
`.____ .' `.___.' `.___.'|________| |____| |____||______.'|_____||_____||_____||_____|\____|
:: https://java.cool-admin.com ::
Hello invokePlugin
```
对应插件内的方法
@@ -51,37 +112,62 @@ public class JarLoaderController {
```java
package com.cool.plugin;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.cool.core.annotation.CoolPlugin;
import com.cool.core.plugin.BaseCoolPlugin;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import java.io.InputStream;
import lombok.extern.slf4j.Slf4j;
/**
* - 类必须要有 @CoolPlugin 注解,一个插件jar有且只能有一个类被 @CoolPlugin 注解
* - 类必须继承 BaseCoolPlugin, 并实现 invokePlugin 插件方法
* - 类必须继承 BaseCoolPlugin, 并实现 invokePlugin
* 插件方法
*/
@Slf4j
@CoolPlugin
public class DemoCoolPlugin extends BaseCoolPlugin {
public class MyCoolPlugin extends BaseCoolPlugin {
@Override
public Object invokePlugin(String... params) {
String chineseChar = params[0]; // 汉字字符
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); // 不带声调
@Override
public Object invokePlugin(String... params) {
System.out.println("Hello invokePlugin");
useCache();
usePlugin();
getParentResource();
return "Hello invokePlugin";
}
String pinyin = null;
try {
pinyin = PinyinHelper.toHanyuPinyinString(chineseChar, format, "");
} catch (BadHanyuPinyinOutputFormatCombination e) {
throw new RuntimeException(e);
}
System.out.println("汉字:" + chineseChar + ",拼音:" + pinyin);
Object cache = invokeMain("coolCache", "get", "verify:img:4fd03504-47ac-4b57-b8e4-3c64059230d0");
System.out.println("缓存结果:" + cache);
return String.format("hello,%s 我是插件", chineseChar);
}
/**
* 使用缓存,使用cool-admin的缓存,开发的时候只是模拟
*/
private void useCache() {
// 调用主应用设置缓存
invokeMain("coolCache", "set", "a", "一个项目用COOL就够了");
// 调用主应用获取缓存
Object cache =
invokeMain("coolCache", "get", "a");
System.out.println("缓存结果:" + cache);
}
/**
* 调用其他插件
*/
private void usePlugin() {
// 获得其他插件,开发的时候无法调试,只有安装到cool-admin中才能调试 xxx 为插件key
Object result = invokeOtherPlugin("aliyun-oss", "invokePlugin");
System.out.println(result);
}
/**
* 获取主应用resources目录下的资源文件
*/
private void getParentResource() {
ClassLoader classLoader = getClass().getClassLoader();
ClassLoader parentClassLoader = classLoader.getParent();
// 获取主应用resources下的 banner.txt 文件内容
InputStream inputStream = parentClassLoader.getResourceAsStream("banner.txt");
System.out.println(StrUtil.str(IoUtil.readBytes(inputStream), "UTF-8"));
}
}
```
其中我们可以在插件包里通过 invokeMain 方法去调用主应用的一些对象方法
@@ -98,10 +184,10 @@ public class DemoCoolPlugin extends BaseCoolPlugin {
{
"appId": "xxxxx",
"appSecret": "xxxxx",
"filePath": "classpath:cool/xxx.txt"
"filePath": "banner.txt"
}
```
其中 classpath 为到resources资源目录下查找文件
其中 banner.txt 为主应用resources资源目录下的文件,路径可以自己指定,范围在resources下
## 开发插件
### 1、脚手架
@@ -117,10 +203,15 @@ main
│ │ ├─ annotation
│ │ └─ ...
│ └─ plugin
│ └─ ...插件包,插件类放在这个包下
│ └─ MyCoolPlugin 插件包,插件类放在这个包下,在打包的时候选择要打包的插件,加上@CoolPlugin注解
├─ resources
│ └─ plugin.json 插件信息配置文件
└──pom.xml
test
│
│─ java
│ └─ com.cool.plugin
│ └─ MyCoolPluginTest 插件运行测试类
```
### 3、开发过程
- 配置插件信息(plugin.json)
@@ -196,10 +287,18 @@ public class DemoCoolPlugin extends BaseCoolPlugin {
- 类必须要有 @CoolPlugin 注解,一个插件jar有且只能有一个类被 @CoolPlugin 注解
- 类必须继承 BaseCoolPlugin, 并实现 invokePlugin 插件方法
满足以上条件,在插件导入时才能被识别到。
满足以上条件,在插件导入时才能被识别到。
在提供的插件脚手架中已经应用了常用的依赖如hutool等
在开发过程中如果需要引入第三方类库,可使用maven引入依赖,如我们这边示例使用到了中文转拼音
```xml
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.26</version>
</dependency>
<!--***以上包在主应用已经引入,避免插件过大不会在打入jar包中***-->
<!--***为了开发插件如果引入了主应用已经有的maven依赖可以在下面的 maven-shade-plugin 中排除掉不打入jar***-->
<!--以下包会打入jar,主应用没有这些依赖,不然调用时会报错-->
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
@@ -210,6 +309,7 @@ public class DemoCoolPlugin extends BaseCoolPlugin {
maven-shade-plugin maven插件可以在打包的时候将在我们 cool-admin-java 主应用项目已经有的依赖给排除掉,避免打包结果过大
```xml
<!--***为了开发插件如果引入了主应用已经有的maven依赖可以在下面的 maven-shade-plugin 中排除掉不打入jar***-->
<build>
<plugins>
<plugin>
@@ -282,6 +382,14 @@ mvn clean package
target/cool-admin-java-plugin-1.0-SNAPSHOT.cool
```
其中对应的包名称 可在pom.xml中的properties里指定
```xml
<properties>
<cool.plugin.name>my_cool_plugin</cool.plugin.name>
</properties>
```
最终打出的包为: my_cool_plugin.cool
## 安装插件
在后台插件管理页面,安装插件将打包好的.cool文件上传。