From 457a53e131d47868913f9c91f1e40f106d3e5b47 Mon Sep 17 00:00:00 2001 From: wangxw Date: Tue, 12 Dec 2023 19:18:23 +0800 Subject: [PATCH] 'init' --- .gitignore | 4 +- HELP.md | 19 +++ plugin/lib/jar.txt | 0 pom.xml | 108 ++++++++++++++++++ .../plugin/PluginManagerApplication.java | 33 ++++++ .../example/plugin/controller/Controller.java | 39 +++++++ .../plugin/demos/web/BasicController.java | 67 +++++++++++ .../demos/web/PathVariableController.java | 44 +++++++ .../com/example/plugin/demos/web/User.java | 43 +++++++ .../example/plugin/properties/SystemEnv.java | 19 +++ .../com/example/plugin/run/StartInit.java | 21 ++++ .../plugin/utils/PluginClassLoader.java | 16 +++ .../com/example/plugin/utils/PluginUtils.java | 66 +++++++++++ src/main/resources/application-dev.yml | 3 + src/main/resources/application-test.yml | 3 + src/main/resources/application.yml | 14 +++ src/main/resources/static/index.html | 6 + .../plugin/PluginManagerApplicationTests.java | 13 +++ 18 files changed, 517 insertions(+), 1 deletion(-) create mode 100644 HELP.md create mode 100644 plugin/lib/jar.txt create mode 100644 pom.xml create mode 100644 src/main/java/com/example/plugin/PluginManagerApplication.java create mode 100644 src/main/java/com/example/plugin/controller/Controller.java create mode 100644 src/main/java/com/example/plugin/demos/web/BasicController.java create mode 100644 src/main/java/com/example/plugin/demos/web/PathVariableController.java create mode 100644 src/main/java/com/example/plugin/demos/web/User.java create mode 100644 src/main/java/com/example/plugin/properties/SystemEnv.java create mode 100644 src/main/java/com/example/plugin/run/StartInit.java create mode 100644 src/main/java/com/example/plugin/utils/PluginClassLoader.java create mode 100644 src/main/java/com/example/plugin/utils/PluginUtils.java create mode 100644 src/main/resources/application-dev.yml create mode 100644 src/main/resources/application-test.yml create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/static/index.html create mode 100644 src/test/java/com/example/plugin/PluginManagerApplicationTests.java diff --git a/.gitignore b/.gitignore index a1c2a23..6894366 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,9 @@ # Log file *.log - +target +.idea +*.iml # BlueJ files *.ctxt diff --git a/HELP.md b/HELP.md new file mode 100644 index 0000000..95b5780 --- /dev/null +++ b/HELP.md @@ -0,0 +1,19 @@ +# Getting Started + +### Reference Documentation + +For further reference, please consider the following sections: + +* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) +* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.6.13/maven-plugin/reference/html/) +* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.6.13/maven-plugin/reference/html/#build-image) +* [Spring Web](https://docs.spring.io/spring-boot/docs/2.6.13/reference/htmlsingle/#web) + +### Guides + +The following guides illustrate how to use some features concretely: + +* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/) +* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/) +* [Building REST services with Spring](https://spring.io/guides/tutorials/rest/) + diff --git a/plugin/lib/jar.txt b/plugin/lib/jar.txt new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..2f93526 --- /dev/null +++ b/pom.xml @@ -0,0 +1,108 @@ + + + 4.0.0 + com.example + plugin-manager + 0.0.1-SNAPSHOT + plugin-manager + plugin-manager + + 1.8 + UTF-8 + UTF-8 + 2.6.13 + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-configuration-processor + true + provided + + + org.springframework.boot + spring-boot-starter-test + test + + + org.example + plugin-core + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + org.example + plugin-core + 1.0-SNAPSHOT + + + + + + dev + + dev + + + + test + + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + UTF-8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + com.example.plugin.PluginManagerApplication + + + + repackage + + repackage + + + + + + + + src/main/resources + true + + **/*.yml + + + + + + diff --git a/src/main/java/com/example/plugin/PluginManagerApplication.java b/src/main/java/com/example/plugin/PluginManagerApplication.java new file mode 100644 index 0000000..a8d2d45 --- /dev/null +++ b/src/main/java/com/example/plugin/PluginManagerApplication.java @@ -0,0 +1,33 @@ +package com.example.plugin; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.ConfigurableApplicationContext; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +@SpringBootApplication +public class PluginManagerApplication { + + public static void main(String[] args) { + ConfigurableApplicationContext context = SpringApplication.run(PluginManagerApplication.class, args); + try { + InetAddress localhost = Inet4Address.getLocalHost(); + String port = context.getEnvironment().getProperty("server.port"); + System.out.println("**************************************************"); + System.out.println("** 系统启动成功! **"); + System.out.printf("** 访问地址:http://%s:%s **\n" + ,localhost.getHostAddress(),port); + System.out.printf("** http://127.0.0.1:%s **\n",port); + System.out.println("**************************************************"); + + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + + } +} diff --git a/src/main/java/com/example/plugin/controller/Controller.java b/src/main/java/com/example/plugin/controller/Controller.java new file mode 100644 index 0000000..2d73bae --- /dev/null +++ b/src/main/java/com/example/plugin/controller/Controller.java @@ -0,0 +1,39 @@ +package com.example.plugin.controller; + +import cn.lyz.plugin.IHello; +import com.example.plugin.utils.PluginClassLoader; +import com.example.plugin.utils.PluginUtils; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.lang.reflect.InvocationTargetException; + +@RestController +@RequestMapping("plugin") +public class Controller { + + private static final String JAR_PATH ="plugin/lib/hello.jar"; + + @GetMapping("load") + public Object jarLoad() { + PluginUtils.load(JAR_PATH); + return "插件加载完成"; + } + + @GetMapping("unload") + public Object unloadJar() { + PluginUtils.unload(JAR_PATH); + return "插件卸载成功"; + } + + @GetMapping("run") + public Object classExists() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { + PluginClassLoader classLoader = PluginUtils.get(JAR_PATH); + Class helloClass = classLoader.loadClass("org.example.plugin.Hello"); + IHello hello = (IHello) helloClass.getDeclaredConstructor().newInstance(); + hello.say(); + hello.say("plugin"); + return "插件执行完成"; + } +} diff --git a/src/main/java/com/example/plugin/demos/web/BasicController.java b/src/main/java/com/example/plugin/demos/web/BasicController.java new file mode 100644 index 0000000..e14c2da --- /dev/null +++ b/src/main/java/com/example/plugin/demos/web/BasicController.java @@ -0,0 +1,67 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.plugin.demos.web; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * @author theonefx + */ +@Controller +public class BasicController { + + // http://127.0.0.1:8080/hello?name=lisi + @RequestMapping("/hello") + @ResponseBody + public String hello(@RequestParam(name = "name", defaultValue = "unknown user") String name) { + return "Hello " + name; + } + + // http://127.0.0.1:8080/user + @RequestMapping("/user") + @ResponseBody + public User user() { + User user = new User(); + user.setName("theonefx"); + user.setAge(666); + return user; + } + + // http://127.0.0.1:8080/save_user?name=newName&age=11 + @RequestMapping("/save_user") + @ResponseBody + public String saveUser(User u) { + return "user will save: name=" + u.getName() + ", age=" + u.getAge(); + } + + // http://127.0.0.1:8080/html + @RequestMapping("/html") + public String html() { + return "index.html"; + } + + @ModelAttribute + public void parseUser(@RequestParam(name = "name", defaultValue = "unknown user") String name + , @RequestParam(name = "age", defaultValue = "12") Integer age, User user) { + user.setName("zhangsan"); + user.setAge(18); + } +} diff --git a/src/main/java/com/example/plugin/demos/web/PathVariableController.java b/src/main/java/com/example/plugin/demos/web/PathVariableController.java new file mode 100644 index 0000000..05bdfa3 --- /dev/null +++ b/src/main/java/com/example/plugin/demos/web/PathVariableController.java @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.plugin.demos.web; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * @author theonefx + */ +@Controller +public class PathVariableController { + + // http://127.0.0.1:8080/user/123/roles/222 + @RequestMapping(value = "/user/{userId}/roles/{roleId}", method = RequestMethod.GET) + @ResponseBody + public String getLogin(@PathVariable("userId") String userId, @PathVariable("roleId") String roleId) { + return "User Id : " + userId + " Role Id : " + roleId; + } + + // http://127.0.0.1:8080/javabeat/somewords + @RequestMapping(value = "/javabeat/{regexp1:[a-z-]+}", method = RequestMethod.GET) + @ResponseBody + public String getRegExp(@PathVariable("regexp1") String regexp1) { + return "URI Part : " + regexp1; + } +} diff --git a/src/main/java/com/example/plugin/demos/web/User.java b/src/main/java/com/example/plugin/demos/web/User.java new file mode 100644 index 0000000..549b744 --- /dev/null +++ b/src/main/java/com/example/plugin/demos/web/User.java @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.plugin.demos.web; + +/** + * @author theonefx + */ +public class User { + + private String name; + + private Integer age; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } +} diff --git a/src/main/java/com/example/plugin/properties/SystemEnv.java b/src/main/java/com/example/plugin/properties/SystemEnv.java new file mode 100644 index 0000000..73e0ea0 --- /dev/null +++ b/src/main/java/com/example/plugin/properties/SystemEnv.java @@ -0,0 +1,19 @@ +package com.example.plugin.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "env") +public class SystemEnv { + + public String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/main/java/com/example/plugin/run/StartInit.java b/src/main/java/com/example/plugin/run/StartInit.java new file mode 100644 index 0000000..2b51570 --- /dev/null +++ b/src/main/java/com/example/plugin/run/StartInit.java @@ -0,0 +1,21 @@ +package com.example.plugin.run; + +import com.example.plugin.properties.SystemEnv; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; + +@Component +public class StartInit implements ApplicationRunner { + + private final SystemEnv systemEnv; + + public StartInit(SystemEnv systemEnv) { + this.systemEnv = systemEnv; + } + + @Override + public void run(ApplicationArguments args) throws Exception { + System.out.println("当前环境:"+systemEnv.getName()); + } +} diff --git a/src/main/java/com/example/plugin/utils/PluginClassLoader.java b/src/main/java/com/example/plugin/utils/PluginClassLoader.java new file mode 100644 index 0000000..9a58672 --- /dev/null +++ b/src/main/java/com/example/plugin/utils/PluginClassLoader.java @@ -0,0 +1,16 @@ +package com.example.plugin.utils; + +import java.net.URL; +import java.net.URLClassLoader; + +public class PluginClassLoader extends URLClassLoader { + + public PluginClassLoader(URL[] urls) { + super(urls); + } + + @Override + protected void addURL(URL url) { + super.addURL(url); + } +} diff --git a/src/main/java/com/example/plugin/utils/PluginUtils.java b/src/main/java/com/example/plugin/utils/PluginUtils.java new file mode 100644 index 0000000..d119bec --- /dev/null +++ b/src/main/java/com/example/plugin/utils/PluginUtils.java @@ -0,0 +1,66 @@ +package com.example.plugin.utils; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +public class PluginUtils { + + private static final Map classloaders = new HashMap<>(); + + /** + * 加载JAR + * @param url 相对路径 + */ + public static PluginClassLoader load(String url) { + File jarFile = new File(url); + if(!jarFile.exists()){ + try { + throw new RuntimeException(String.format("%s插件不存在",jarFile.toURI().toURL())); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + PluginClassLoader loader = new PluginClassLoader(new URL[]{}); + try { + loader.addURL(jarFile.toURI().toURL()); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + classloaders.put(url,loader); + return loader; + } + + /** + * 获取对应的classloader + * @param url 相对路径 + * @return PluginClassLoader + */ + public static PluginClassLoader get(String url){ + if(!classloaders.containsKey(url)){ + throw new RuntimeException("插件未加载"); + } + return classloaders.get(url); + } + + /** + * 卸载jar + * @param url 相对路径 + */ + public static void unload(String url){ + if(classloaders.containsKey(url)){ + PluginClassLoader classLoader = classloaders.get(url); + try { + classLoader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + classloaders.remove(url); + }else{ + throw new RuntimeException(String.format("插件“%s”未加载",url)); + } + } +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000..6655bee --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,3 @@ +# 应用服务 WEB 访问端口 +env: + name: dev \ No newline at end of file diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml new file mode 100644 index 0000000..e0dcaef --- /dev/null +++ b/src/main/resources/application-test.yml @@ -0,0 +1,3 @@ +# 应用服务 WEB 访问端口 +env: + name: test \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..9cfdb04 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,14 @@ +# 应用服务 WEB 访问端口 +spring: + profiles: + active: @profiles.active@ + +server: + port: 8080 + ssl: + enabled: false + key-store: file:E:/demo.old.jks + key-store-type: JKS + key-alias: demo + key-password: 123456@key + key-store-password: 123456@store \ No newline at end of file diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html new file mode 100644 index 0000000..89bb8ba --- /dev/null +++ b/src/main/resources/static/index.html @@ -0,0 +1,6 @@ + + +

hello word!!!

+

this is a html page

+ + \ No newline at end of file diff --git a/src/test/java/com/example/plugin/PluginManagerApplicationTests.java b/src/test/java/com/example/plugin/PluginManagerApplicationTests.java new file mode 100644 index 0000000..0aad643 --- /dev/null +++ b/src/test/java/com/example/plugin/PluginManagerApplicationTests.java @@ -0,0 +1,13 @@ +package com.example.plugin; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +class PluginManagerApplicationTests { + + @Test + void contextLoads() { + System.out.println(String.format("%03d",12345)); + } + +} -- Gitee