diff --git a/README.md b/README.md index 738aded98a386e19bc33d7f5aee2a689a062813d..393f63f04e65d91792b20500272fee77960c2984 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ - 支持在插件中自定义`Mapper`接口、`Mapper xml` 以及对应的实体`bean` -- 支持集成`Mybatis-Plus`、`Tk-Mybatis` +- 支持集成``Mybatis`、`Mybatis-Plus`、`Tk-Mybatis` - 支持可在插件中独立配置数据源 diff --git a/example/basic-example/basic-example-main/pom.xml b/example/basic-example/basic-example-main/pom.xml index d9ae937011b94431ab84157365dc0d46030041aa..119c86efe6500d111e6c9c2901e3535e5afa6064 100644 --- a/example/basic-example/basic-example-main/pom.xml +++ b/example/basic-example/basic-example-main/pom.xml @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.3.RELEASE + 2.4.2 diff --git a/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/config/PluginConfiguration.java b/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/config/PluginConfiguration.java index 6557abf5971fac8bca5a14fd797d4b6aa5bdfb7f..16eb1c9bffa4815725819aed57604036254b2c22 100644 --- a/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/config/PluginConfiguration.java +++ b/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/config/PluginConfiguration.java @@ -1,12 +1,14 @@ package com.basic.example.main.config; import com.gitee.starblues.integration.DefaultIntegrationConfiguration; +import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.pf4j.RuntimeMode; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; +import java.util.List; import java.util.Set; @@ -124,7 +126,6 @@ public class PluginConfiguration extends DefaultIntegrationConfiguration { } - @Override public String toString() { return "PluginArgConfiguration{" + diff --git a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/PluginListener1.java b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/PluginListener1.java index c613b212b57487cc051d9536a1b378a9f4e5c9ef..477d14944b970964a5be45d0569445c524bcea97 100644 --- a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/PluginListener1.java +++ b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/PluginListener1.java @@ -1,8 +1,10 @@ package com.basic.example.plugin1; +import com.basic.example.main.config.PluginConfiguration; import com.basic.example.plugin1.service.HelloService; import com.gitee.starblues.realize.BasePlugin; import com.gitee.starblues.realize.OneselfListener; +import com.gitee.starblues.realize.PluginUtils; import com.gitee.starblues.utils.OrderPriority; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,9 +20,11 @@ public class PluginListener1 implements OneselfListener { private static final Logger logger = LoggerFactory.getLogger(PluginListener1.class); private final HelloService helloService; + private final PluginUtils pluginUtils; - public PluginListener1(HelloService helloService) { + public PluginListener1(HelloService helloService, PluginUtils pluginUtils) { this.helloService = helloService; + this.pluginUtils = pluginUtils; } @@ -31,12 +35,16 @@ public class PluginListener1 implements OneselfListener { @Override public void startEvent(BasePlugin basePlugin) { + PluginConfiguration mainBean = pluginUtils.getMainBean(PluginConfiguration.class); + System.out.println(mainBean); logger.info("PluginListener1 {} start. helloService : {} .", basePlugin.getWrapper().getPluginId(), helloService.sayService2()); } @Override public void stopEvent(BasePlugin basePlugin) { + PluginConfiguration mainBean = pluginUtils.getMainBean(PluginConfiguration.class); + System.out.println(mainBean); logger.info("PluginListener1 {} stop. helloService : {} .", basePlugin.getWrapper().getPluginId(), helloService.sayService2()); } diff --git a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/config/ConfigBean.java b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/config/ConfigBean.java new file mode 100644 index 0000000000000000000000000000000000000000..23d56b9d0ba29e8596beea2b3c8ff0615d05b0c9 --- /dev/null +++ b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/config/ConfigBean.java @@ -0,0 +1,54 @@ +package com.basic.example.plugin1.config; + +import com.basic.example.main.config.PluginConfiguration; +import com.gitee.starblues.realize.PluginUtils; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author starBlues + * @version 1.0 + */ +@Configuration +public class ConfigBean { + + @Bean + public ConfigBeanTest c(PluginUtils pluginUtils){ + PluginConfiguration mainBean = pluginUtils.getMainBean(PluginConfiguration.class); + System.out.println("configTest: mainBean=" + mainBean); + ConfigBeanTest configBeanTest = new ConfigBeanTest(); + configBeanTest.name = "hello"; + configBeanTest.age = 16; + return configBeanTest; + } + + public static class ConfigBeanTest{ + 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; + } + + @Override + public String toString() { + return "ConfigBeanTest{" + + "name='" + name + '\'' + + ", age=" + age + + '}'; + } + } + +} diff --git a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/rest/HelloPlugin1.java b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/rest/HelloPlugin1.java index ddc966fbbc7fa81f278bf85eeb5cca140d606e58..56c9aea392bb429b06bb48e37720b275d3571c70 100644 --- a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/rest/HelloPlugin1.java +++ b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/rest/HelloPlugin1.java @@ -1,9 +1,12 @@ package com.basic.example.plugin1.rest; +import com.basic.example.plugin1.config.ConfigBean; import com.basic.example.plugin1.config.PluginConfig1; import com.basic.example.plugin1.service.HelloService; +import com.gitee.starblues.realize.PluginUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import org.pf4j.PluginDescriptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -26,6 +29,11 @@ public class HelloPlugin1 { @Autowired private PluginConfig1 pluginConfig1; + @Autowired + private PluginUtils pluginUtils; + + @Autowired + private ConfigBean.ConfigBeanTest configBeanTest; @GetMapping("plugin1") @ApiOperation(value = "hello", notes = "hello") @@ -50,6 +58,14 @@ public class HelloPlugin1 { return helloService.sayService2(); } + @GetMapping("pluginInfo") + public PluginDescriptor getPluginInfo(){ + return pluginUtils.getPluginDescriptor(); + } + @GetMapping("configBeanTest") + public ConfigBean.ConfigBeanTest getConfigBeanTest(){ + return configBeanTest; + } } diff --git a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/service/ConsoleNameImpl.java b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/service/ConsoleNameImpl.java index 3c86405e299fec49ceee099b75867cbe2003c3ba..6e79ff42221af1ec8d7d6f2efbc00c06ec1bfbc0 100644 --- a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/service/ConsoleNameImpl.java +++ b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/service/ConsoleNameImpl.java @@ -2,6 +2,7 @@ package com.basic.example.plugin1.service; import com.basic.example.main.config.PluginConfiguration; import com.basic.example.main.plugin.ConsoleName; +import com.gitee.starblues.realize.PluginUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -15,10 +16,11 @@ import org.springframework.stereotype.Component; public class ConsoleNameImpl implements ConsoleName { @Autowired - private PluginConfiguration pluginConfiguration; + private PluginUtils pluginUtils; @Override public String name() { + PluginConfiguration pluginConfiguration = pluginUtils.getMainBean(PluginConfiguration.class); return "My name is Plugin1" + "->pluginArgConfiguration :" + pluginConfiguration.toString(); } } diff --git a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/service/HelloService.java b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/service/HelloService.java index 12205b1fb12cc588788b127b14a5de836671d3ea..7bdbeba381b9a699e989e542507caa887c7206dd 100644 --- a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/service/HelloService.java +++ b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/service/HelloService.java @@ -16,7 +16,6 @@ public class HelloService { private final PluginConfig1 pluginConfig1; private final Service2 service2; - @Autowired public HelloService(PluginConfig1 pluginConfig1, Service2 service2) { this.pluginConfig1 = pluginConfig1; this.service2 = service2; diff --git a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/service/SupplierService.java b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/service/SupplierService.java index a698a622cec019ff8c3f5f9461d3a5cbad7fd874..eb2c76eb104d6fc5cf70c658f959f27a4178bd64 100644 --- a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/service/SupplierService.java +++ b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/service/SupplierService.java @@ -40,6 +40,9 @@ public class SupplierService { return key; } + public String notArg(){ + return "noArg"; + } public CommonReturn commonTest(String key, CommonParam commonParam){ System.out.println(commonParam); diff --git a/example/basic-example/plugins/basic-example-plugin2/src/main/java/com/basic/example/plugin2/rest/ProxyController.java b/example/basic-example/plugins/basic-example-plugin2/src/main/java/com/basic/example/plugin2/rest/ProxyController.java index cb269beea3e1fd68b83a4e495f3d7ef015da01e4..3bf98de9d7f5d80db95ea204ba8cb85298ea0426 100644 --- a/example/basic-example/plugins/basic-example-plugin2/src/main/java/com/basic/example/plugin2/rest/ProxyController.java +++ b/example/basic-example/plugins/basic-example-plugin2/src/main/java/com/basic/example/plugin2/rest/ProxyController.java @@ -28,6 +28,11 @@ public class ProxyController { } + @GetMapping("noArg") + public String noArg(){ + return callerService.notArg(); + } + @GetMapping("add") public Integer add(){ return callerService.add(1, 2); diff --git a/example/basic-example/plugins/basic-example-plugin2/src/main/java/com/basic/example/plugin2/service/CallerService.java b/example/basic-example/plugins/basic-example-plugin2/src/main/java/com/basic/example/plugin2/service/CallerService.java index 34a30fd04449548fadfe432ac9899c82a7315a01..1a156d960b68a3e73fede68b63645c2156c39204 100644 --- a/example/basic-example/plugins/basic-example-plugin2/src/main/java/com/basic/example/plugin2/service/CallerService.java +++ b/example/basic-example/plugins/basic-example-plugin2/src/main/java/com/basic/example/plugin2/service/CallerService.java @@ -10,7 +10,7 @@ import com.gitee.starblues.annotation.Caller; * @author starBlues * @version 1.0 */ -@Caller("SupplierService") +@Caller(value = "SupplierService") public interface CallerService { PluginInfo getConfig(String key); @@ -22,6 +22,8 @@ public interface CallerService { CommonReturn commonTest(String key, CommonParam commonParam); + String notArg(); + class CallerInfo{ private String name; private PluginInfo pluginInfo; diff --git a/example/basic-example/plugins/basic-example-plugin2/src/main/java/com/basic/example/plugin2/service/HelloService.java b/example/basic-example/plugins/basic-example-plugin2/src/main/java/com/basic/example/plugin2/service/HelloService.java index 7e370813adef7e34cf0a388d94ba1dca23993605..c225d13b5c7413be8b0867968afdf499b6e95be7 100644 --- a/example/basic-example/plugins/basic-example-plugin2/src/main/java/com/basic/example/plugin2/service/HelloService.java +++ b/example/basic-example/plugins/basic-example-plugin2/src/main/java/com/basic/example/plugin2/service/HelloService.java @@ -16,7 +16,7 @@ public class HelloService { private final Plugin2Config plugin2Config; private final Service2 service2; - @Autowired + public HelloService(Plugin2Config plugin2Config, Service2 service2) { this.plugin2Config = plugin2Config; this.service2 = service2; diff --git a/example/integration-mybatis/integration-mybatis-main/src/main/java/com/mybatis/main/config/PluginBeanConfig.java b/example/integration-mybatis/integration-mybatis-main/src/main/java/com/mybatis/main/config/PluginBeanConfig.java index 77444a5616cfc071c773260ead6d0e741cb00c88..1c0b551965ea0e8c1ec6fded3e556be460b71bec 100644 --- a/example/integration-mybatis/integration-mybatis-main/src/main/java/com/mybatis/main/config/PluginBeanConfig.java +++ b/example/integration-mybatis/integration-mybatis-main/src/main/java/com/mybatis/main/config/PluginBeanConfig.java @@ -5,6 +5,7 @@ import com.gitee.starblues.extension.resources.StaticResourceExtension; import com.gitee.starblues.integration.*; import com.gitee.starblues.integration.application.AutoPluginApplication; import com.gitee.starblues.integration.application.PluginApplication; +import com.google.common.collect.Sets; import org.pf4j.RuntimeMode; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -59,6 +60,8 @@ public class PluginBeanConfig { .pluginRestPathPrefix("/api/plugin") .enablePluginIdRestPathPrefix(true) .enableSwaggerRefresh(true) + .enablePluginIds(Sets.newHashSet("integration-mybatis-plugin1")) + .disablePluginIds(Sets.newHashSet("integration-mybatis-plugin2")) .build(); } diff --git a/example/integration-mybatis/plugins/integration-mybatis-plugin1/pom.xml b/example/integration-mybatis/plugins/integration-mybatis-plugin1/pom.xml index fd0225d080c242a28e24ead3fea52d675743608e..41fa0f398e298ed261f5b48b37bc050c33d2d081 100644 --- a/example/integration-mybatis/plugins/integration-mybatis-plugin1/pom.xml +++ b/example/integration-mybatis/plugins/integration-mybatis-plugin1/pom.xml @@ -24,26 +24,6 @@ - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus.version} - - - - - org.apache.velocity - velocity-engine-core - ${velocity.version} - - - - org.mybatis.spring.boot - mybatis-spring-boot-starter - ${mybatis-spring-boot-starter.version} - - \ No newline at end of file diff --git a/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/MybatisConfig.java b/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/MybatisConfig.java index 4e57c31b1a4b7e6ee16eb9804c3132947870b7ff..fba3cfc0be6584d0f3b9b0788ed0b6265184b230 100644 --- a/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/MybatisConfig.java +++ b/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/MybatisConfig.java @@ -1,5 +1,6 @@ package com.mybatis.plugin1; +import com.gitee.starblues.annotation.ConfigDefinition; import com.gitee.starblues.extension.mybatis.SpringBootMybatisConfig; import org.springframework.stereotype.Component; @@ -11,7 +12,7 @@ import java.util.Set; * @version 1.0 * @since 2020-12-18 */ -@Component +@ConfigDefinition public class MybatisConfig implements SpringBootMybatisConfig { @Override diff --git a/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/ResourceConfig.java b/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/ResourceConfig.java index be69126fe4a781ac54bca95ab0d28349c07df9de..17784c8cd48f01567be43ac4da7f870762da7d8e 100644 --- a/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/ResourceConfig.java +++ b/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/ResourceConfig.java @@ -1,5 +1,6 @@ package com.mybatis.plugin1; +import com.gitee.starblues.annotation.ConfigDefinition; import com.gitee.starblues.extension.resources.StaticResourceConfig; import com.gitee.starblues.extension.resources.thymeleaf.SpringBootThymeleafConfig; import com.gitee.starblues.extension.resources.thymeleaf.ThymeleafConfig; @@ -13,7 +14,7 @@ import java.util.Set; * @version 1.0 * @since 2020-12-19 */ -@Component +@ConfigDefinition public class ResourceConfig implements StaticResourceConfig, SpringBootThymeleafConfig { @Override public Set locations() { diff --git a/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/config/PluginConfigBean.java b/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/config/PluginConfigBean.java new file mode 100644 index 0000000000000000000000000000000000000000..9af63cdf24d6ffa7a51c8ee1f44665d5eae3ae95 --- /dev/null +++ b/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/config/PluginConfigBean.java @@ -0,0 +1,28 @@ +package com.mybatis.plugin1.config; + +import com.gitee.starblues.realize.ConfigBean; + +/** + * @author starBlues + * @version 1.0 + */ +public class PluginConfigBean implements ConfigBean { + + private final Plugin1Config plugin1Config; + + public PluginConfigBean(Plugin1Config plugin1Config) { + this.plugin1Config = plugin1Config; + } + + @Override + public void initialize() throws Exception { + System.out.println("初始化Bean"); + System.out.println(plugin1Config); + } + + @Override + public void destroy() throws Exception { + System.out.println("销毁Bean"); + System.out.println(plugin1Config); + } +} diff --git a/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/rest/Plugin1Controller.java b/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/rest/Plugin1Controller.java index b82a9e82321c8390b69675d94de72883dd386d8a..4e2748c8efdb0084d1ff4544cdb3883efbbd45cb 100644 --- a/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/rest/Plugin1Controller.java +++ b/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/rest/Plugin1Controller.java @@ -1,6 +1,5 @@ package com.mybatis.plugin1.rest; -import com.baomidou.mybatisplus.generator.config.GlobalConfig; import com.mybatis.plugin1.entity.Plugin1; import com.mybatis.plugin1.mapper.Plugin1Mapper; import com.mybatis.plugin1.service.TranServiec; @@ -47,7 +46,6 @@ public class Plugin1Controller { if(!StringUtils.isEmpty(name)){ p.setName(name); } - GlobalConfig config = new GlobalConfig(); return pluginMapperl.getByCondition(p); } diff --git a/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/rest/UserController.java b/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/rest/UserController.java index d1fc6045bd71471c095b228624dd8e8ec35bfe3b..6ff4acff3c7b34dcd9ee90e42922a4c10e6cdf48 100644 --- a/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/rest/UserController.java +++ b/example/integration-mybatis/plugins/integration-mybatis-plugin1/src/main/java/com/mybatis/plugin1/rest/UserController.java @@ -1,5 +1,6 @@ package com.mybatis.plugin1.rest; +import com.gitee.starblues.realize.PluginUtils; import com.mybatis.main.entity.User; import com.mybatis.main.mapper.UserMapper; import com.mybatis.main.service.TestTestTransactional; @@ -22,10 +23,12 @@ public class UserController { private final UserMapper userMapper; private final TestTestTransactional testTestTransactional; + + @Autowired - public UserController(UserMapper userMapper, TestTestTransactional testTestTransactional) { - this.userMapper = userMapper; - this.testTestTransactional = testTestTransactional; + public UserController(PluginUtils pluginUtils) { + this.userMapper = pluginUtils.getMainBean(UserMapper.class); + this.testTestTransactional = pluginUtils.getMainBean(TestTestTransactional.class); } @GetMapping("/list") diff --git a/example/integration-mybatis/plugins/integration-mybatis-plugin2/src/main/java/com/mybatis/plugin2/MybatisConfig2.java b/example/integration-mybatis/plugins/integration-mybatis-plugin2/src/main/java/com/mybatis/plugin2/MybatisConfig2.java index efa972a2f3a56ea7d17bad6a0e8e85e737eaa3d4..8daa7a8311a8b040ec04fa473b296064ec7a6051 100644 --- a/example/integration-mybatis/plugins/integration-mybatis-plugin2/src/main/java/com/mybatis/plugin2/MybatisConfig2.java +++ b/example/integration-mybatis/plugins/integration-mybatis-plugin2/src/main/java/com/mybatis/plugin2/MybatisConfig2.java @@ -1,5 +1,6 @@ package com.mybatis.plugin2; +import com.gitee.starblues.annotation.ConfigDefinition; import com.gitee.starblues.extension.mybatis.SpringBootMybatisConfig; import org.springframework.stereotype.Component; @@ -11,7 +12,7 @@ import java.util.Set; * @version 1.0 * @since 2020-12-18 */ -@Component +@ConfigDefinition public class MybatisConfig2 implements SpringBootMybatisConfig { @Override diff --git a/example/integration-mybatis/plugins/integration-mybatis-plugin2/src/main/java/com/mybatis/plugin2/Plugin2Listener.java b/example/integration-mybatis/plugins/integration-mybatis-plugin2/src/main/java/com/mybatis/plugin2/Plugin2Listener.java index ea5dfa6e7e03c81151079add506d21cbdbbee802..4e5aebb823a74010af368fdb6017f5ddf746eeb7 100644 --- a/example/integration-mybatis/plugins/integration-mybatis-plugin2/src/main/java/com/mybatis/plugin2/Plugin2Listener.java +++ b/example/integration-mybatis/plugins/integration-mybatis-plugin2/src/main/java/com/mybatis/plugin2/Plugin2Listener.java @@ -2,10 +2,12 @@ package com.mybatis.plugin2; import com.gitee.starblues.realize.BasePlugin; import com.gitee.starblues.realize.OneselfListener; +import com.gitee.starblues.realize.PluginUtils; import com.gitee.starblues.utils.OrderPriority; import com.mybatis.main.mapper.RoleMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; /** * description @@ -19,8 +21,9 @@ public class Plugin2Listener implements OneselfListener { private final RoleMapper roleMapper; - public Plugin2Listener(RoleMapper roleMapper) { - this.roleMapper = roleMapper; + @Autowired + public Plugin2Listener(PluginUtils pluginUtils){ + roleMapper = pluginUtils.getMainBean(RoleMapper.class); } @Override diff --git a/example/integration-mybatis/plugins/integration-mybatis-plugin2/src/main/java/com/mybatis/plugin2/rest/RoleController.java b/example/integration-mybatis/plugins/integration-mybatis-plugin2/src/main/java/com/mybatis/plugin2/rest/RoleController.java index 1d8b1e9a52b8660ec584637b8005183b7e7c1b82..dfc92a332288dfe3178e3f5a29a62a1c6fe83206 100644 --- a/example/integration-mybatis/plugins/integration-mybatis-plugin2/src/main/java/com/mybatis/plugin2/rest/RoleController.java +++ b/example/integration-mybatis/plugins/integration-mybatis-plugin2/src/main/java/com/mybatis/plugin2/rest/RoleController.java @@ -1,5 +1,6 @@ package com.mybatis.plugin2.rest; +import com.gitee.starblues.realize.PluginUtils; import com.mybatis.main.entity.Role; import com.mybatis.main.mapper.RoleMapper; import org.springframework.beans.factory.annotation.Autowired; @@ -22,8 +23,8 @@ public class RoleController { private final RoleMapper roleMapper; @Autowired - public RoleController(RoleMapper roleMapper) { - this.roleMapper = roleMapper; + public RoleController(PluginUtils pluginUtils){ + roleMapper = pluginUtils.getMainBean(RoleMapper.class); } @GetMapping("/list") diff --git a/example/integration-mybatisplus/integration-mybatisplus-main/pom.xml b/example/integration-mybatisplus/integration-mybatisplus-main/pom.xml index f65a1a0e3a88143d9a787314f97708abd47c6818..fce0dc9f661ac28f8bb936466c0db860d91e84c2 100644 --- a/example/integration-mybatisplus/integration-mybatisplus-main/pom.xml +++ b/example/integration-mybatisplus/integration-mybatisplus-main/pom.xml @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.3.RELEASE + 2.4.2 diff --git a/example/integration-mybatisplus/integration-mybatisplus-main/src/main/java/com/mybatisplus/main/config/PluginBeanConfig.java b/example/integration-mybatisplus/integration-mybatisplus-main/src/main/java/com/mybatisplus/main/config/PluginBeanConfig.java index b896a397903fefc34c78dc7f41e04c202da9dc85..b9e39dd9e51a97524462c3d8e294c892dd539f12 100644 --- a/example/integration-mybatisplus/integration-mybatisplus-main/src/main/java/com/mybatisplus/main/config/PluginBeanConfig.java +++ b/example/integration-mybatisplus/integration-mybatisplus-main/src/main/java/com/mybatisplus/main/config/PluginBeanConfig.java @@ -17,7 +17,6 @@ import org.springframework.context.annotation.Configuration; @Configuration public class PluginBeanConfig { - /** * 定义插件应用。使用可以注入它操作插件。 * @return PluginApplication @@ -31,5 +30,4 @@ public class PluginBeanConfig { )); return pluginApplication; } - } diff --git a/example/integration-mybatisplus/integration-mybatisplus-main/src/main/resources/application-dev.yml b/example/integration-mybatisplus/integration-mybatisplus-main/src/main/resources/application-dev.yml index d07e143ec314f784c4d4d5cd3058a9bdaa71a88a..9a4d4e72bc83bc6c2d9c7fa47fdced51c3da11c0 100644 --- a/example/integration-mybatisplus/integration-mybatisplus-main/src/main/resources/application-dev.yml +++ b/example/integration-mybatisplus/integration-mybatisplus-main/src/main/resources/application-dev.yml @@ -16,6 +16,6 @@ mybatis-plus: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl plugin: - runMode: prod - pluginPath: D:\code\open-source-code\springboot-plugin-framework-parent\example\integration-mybatisplus\dist\plugins + runMode: dev + pluginPath: ./example/integration-mybatisplus/plugins pluginConfigFilePath: \ No newline at end of file diff --git a/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/src/main/java/com/mybatisplus/plugin/MybatisPlusConfig.java b/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/src/main/java/com/mybatisplus/plugin/MybatisPlusConfig2.java similarity index 41% rename from example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/src/main/java/com/mybatisplus/plugin/MybatisPlusConfig.java rename to example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/src/main/java/com/mybatisplus/plugin/MybatisPlusConfig2.java index dea3e3f22983a9b5752f3f8cf7a2e49c5d935477..df5b71b7c7d11428f23b94808b9e9b2458b597ae 100644 --- a/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/src/main/java/com/mybatisplus/plugin/MybatisPlusConfig.java +++ b/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/src/main/java/com/mybatisplus/plugin/MybatisPlusConfig2.java @@ -1,9 +1,8 @@ package com.mybatisplus.plugin; -import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.gitee.starblues.annotation.ConfigDefinition; import com.gitee.starblues.extension.mybatis.mybatisplus.SpringBootMybatisPlusConfig; import com.google.common.collect.Sets; -import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; import org.springframework.stereotype.Component; import java.util.Set; @@ -13,8 +12,8 @@ import java.util.Set; * @version 1.0 * @since 2020-12-14 */ -@Component -public class MybatisPlusConfig implements SpringBootMybatisPlusConfig { +@ConfigDefinition("") +public class MybatisPlusConfig2 implements SpringBootMybatisPlusConfig { @Override public Set entityPackage() { return Sets.newHashSet("com.mybatisplus.plugin.entity"); @@ -25,17 +24,4 @@ public class MybatisPlusConfig implements SpringBootMybatisPlusConfig { return Sets.newHashSet("classpath:mapper/*Mapper.xml"); } - @Override - public void oneselfConfig(MybatisSqlSessionFactoryBean sqlSessionFactoryBean) { - MysqlDataSource mysqlDataSource = new MysqlDataSource(); - mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/ac_identity_auth?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC"); - mysqlDataSource.setUser("root"); - mysqlDataSource.setPassword("root"); - sqlSessionFactoryBean.setDataSource(mysqlDataSource); - } - - @Override - public boolean enableOneselfConfig() { - return true; - } } diff --git a/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/src/main/java/com/mybatisplus/plugin/rest/AppController.java b/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/src/main/java/com/mybatisplus/plugin/rest/AppController.java index 98905d047f1e52ed36be1ba49f68149c86d8ed34..89da14b1b921d5ae434df17df420bf9ed8425387 100644 --- a/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/src/main/java/com/mybatisplus/plugin/rest/AppController.java +++ b/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/src/main/java/com/mybatisplus/plugin/rest/AppController.java @@ -1,5 +1,7 @@ package com.mybatisplus.plugin.rest; +import com.mybatisplus.plugin.A; +import com.mybatisplus.plugin.MybatisPlusPlugin; import com.mybatisplus.plugin.entity.App; import com.mybatisplus.plugin.entity.PluginData; import com.mybatisplus.plugin.mapper.AppMapper; @@ -24,6 +26,9 @@ public class AppController { @Autowired private AppMapper appMapper; + @Autowired + private A a; + @GetMapping public List getAll(){ @@ -31,6 +36,12 @@ public class AppController { } + + @GetMapping("a") + public String getA(){ + return a.getName(); + } + @GetMapping("{version}") public List getAll(@PathVariable("version") Integer version){ return appMapper.getAppVersion(version); diff --git a/example/integration-tkmybatis/plugins/integration-tkmybatis-plugin/src/main/java/com/tkmybatis/plugin/config/TkMybatisPlusConfig.java b/example/integration-tkmybatis/plugins/integration-tkmybatis-plugin/src/main/java/com/tkmybatis/plugin/config/TkMybatisPlusConfig.java index 838b0bec27b73810e9603719ceb1ba9996906972..bf8b5ca6f8b889425d3b9fd36be05ad14578caad 100644 --- a/example/integration-tkmybatis/plugins/integration-tkmybatis-plugin/src/main/java/com/tkmybatis/plugin/config/TkMybatisPlusConfig.java +++ b/example/integration-tkmybatis/plugins/integration-tkmybatis-plugin/src/main/java/com/tkmybatis/plugin/config/TkMybatisPlusConfig.java @@ -1,5 +1,6 @@ package com.tkmybatis.plugin.config; +import com.gitee.starblues.annotation.ConfigDefinition; import com.gitee.starblues.extension.mybatis.tkmyabtis.SpringBootTkMybatisConfig; import com.google.common.collect.Sets; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; @@ -14,7 +15,7 @@ import java.util.Set; * @version 1.0 * @since 2020-12-14 */ -@Component +@ConfigDefinition public class TkMybatisPlusConfig implements SpringBootTkMybatisConfig { @Override diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/README.md b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/README.md index 6c328c67fe753300c491928a3e540ef7f3d4da1f..ecb5844e39a8f65f95dc0fc289a4d098f788caca 100644 --- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/README.md +++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/README.md @@ -1,4 +1,9 @@ -#扩展包 - 集成SpringBoot Mybatis +### 特性 +- 支持在插件中自定义Mapper接口、Mapper xml 以及对应的实体bean +- 支持插件独立定义数据源 +- 支持集成 `Mybatis` +- 支持集成 `Mybatis-Plus` +- 支持集成`Tk-Mybatis` ### maven 仓库地址 @@ -77,11 +82,12 @@ public PluginApplication pluginApplication(){ - 如果集成`mybatis-plus`, 则实现接口:`com.gitee.starblues.extension.mybatis.SpringBootMybatisPlusConfig` - 如果集成`tkmybatis`, 则实现接口:`com.gitee.starblues.extension.mybatis.SpringBootTkMybatisConfig` +- 以上实现类添加注解`@ConfigDefinition` 例如集成mybatis-plus: ```java -@Component +@ConfigDefinition public class MybatisConfig implements SpringBootMybatisConfig { @Override @@ -102,7 +108,7 @@ public class MybatisConfig implements SpringBootMybatisConfig { ``` 该步骤主要定义插件中的Mapper xml的位置。该位置的定义规则如下: - +- 注意: 插件中的xml路径不能和主程序中的xml路径在`resources`相对一致, 比如文件名都为`mapper`, 建议使用不同名称区分开 ``` text xmlLocationsMatch: ? 匹配一个字符 @@ -205,6 +211,8 @@ public void oneselfConfig(Config config){ ### 版本升级 +#### 2.4.0 版本 +- 修改扩展功能中配置实现类,必须新增`@ConfigDefinition` 注解 #### 2.2.5 版本 全新升级该扩展 @@ -221,6 +229,4 @@ public void oneselfConfig(Config config){ 2. 修复 Mapper.xml 中定义的 resultType 类型无法定义的bug。 #### 2.0.3 版本 -1. 修复Mapper无法注入的bug. (由于springboot-plugin-framework 2.0.3 版本升级导致) - - +1. 修复Mapper无法注入的bug. (由于springboot-plugin-framework 2.0.3 版本升级导致) \ No newline at end of file diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/MapperHandler.java b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/MapperHandler.java index 0ea44708b306dbeba129b8c3d7ba6d1c964c4345..0f8e55f88661a12ded490ee226f1bbc482361b0a 100644 --- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/MapperHandler.java +++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/MapperHandler.java @@ -1,7 +1,6 @@ package com.gitee.starblues.extension.mybatis; import com.gitee.starblues.extension.mybatis.group.PluginMapperGroup; -import com.gitee.starblues.factory.PluginInfoContainer; import com.gitee.starblues.factory.PluginRegistryInfo; import com.gitee.starblues.factory.process.pipe.bean.name.PluginAnnotationBeanNameGenerator; import org.apache.ibatis.session.SqlSessionFactory; @@ -15,6 +14,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.support.BeanNameGenerator; import org.springframework.beans.factory.support.GenericBeanDefinition; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigUtils; import org.springframework.context.annotation.AnnotationScopeMetadataResolver; import org.springframework.context.annotation.ScopeMetadata; @@ -38,10 +38,8 @@ public class MapperHandler { private final ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver(); - private final GenericApplicationContext applicationContext; - public MapperHandler(GenericApplicationContext applicationContext) { - this.applicationContext = applicationContext; + public MapperHandler() { } /** @@ -51,6 +49,7 @@ public class MapperHandler { */ public void processMapper(PluginRegistryInfo pluginRegistryInfo, MapperHandler.ProcessMapper processMapper){ + GenericApplicationContext applicationContext = pluginRegistryInfo.getPluginApplicationContext(); List> groupClasses = pluginRegistryInfo.getGroupClasses(PluginMapperGroup.GROUP_ID); if(groupClasses == null || groupClasses.isEmpty()){ return; @@ -72,7 +71,6 @@ public class MapperHandler { try { processMapper.process(definitionHolder, groupClass); beanNames.add(beanName); - PluginInfoContainer.addRegisterBeanName(pluginId, beanName); } catch (Exception e) { LOGGER.error("process mapper '{}' error. {}", groupClass.getName(), e.getMessage(), e); } @@ -101,22 +99,6 @@ public class MapperHandler { definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); } - /** - * 公共卸载Mapper - * @param pluginRegistryInfo 插件信息 - * @throws Exception 卸载异常 - */ - public void unRegistryMapper(PluginRegistryInfo pluginRegistryInfo) throws Exception { - Set beanNames = pluginRegistryInfo.getExtension(MAPPER_INTERFACE_NAMES); - if(beanNames == null){ - return; - } - String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); - for (String beanName : beanNames) { - applicationContext.removeBeanDefinition(beanName); - PluginInfoContainer.removeRegisterBeanName(pluginId, beanName); - } - } @FunctionalInterface diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/MybatisProcessor.java b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/MybatisProcessor.java index 3e6b5fb638d57cc9107ec27df3221ca247acb130..cd522b045239c0dd8ca9a7c7de67ec7b59dd3fe6 100644 --- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/MybatisProcessor.java +++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/MybatisProcessor.java @@ -1,9 +1,8 @@ package com.gitee.starblues.extension.mybatis; -import com.gitee.starblues.extension.ExtensionConfigUtils; import com.gitee.starblues.factory.PluginRegistryInfo; -import com.gitee.starblues.factory.process.pipe.PluginPipeProcessorExtend; -import com.gitee.starblues.utils.OrderPriority; +import com.gitee.starblues.factory.process.pipe.bean.PluginBeanRegistrarExtend; +import com.gitee.starblues.utils.PluginBeanUtils; import org.apache.ibatis.io.Resources; import org.apache.ibatis.mapping.DatabaseIdProvider; import org.apache.ibatis.plugin.Interceptor; @@ -12,11 +11,8 @@ import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; -import org.pf4j.ClassLoadingStrategy; -import org.pf4j.PluginWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.io.Resource; @@ -25,16 +21,11 @@ import org.springframework.core.io.Resource; * @author starBlues * @version 2.3 */ -public class MybatisProcessor implements PluginPipeProcessorExtend { +public class MybatisProcessor implements PluginBeanRegistrarExtend { private static final Logger LOGGER = LoggerFactory.getLogger(MybatisProcessor.class); - private final GenericApplicationContext applicationContext; - private final MapperHandler mapperHandler; - - public MybatisProcessor(ApplicationContext applicationContext) { - this.applicationContext = (GenericApplicationContext) applicationContext; - this.mapperHandler = new MapperHandler(this.applicationContext); + public MybatisProcessor() { } @Override @@ -42,21 +33,10 @@ public class MybatisProcessor implements PluginPipeProcessorExtend { return "MybatisProcessor"; } - @Override - public OrderPriority order() { - return OrderPriority.getHighPriority(); - } - - @Override - public void initialize() throws Exception { - - } - @Override public void registry(PluginRegistryInfo pluginRegistryInfo) throws Exception { - PluginWrapper pluginWrapper = pluginRegistryInfo.getPluginWrapper(); - - SpringBootMybatisConfig config = ExtensionConfigUtils.getConfig(applicationContext, pluginWrapper.getPluginId(), + SpringBootMybatisConfig config = PluginBeanUtils.getObjectByInterfaceClass( + pluginRegistryInfo.getConfigSingletons(), SpringBootMybatisConfig.class); if(config == null){ return; @@ -67,7 +47,8 @@ public class MybatisProcessor implements PluginPipeProcessorExtend { if(config.enableOneselfConfig()){ config.oneselfConfig(factory); } else { - PluginFollowCoreConfig followCoreConfig = new PluginFollowCoreConfig(applicationContext); + GenericApplicationContext mainApplicationContext = pluginRegistryInfo.getMainApplicationContext(); + PluginFollowCoreConfig followCoreConfig = new PluginFollowCoreConfig(mainApplicationContext); factory.setDataSource(followCoreConfig.getDataSource()); Configuration configuration = followCoreConfig.getConfiguration(SpringBootMybatisExtension.Type.MYBATIS); factory.setConfiguration(configuration); @@ -100,12 +81,13 @@ public class MybatisProcessor implements PluginPipeProcessorExtend { ClassLoader defaultClassLoader = Resources.getDefaultClassLoader(); try { - Resources.setDefaultClassLoader(pluginRegistryInfo.getPluginClassLoader(PluginRegistryInfo.ClassLoaderStrategy.PAD)); + Resources.setDefaultClassLoader(pluginRegistryInfo.getDefaultPluginClassLoader()); SqlSessionFactory sqlSessionFactory = factory.getObject(); if(sqlSessionFactory == null){ throw new Exception("Get mybatis sqlSessionFactory is null"); } SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory); + MapperHandler mapperHandler = new MapperHandler(); mapperHandler.processMapper(pluginRegistryInfo, (holder, mapperClass) -> { mapperHandler.commonProcessMapper(holder, mapperClass, sqlSessionFactory, sqlSessionTemplate); }); @@ -115,10 +97,5 @@ public class MybatisProcessor implements PluginPipeProcessorExtend { } - @Override - public void unRegistry(PluginRegistryInfo pluginRegistryInfo) throws Exception { - mapperHandler.unRegistryMapper(pluginRegistryInfo); - } - } diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/PluginFollowCoreConfig.java b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/PluginFollowCoreConfig.java index 455257c1934424d6dd8bbb1eae8419be6b8e1a29..97cc0671ce734dd91f1aa4a85f2fda27c6c0c588 100644 --- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/PluginFollowCoreConfig.java +++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/PluginFollowCoreConfig.java @@ -22,22 +22,22 @@ import java.util.*; */ public class PluginFollowCoreConfig { - private final ApplicationContext applicationContext; + private final ApplicationContext mainApplicationContext; - public PluginFollowCoreConfig(ApplicationContext applicationContext) { - this.applicationContext = applicationContext; + public PluginFollowCoreConfig(ApplicationContext mainApplicationContext) { + this.mainApplicationContext = mainApplicationContext; } public DataSource getDataSource(){ - return applicationContext.getBean(DataSource.class); + return mainApplicationContext.getBean(DataSource.class); } public Configuration getConfiguration(SpringBootMybatisExtension.Type type){ Configuration configuration = new Configuration(); if(type == SpringBootMybatisExtension.Type.MYBATIS){ try { - Map customizerMap = applicationContext.getBeansOfType(ConfigurationCustomizer.class); + Map customizerMap = mainApplicationContext.getBeansOfType(ConfigurationCustomizer.class); if(!customizerMap.isEmpty()){ for (ConfigurationCustomizer customizer : customizerMap.values()) { customizer.customize(configuration); @@ -54,7 +54,7 @@ public class PluginFollowCoreConfig { MybatisConfiguration configuration = new MybatisConfiguration(); try { Map customizerMap = - applicationContext.getBeansOfType(com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer.class); + mainApplicationContext.getBeansOfType(com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer.class); if(!customizerMap.isEmpty()){ for (com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer customizer : customizerMap.values()) { customizer.customize(configuration); @@ -69,7 +69,7 @@ public class PluginFollowCoreConfig { public Interceptor[] getInterceptor(){ Map, Interceptor> interceptorMap = new HashMap<>(); try { - SqlSessionFactory sqlSessionFactory = applicationContext.getBean(SqlSessionFactory.class); + SqlSessionFactory sqlSessionFactory = mainApplicationContext.getBean(SqlSessionFactory.class); // 先从 SqlSessionFactory 工厂中获取拦截器 List interceptors = sqlSessionFactory.getConfiguration().getInterceptors(); if(interceptors != null){ @@ -84,7 +84,7 @@ public class PluginFollowCoreConfig { // ignore } // 再从定义Bean中获取拦截器 - Map beanInterceptorMap = applicationContext.getBeansOfType(Interceptor.class); + Map beanInterceptorMap = mainApplicationContext.getBeansOfType(Interceptor.class); if(!beanInterceptorMap.isEmpty()){ beanInterceptorMap.forEach((k, v)->{ // 如果Class一致, 则会覆盖 @@ -99,9 +99,9 @@ public class PluginFollowCoreConfig { } public DatabaseIdProvider getDatabaseIdProvider(){ - String[] beanNamesForType = applicationContext.getBeanNamesForType(DatabaseIdProvider.class, false, false); + String[] beanNamesForType = mainApplicationContext.getBeanNamesForType(DatabaseIdProvider.class, false, false); if(beanNamesForType.length > 0){ - return applicationContext.getBean(DatabaseIdProvider.class); + return mainApplicationContext.getBean(DatabaseIdProvider.class); } return null; } @@ -110,7 +110,7 @@ public class PluginFollowCoreConfig { public LanguageDriver[] getLanguageDriver(){ Map, LanguageDriver> languageDriverMap = new HashMap<>(); try { - SqlSessionFactory sqlSessionFactory = applicationContext.getBean(SqlSessionFactory.class); + SqlSessionFactory sqlSessionFactory = mainApplicationContext.getBean(SqlSessionFactory.class); LanguageDriverRegistry languageRegistry = sqlSessionFactory.getConfiguration() .getLanguageRegistry(); // 先从 SqlSessionFactory 工厂中获取LanguageDriver @@ -128,7 +128,7 @@ public class PluginFollowCoreConfig { } catch (Exception e){ // ignore } - Map beansLanguageDriver = applicationContext.getBeansOfType(LanguageDriver.class); + Map beansLanguageDriver = mainApplicationContext.getBeansOfType(LanguageDriver.class); if(!beansLanguageDriver.isEmpty()){ beansLanguageDriver.forEach((k, v)->{ // 如果Class一致, 则会覆盖 diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/PluginResourceFinder.java b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/PluginResourceFinder.java index 423fe0b1b30bbd34f218e29cfbf66001c0cec5c2..7dc23d21d22425ab1d0e93d679a21d380b407f24 100644 --- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/PluginResourceFinder.java +++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/PluginResourceFinder.java @@ -37,7 +37,7 @@ public class PluginResourceFinder { public PluginResourceFinder(PluginRegistryInfo pluginRegistryInfo) { - this.classLoader = pluginRegistryInfo.getPluginClassLoader(PluginRegistryInfo.ClassLoaderStrategy.PAD); + this.classLoader = pluginRegistryInfo.getDefaultPluginClassLoader(); this.resourcePatternResolver = new PathMatchingResourcePatternResolver(classLoader);; } diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/SpringBootMybatisExtension.java b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/SpringBootMybatisExtension.java index 4e5689cdaa60dd33773731d6028e57f5f83ec285..acaba4b7b26a62e8aa60a01c9247a3f7ba50314c 100644 --- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/SpringBootMybatisExtension.java +++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/SpringBootMybatisExtension.java @@ -7,6 +7,7 @@ import com.gitee.starblues.extension.mybatis.group.PluginMapperGroup; import com.gitee.starblues.extension.mybatis.mybatisplus.MybatisPlusProcessor; import com.gitee.starblues.extension.mybatis.tkmyabtis.TkMybatisProcessor; import com.gitee.starblues.factory.process.pipe.PluginPipeProcessorExtend; +import com.gitee.starblues.factory.process.pipe.bean.PluginBeanRegistrarExtend; import com.gitee.starblues.factory.process.pipe.classs.PluginClassGroupExtend; import org.springframework.context.ApplicationContext; @@ -42,11 +43,11 @@ public class SpringBootMybatisExtension extends AbstractExtension { } @Override - public void initialize(ApplicationContext applicationContext) throws Exception { + public void initialize(ApplicationContext mainApplicationContext) throws Exception { } @Override - public List getPluginClassGroup(ApplicationContext applicationContext) { + public List getPluginClassGroup(ApplicationContext mainApplicationContext) { final List pluginClassGroups = new ArrayList<>(); pluginClassGroups.add(new MybatisConfigGroup()); pluginClassGroups.add(new PluginEntityAliasesGroup()); @@ -55,16 +56,16 @@ public class SpringBootMybatisExtension extends AbstractExtension { } @Override - public List getPluginPipeProcessor(ApplicationContext applicationContext) { - final List pluginPipeProcessorExtends = new ArrayList<>(); + public List getPluginBeanRegistrar(ApplicationContext mainApplicationContext) { + final List pluginBeanRegistrarExtends = new ArrayList<>(3); if(type == Type.MYBATIS_PLUS){ - pluginPipeProcessorExtends.add(new MybatisPlusProcessor(applicationContext)); + pluginBeanRegistrarExtends.add(new MybatisPlusProcessor()); } else if(type == Type.TK_MYBATIS){ - pluginPipeProcessorExtends.add(new TkMybatisProcessor(applicationContext)); + pluginBeanRegistrarExtends.add(new TkMybatisProcessor()); } else { - pluginPipeProcessorExtends.add(new MybatisProcessor(applicationContext)); + pluginBeanRegistrarExtends.add(new MybatisProcessor()); } - return pluginPipeProcessorExtends; + return pluginBeanRegistrarExtends; } public enum Type{ diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/mybatisplus/MybatisPlusProcessor.java b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/mybatisplus/MybatisPlusProcessor.java index 22336904d730586cbfd50ed1fecec3fcb9a86c3e..012f7c29c7aa8ddda8fcbd5c71a264bdee6fae37 100644 --- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/mybatisplus/MybatisPlusProcessor.java +++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/mybatisplus/MybatisPlusProcessor.java @@ -6,24 +6,20 @@ import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator; import com.baomidou.mybatisplus.core.injector.ISqlInjector; import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; -import com.gitee.starblues.extension.ExtensionConfigUtils; import com.gitee.starblues.extension.mybatis.MapperHandler; import com.gitee.starblues.extension.mybatis.PluginFollowCoreConfig; import com.gitee.starblues.extension.mybatis.PluginResourceFinder; import com.gitee.starblues.factory.PluginRegistryInfo; -import com.gitee.starblues.factory.process.pipe.PluginPipeProcessorExtend; -import com.gitee.starblues.utils.OrderPriority; +import com.gitee.starblues.factory.process.pipe.bean.PluginBeanRegistrarExtend; +import com.gitee.starblues.utils.PluginBeanUtils; import org.apache.ibatis.io.Resources; import org.apache.ibatis.mapping.DatabaseIdProvider; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.scripting.LanguageDriver; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionTemplate; -import org.pf4j.ClassLoadingStrategy; -import org.pf4j.PluginWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.io.Resource; @@ -33,16 +29,12 @@ import org.springframework.core.io.Resource; * @author starBlues * @version 2.3 */ -public class MybatisPlusProcessor implements PluginPipeProcessorExtend { +public class MybatisPlusProcessor implements PluginBeanRegistrarExtend { private static final Logger LOGGER = LoggerFactory.getLogger(MybatisPlusProcessor.class); - private final GenericApplicationContext applicationContext; - private final MapperHandler mapperHandler; - public MybatisPlusProcessor(ApplicationContext applicationContext) { - this.applicationContext = (GenericApplicationContext) applicationContext; - this.mapperHandler = new MapperHandler(this.applicationContext); + public MybatisPlusProcessor() { } @Override @@ -50,33 +42,23 @@ public class MybatisPlusProcessor implements PluginPipeProcessorExtend { return "MybatisPlusProcessor"; } - @Override - public OrderPriority order() { - return OrderPriority.getMiddlePriority(); - } - - @Override - public void initialize() throws Exception { - - } @Override public void registry(PluginRegistryInfo pluginRegistryInfo) throws Exception { - PluginWrapper pluginWrapper = pluginRegistryInfo.getPluginWrapper(); - - SpringBootMybatisPlusConfig config = ExtensionConfigUtils.getConfig(applicationContext, - pluginWrapper.getPluginId(), + SpringBootMybatisPlusConfig config = PluginBeanUtils.getObjectByInterfaceClass( + pluginRegistryInfo.getConfigSingletons(), SpringBootMybatisPlusConfig.class); if(config == null){ return; } - final MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean(); if(config.enableOneselfConfig()){ config.oneselfConfig(factory); } else { - PluginFollowCoreConfig followCoreConfig = new PluginFollowCoreConfig(applicationContext); + PluginFollowCoreConfig followCoreConfig = new PluginFollowCoreConfig( + pluginRegistryInfo.getMainApplicationContext() + ); factory.setDataSource(followCoreConfig.getDataSource()); factory.setConfiguration(followCoreConfig.getMybatisPlusConfiguration()); Interceptor[] interceptor = followCoreConfig.getInterceptor(); @@ -92,7 +74,7 @@ public class MybatisPlusProcessor implements PluginPipeProcessorExtend { factory.setScriptingLanguageDrivers(languageDriver); } // 配置mybatis私有的配置 - mybatisPlusFollowCoreConfig(factory); + mybatisPlusFollowCoreConfig(factory, pluginRegistryInfo.getMainApplicationContext()); } PluginResourceFinder pluginResourceFinder = new PluginResourceFinder(pluginRegistryInfo); @@ -108,12 +90,13 @@ public class MybatisPlusProcessor implements PluginPipeProcessorExtend { } ClassLoader defaultClassLoader = Resources.getDefaultClassLoader(); try { - Resources.setDefaultClassLoader(pluginRegistryInfo.getPluginClassLoader(PluginRegistryInfo.ClassLoaderStrategy.PAD)); + Resources.setDefaultClassLoader(pluginRegistryInfo.getDefaultPluginClassLoader()); SqlSessionFactory sqlSessionFactory = factory.getObject(); if(sqlSessionFactory == null){ throw new Exception("Get mybatis-plus sqlSessionFactory is null"); } SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory); + MapperHandler mapperHandler = new MapperHandler(); mapperHandler.processMapper(pluginRegistryInfo, (holder, mapperClass) -> { mapperHandler.commonProcessMapper(holder, mapperClass, sqlSessionFactory, sqlSessionTemplate); }); @@ -124,40 +107,36 @@ public class MybatisPlusProcessor implements PluginPipeProcessorExtend { } - @Override - public void unRegistry(PluginRegistryInfo pluginRegistryInfo) throws Exception { - mapperHandler.unRegistryMapper(pluginRegistryInfo); - } - private void mybatisPlusFollowCoreConfig(MybatisSqlSessionFactoryBean factory){ - MybatisPlusProperties plusProperties = applicationContext.getBean(MybatisPlusProperties.class); + private void mybatisPlusFollowCoreConfig(MybatisSqlSessionFactoryBean factory, + GenericApplicationContext parentApplicationContext){ + MybatisPlusProperties plusProperties = parentApplicationContext.getBean(MybatisPlusProperties.class); GlobalConfig globalConfig = plusProperties.getGlobalConfig(); - if (this.applicationContext.getBeanNamesForType(IKeyGenerator.class, false, + if (parentApplicationContext.getBeanNamesForType(IKeyGenerator.class, false, false).length > 0) { - IKeyGenerator keyGenerator = this.applicationContext.getBean(IKeyGenerator.class); + IKeyGenerator keyGenerator = parentApplicationContext.getBean(IKeyGenerator.class); globalConfig.getDbConfig().setKeyGenerator(keyGenerator); } - if (this.applicationContext.getBeanNamesForType(MetaObjectHandler.class, + if (parentApplicationContext.getBeanNamesForType(MetaObjectHandler.class, false, false).length > 0) { - MetaObjectHandler metaObjectHandler = this.applicationContext.getBean(MetaObjectHandler.class); + MetaObjectHandler metaObjectHandler = parentApplicationContext.getBean(MetaObjectHandler.class); globalConfig.setMetaObjectHandler(metaObjectHandler); } - if (this.applicationContext.getBeanNamesForType(IKeyGenerator.class, false, + if (parentApplicationContext.getBeanNamesForType(IKeyGenerator.class, false, false).length > 0) { - IKeyGenerator keyGenerator = this.applicationContext.getBean(IKeyGenerator.class); + IKeyGenerator keyGenerator = parentApplicationContext.getBean(IKeyGenerator.class); globalConfig.getDbConfig().setKeyGenerator(keyGenerator); } - if (this.applicationContext.getBeanNamesForType(ISqlInjector.class, false, + if (parentApplicationContext.getBeanNamesForType(ISqlInjector.class, false, false).length > 0) { - ISqlInjector iSqlInjector = this.applicationContext.getBean(ISqlInjector.class); + ISqlInjector iSqlInjector = parentApplicationContext.getBean(ISqlInjector.class); globalConfig.setSqlInjector(iSqlInjector); } factory.setGlobalConfig(globalConfig); } - } diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/tkmyabtis/TkMybatisProcessor.java b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/tkmyabtis/TkMybatisProcessor.java index 8f2689e59c84d319e321ea7a1b296ffa22ea28b0..debfb080a0697492422da32f41fb65eb24e81b7b 100644 --- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/tkmyabtis/TkMybatisProcessor.java +++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/src/main/java/com/gitee/starblues/extension/mybatis/tkmyabtis/TkMybatisProcessor.java @@ -1,27 +1,23 @@ package com.gitee.starblues.extension.mybatis.tkmyabtis; -import com.gitee.starblues.extension.ExtensionConfigUtils; import com.gitee.starblues.extension.mybatis.MapperHandler; import com.gitee.starblues.extension.mybatis.PluginFollowCoreConfig; import com.gitee.starblues.extension.mybatis.PluginResourceFinder; import com.gitee.starblues.extension.mybatis.SpringBootMybatisExtension; import com.gitee.starblues.factory.PluginRegistryInfo; -import com.gitee.starblues.factory.process.pipe.PluginPipeProcessorExtend; -import com.gitee.starblues.utils.OrderPriority; +import com.gitee.starblues.factory.process.pipe.bean.PluginBeanRegistrarExtend; +import com.gitee.starblues.utils.PluginBeanUtils; import org.apache.ibatis.io.Resources; import org.apache.ibatis.mapping.DatabaseIdProvider; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; -import org.pf4j.ClassLoadingStrategy; -import org.pf4j.PluginWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.GenericBeanDefinition; -import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.io.Resource; import tk.mybatis.mapper.entity.Config; @@ -33,17 +29,13 @@ import tk.mybatis.spring.mapper.MapperFactoryBean; * @author starBlues * @version 2.3 */ -public class TkMybatisProcessor implements PluginPipeProcessorExtend { +public class TkMybatisProcessor implements PluginBeanRegistrarExtend { private static final Logger LOGGER = LoggerFactory.getLogger(TkMybatisProcessor.class); - private final GenericApplicationContext applicationContext; - private final MapperHandler mapperHandler; private final MapperFactoryBean mapperFactoryBean = new MapperFactoryBean(); - public TkMybatisProcessor(ApplicationContext applicationContext) { - this.applicationContext = (GenericApplicationContext) applicationContext; - this.mapperHandler = new MapperHandler(this.applicationContext); + public TkMybatisProcessor() { } @Override @@ -51,22 +43,11 @@ public class TkMybatisProcessor implements PluginPipeProcessorExtend { return "TkMybatisProcessor"; } - @Override - public OrderPriority order() { - return OrderPriority.getHighPriority(); - } - - @Override - public void initialize() throws Exception { - - } @Override public void registry(PluginRegistryInfo pluginRegistryInfo) throws Exception { - PluginWrapper pluginWrapper = pluginRegistryInfo.getPluginWrapper(); - - SpringBootTkMybatisConfig config = ExtensionConfigUtils.getConfig(applicationContext, - pluginWrapper.getPluginId(), + SpringBootTkMybatisConfig config = PluginBeanUtils.getObjectByInterfaceClass( + pluginRegistryInfo.getConfigSingletons(), SpringBootTkMybatisConfig.class); if(config == null){ return; @@ -80,7 +61,8 @@ public class TkMybatisProcessor implements PluginPipeProcessorExtend { tkConfig = new Config(); config.oneselfConfig(tkConfig); } else { - PluginFollowCoreConfig followCoreConfig = new PluginFollowCoreConfig(applicationContext); + GenericApplicationContext mainApplicationContext = pluginRegistryInfo.getMainApplicationContext(); + PluginFollowCoreConfig followCoreConfig = new PluginFollowCoreConfig(mainApplicationContext); factory.setDataSource(followCoreConfig.getDataSource()); factory.setConfiguration(followCoreConfig.getConfiguration(SpringBootMybatisExtension.Type.TK_MYBATIS)); Interceptor[] interceptor = followCoreConfig.getInterceptor(); @@ -91,9 +73,9 @@ public class TkMybatisProcessor implements PluginPipeProcessorExtend { if(databaseIdProvider != null){ factory.setDatabaseIdProvider(databaseIdProvider); } - if(applicationContext.getBeanNamesForType(Config.class, + if(mainApplicationContext.getBeanNamesForType(Config.class, false, false).length > 0){ - tkConfig = applicationContext.getBean(Config.class); + tkConfig = mainApplicationContext.getBean(Config.class); } } @@ -114,7 +96,7 @@ public class TkMybatisProcessor implements PluginPipeProcessorExtend { if(xmlResource != null && xmlResource.length > 0){ factory.setMapperLocations(xmlResource); } - ClassLoader pluginClassLoader = pluginRegistryInfo.getPluginClassLoader(PluginRegistryInfo.ClassLoaderStrategy.PAD); + ClassLoader pluginClassLoader = pluginRegistryInfo.getDefaultPluginClassLoader(); ClassLoader defaultClassLoader = Resources.getDefaultClassLoader(); ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); try { @@ -126,10 +108,9 @@ public class TkMybatisProcessor implements PluginPipeProcessorExtend { SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory); // 用于解决Tk中MsUtil的ClassLoader的问题 Thread.currentThread().setContextClassLoader(pluginClassLoader); + MapperHandler mapperHandler = new MapperHandler(); mapperHandler.processMapper(pluginRegistryInfo, (holder, mapperClass) -> { processMapper(holder, mapperClass, mapperHelper, sqlSessionFactory, sqlSessionTemplate); - // tk需要立即生成创建Mapper - applicationContext.getBean(mapperClass); }); } finally { Resources.setDefaultClassLoader(defaultClassLoader); @@ -162,10 +143,4 @@ public class TkMybatisProcessor implements PluginPipeProcessorExtend { } - @Override - public void unRegistry(PluginRegistryInfo pluginRegistryInfo) throws Exception { - mapperHandler.unRegistryMapper(pluginRegistryInfo); - } - - } diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/README.md b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/README.md index 00f1de69c65b55a6e728660bc22962dba12f0500..e6c74e165816f263920c3c737a122930921d417a 100644 --- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/README.md +++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/README.md @@ -1,4 +1,6 @@ -#扩展包 - 集成SpringBoot Mybatis +### 特性 +- 支持通过http访问插件中静态资源 +- 支持集成`Thymeleaf` ### maven 仓库地址 @@ -57,7 +59,7 @@ public PluginApplication pluginApplication(){ 例如: ```java -@Component +@ConfigDefinition public class ResourceConfig implements StaticResourceConfig { @Override public Set locations() { @@ -84,7 +86,7 @@ public class ResourceConfig implements StaticResourceConfig { 例如: ``` java -@Component +@ConfigDefinition public class ResourceConfig implements SpringBootThymeleafConfig { @Override @@ -99,6 +101,10 @@ public class ResourceConfig implements SpringBootThymeleafConfig { ### 版本升级 +#### 2.4.0 版本 +- 修改扩展功能中配置实现类,必须新增`@ConfigDefinition` 注解 +- 修复插件中的静态资源和主程序冲突的bug + #### 2.2.5 版本 1. 新增`Thymeleaf`模板引擎 2. 修改插件中扩展的配置方式 diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/PluginResourceResolverProcess.java b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/PluginResourceResolverProcess.java index 8b0d09312170168176e0dc62e3859aff7600b551..5700e038fac3bc34f14de2f5fb91c66e6005d0a7 100644 --- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/PluginResourceResolverProcess.java +++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/PluginResourceResolverProcess.java @@ -1,13 +1,12 @@ package com.gitee.starblues.extension.resources; -import com.gitee.starblues.extension.ExtensionConfigUtils; import com.gitee.starblues.extension.resources.resolver.PluginResourceResolver; import com.gitee.starblues.factory.PluginRegistryInfo; import com.gitee.starblues.factory.process.post.PluginPostProcessorExtend; import com.gitee.starblues.utils.OrderPriority; +import com.gitee.starblues.utils.PluginBeanUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; import java.util.List; @@ -22,10 +21,8 @@ public class PluginResourceResolverProcess implements PluginPostProcessorExtend private static final Logger LOGGER = LoggerFactory.getLogger(PluginResourceResolverProcess.class); private static final String KEY = "PluginResourceResolverProcess"; - private final ApplicationContext applicationContext; - PluginResourceResolverProcess(ApplicationContext applicationContext) { - this.applicationContext = applicationContext; + PluginResourceResolverProcess() { } @Override @@ -51,9 +48,13 @@ public class PluginResourceResolverProcess implements PluginPostProcessorExtend } String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); try { - StaticResourceConfig staticResourceConfig = ExtensionConfigUtils.getConfig( - applicationContext, pluginId, StaticResourceConfig.class); - PluginResourceResolver.parse(pluginRegistryInfo, staticResourceConfig); + StaticResourceConfig config = PluginBeanUtils.getObjectByInterfaceClass( + pluginRegistryInfo.getConfigSingletons(), + StaticResourceConfig.class); + if(config == null){ + return; + } + PluginResourceResolver.parse(pluginRegistryInfo, config); } catch (Exception e){ LOGGER.error("Parse plugin '{}' static resource failure.", pluginId, e); } @@ -70,7 +71,6 @@ public class PluginResourceResolverProcess implements PluginPostProcessorExtend pluginRegistryInfo.getPluginWrapper().getPluginId(), e); } - } } } diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/StaticResourceExtension.java b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/StaticResourceExtension.java index 4747c7c7448d313e8ac577eb374b3391f9b12bcf..64512ffd631c4951c359a0988b3ae1b2b1c5563f 100644 --- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/StaticResourceExtension.java +++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/StaticResourceExtension.java @@ -43,26 +43,26 @@ public class StaticResourceExtension extends AbstractExtension { } @Override - public void initialize(ApplicationContext applicationContext) throws Exception{ + public void initialize(ApplicationContext mainApplicationContext) throws Exception{ WebMvcConfigurer webMvcConfigurer = new ResourceWebMvcConfigurer(); List webMvcConfigurers = new ArrayList<>(); webMvcConfigurers.add(webMvcConfigurer); DelegatingWebMvcConfiguration support = - applicationContext.getBean(DelegatingWebMvcConfiguration.class); + mainApplicationContext.getBean(DelegatingWebMvcConfiguration.class); support.setConfigurers(webMvcConfigurers); } @Override - public List getPluginPipeProcessor(ApplicationContext applicationContext) { + public List getPluginPipeProcessor(ApplicationContext mainApplicationContext) { final List pluginPipeProcessorExtends = new ArrayList<>(); - pluginPipeProcessorExtends.add(new ThymeleafProcessor(applicationContext)); + pluginPipeProcessorExtends.add(new ThymeleafProcessor()); return pluginPipeProcessorExtends; } @Override - public List getPluginPostProcessor(ApplicationContext applicationContext) { + public List getPluginPostProcessor(ApplicationContext mainApplicationContext) { final List pluginPostProcessorExtends = new ArrayList<>(); - pluginPostProcessorExtends.add(new PluginResourceResolverProcess(applicationContext)); + pluginPostProcessorExtends.add(new PluginResourceResolverProcess()); return pluginPostProcessorExtends; } diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/resolver/PluginResourceResolver.java b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/resolver/PluginResourceResolver.java index c87991750a9495749b4bd5543c18555a0300c7ba..731df42c8c4b76d9bfff7bd049112a96fa0b65af 100644 --- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/resolver/PluginResourceResolver.java +++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/resolver/PluginResourceResolver.java @@ -100,10 +100,11 @@ public class PluginResourceResolver extends AbstractResourceResolver { return null; } - + ClassLoader pluginClassLoader = pluginRegistryInfo.getPluginClassLoader(PluginRegistryInfo.ClassLoaderStrategy.PDA); for (String classPath : classPaths) { try { - Resource resource = new PluginResource(classPath + partialPath, pluginRegistryInfo); + PluginResource resource = new PluginResource(classPath + partialPath, pluginRegistryInfo); + resource.setClassLoader(pluginClassLoader); if(resource.exists()){ return resource; } diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/thymeleaf/ThymeleafProcessor.java b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/thymeleaf/ThymeleafProcessor.java index a27ea9cb37642f08fe147c09fc1160fea2f7ad90..e857deb7d151f4536d2f95e7e5e510fca135f0ee 100644 --- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/thymeleaf/ThymeleafProcessor.java +++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/thymeleaf/ThymeleafProcessor.java @@ -1,12 +1,12 @@ package com.gitee.starblues.extension.resources.thymeleaf; -import com.gitee.starblues.extension.ExtensionConfigUtils; import com.gitee.starblues.factory.PluginRegistryInfo; import com.gitee.starblues.factory.process.pipe.PluginPipeProcessorExtend; import com.gitee.starblues.utils.OrderPriority; +import com.gitee.starblues.utils.PluginBeanUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; import org.thymeleaf.spring5.SpringTemplateEngine; @@ -26,10 +26,7 @@ public class ThymeleafProcessor implements PluginPipeProcessorExtend { private static final String TEMPLATE_RESOLVER_BEAN = "ClassLoaderTemplateResolver"; private static final Logger LOGGER = LoggerFactory.getLogger(ThymeleafProcessor.class); - private final ApplicationContext applicationContext; - - public ThymeleafProcessor(ApplicationContext applicationContext) { - this.applicationContext = applicationContext; + public ThymeleafProcessor() { } @Override @@ -49,14 +46,13 @@ public class ThymeleafProcessor implements PluginPipeProcessorExtend { @Override public void registry(PluginRegistryInfo pluginRegistryInfo) throws Exception { - - SpringTemplateEngine springTemplateEngine = getSpringTemplateEngine(); + SpringTemplateEngine springTemplateEngine = getSpringTemplateEngine(pluginRegistryInfo); if(springTemplateEngine == null){ return; } - String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); - SpringBootThymeleafConfig config = ExtensionConfigUtils.getConfig(applicationContext, - pluginId, SpringBootThymeleafConfig.class); + SpringBootThymeleafConfig config = PluginBeanUtils.getObjectByInterfaceClass( + pluginRegistryInfo.getConfigSingletons(), + SpringBootThymeleafConfig.class); if(config == null){ return; } @@ -114,7 +110,7 @@ public class ThymeleafProcessor implements PluginPipeProcessorExtend { return; } try { - SpringTemplateEngine springTemplateEngine = getSpringTemplateEngine(); + SpringTemplateEngine springTemplateEngine = getSpringTemplateEngine(pluginRegistryInfo); Set templateResolvers = getITemplateResolvers(springTemplateEngine); if(templateResolvers != null){ templateResolvers.remove(resolver); @@ -125,7 +121,8 @@ public class ThymeleafProcessor implements PluginPipeProcessorExtend { } } - private SpringTemplateEngine getSpringTemplateEngine(){ + private SpringTemplateEngine getSpringTemplateEngine(PluginRegistryInfo pluginRegistryInfo){ + GenericApplicationContext applicationContext = pluginRegistryInfo.getMainApplicationContext(); String[] beanNamesForType = applicationContext.getBeanNamesForType(SpringTemplateEngine.class, false, false); if(beanNamesForType.length == 0){ diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/annotation/Caller.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/annotation/Caller.java index 7ac0f9d6239a880de32391b3a401130beea78467..aeca1a289930723fff37dab637f5c466a111ee03 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/annotation/Caller.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/annotation/Caller.java @@ -20,6 +20,12 @@ public @interface Caller { */ String value(); + /** + * 可指定调用哪一个插件 + * @return 插件id + */ + String pluginId() default ""; + /** * 调用者方法注解。配合 @Supper.Method 使用。如果不定义, 则以方法名称为准。 */ diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/annotation/ConfigDefinition.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/annotation/ConfigDefinition.java index 1e2389cbcc2acb116dcfd14a3b6f5603d06ab7a2..4df2a07abb0b980cc7a6e6a7ff6c9481c5dd9ecd 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/annotation/ConfigDefinition.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/annotation/ConfigDefinition.java @@ -3,7 +3,9 @@ package com.gitee.starblues.annotation; import java.lang.annotation.*; /** - * 插件配置文件对应的bean定义注解 + * 插件配置对应的bean定义注解 + * 如果存在配置文件, 则进行属性自定义 + * 如果未依赖配置文件, 则直接定义注解即可 * @author starBlues * @version 1.0 */ @@ -14,10 +16,17 @@ public @interface ConfigDefinition { /** - * 插件中的配置文件的名称 + * 插件中的配置文件的名称. 建议使用 fileName 进行文件名称配置. * @return String */ - String value(); + @Deprecated + String value() default ""; + + /** + * 插件中的配置文件的名称, 新版本替换 value 值 + * @return String + */ + String fileName() default ""; /** * 自定义 bean 名称 diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/AbstractExtension.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/AbstractExtension.java index 8ae1cc17a15dcaf6c9b290ac5b7c21092f4bc318..43fc883a8d753ade156e7bd17284b71fd2eccd13 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/AbstractExtension.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/AbstractExtension.java @@ -1,6 +1,7 @@ package com.gitee.starblues.extension; import com.gitee.starblues.factory.process.pipe.PluginPreProcessorExtend; +import com.gitee.starblues.factory.process.pipe.bean.PluginBeanRegistrarExtend; import com.gitee.starblues.integration.application.PluginApplication; import com.gitee.starblues.factory.process.pipe.loader.PluginResourceLoader; import com.gitee.starblues.factory.process.pipe.PluginPipeProcessorExtend; @@ -20,7 +21,6 @@ public abstract class AbstractExtension { protected PluginApplication pluginApplication; - public void setPluginApplication(PluginApplication pluginApplication) { this.pluginApplication = pluginApplication; } @@ -34,13 +34,12 @@ public abstract class AbstractExtension { /** * 该扩展初始化的操作 * 主要是在插件初始化阶段被调用 - * @param applicationContext applicationContext + * @param mainApplicationContext 主程序ApplicationContext * @throws Exception 初始化异常 */ - public void initialize(ApplicationContext applicationContext) throws Exception{ + public void initialize(ApplicationContext mainApplicationContext) throws Exception{ } - /** * 返回插件的资源加载者。 * 主要是加载插件中的某些资源,比如文件、图片等。 @@ -53,40 +52,50 @@ public abstract class AbstractExtension { /** * 返回扩展的插件中的类分组器。 * 该扩展主要是对插件中的Class文件分组,然后供 PluginPipeProcessor、PluginPostProcessor 阶段使用。 - * @param applicationContext 主程序ApplicationContext + * @param mainApplicationContext 主程序ApplicationContext * @return List PluginPipeProcessorExtend */ - public List getPluginClassGroup(ApplicationContext applicationContext){ + public List getPluginClassGroup(ApplicationContext mainApplicationContext){ return null; } /** * 返回扩展的插件前置处理者。 * 该扩展主要是对每一个插件进行处理 - * @param applicationContext 主程序ApplicationContext + * @param mainApplicationContext 主程序ApplicationContext + * @return List PluginPipeProcessorExtend + */ + public List getPluginPreProcessor(ApplicationContext mainApplicationContext){ + return null; + } + + /** + * 返回扩展的bean定义注册者扩展 + * 该扩展主要是对每一个插件进行处理 + * @param mainApplicationContext 主程序ApplicationContext * @return List PluginPipeProcessorExtend */ - public List getPluginPreProcessor(ApplicationContext applicationContext){ + public List getPluginBeanRegistrar(ApplicationContext mainApplicationContext){ return null; } /** * 返回扩展的流插件处理者。 * 该扩展主要是对每一个插件进行处理 - * @param applicationContext 主程序ApplicationContext + * @param mainApplicationContext 主程序ApplicationContext * @return List PluginPipeProcessorExtend */ - public List getPluginPipeProcessor(ApplicationContext applicationContext){ + public List getPluginPipeProcessor(ApplicationContext mainApplicationContext){ return null; } /** * 返回扩展的插件后置处理者。 * 该扩展主要是对全部插件进行处理。 - * @param applicationContext 主程序ApplicationContext + * @param mainApplicationContext 主程序ApplicationContext * @return List PluginPostProcessorExtend */ - public List getPluginPostProcessor(ApplicationContext applicationContext){ + public List getPluginPostProcessor(ApplicationContext mainApplicationContext){ return null; } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/ExtensionConfigUtils.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/ExtensionConfigUtils.java deleted file mode 100644 index 2b4ee61b1586a9f4ece3cdba750956ee35942536..0000000000000000000000000000000000000000 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/ExtensionConfigUtils.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.gitee.starblues.extension; - -import com.gitee.starblues.factory.PluginInfoContainer; -import org.pf4j.util.StringUtils; -import org.springframework.context.ApplicationContext; - - -/** - * 扩展配置文件工具 - * @author starBlues - * @version 2.4.0 - */ -public class ExtensionConfigUtils { - - private ExtensionConfigUtils(){} - - /** - * 得到扩展的配置 - * @param applicationContext ApplicationContext - * @param pluginId 插件id - * @param tClass 配置类 - * @param 配置类的类型 - * @return 配置类的Spring容器对象 - */ - public static T getConfig(ApplicationContext applicationContext, - String pluginId, - Class tClass){ - try { - String[] beanNamesForType = applicationContext.getBeanNamesForType(tClass, - false, false); - if(beanNamesForType.length == 0){ - return null; - } - for (String beanName : beanNamesForType) { - if(StringUtils.isNullOrEmpty(beanName)){ - continue; - } - if(PluginInfoContainer.existRegisterBeanName(pluginId, beanName)){ - return applicationContext.getBean(beanName, tClass); - } - } - return null; - } catch (Exception e){ - return null; - } - } - -} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/ExtensionInitializer.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/ExtensionInitializer.java index b1e7c0a30fa7a08f38d9f1a07648e65b4833e2e2..4463bdf262afdf44dde5ed83dd61f89608b3d1fe 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/ExtensionInitializer.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/ExtensionInitializer.java @@ -2,6 +2,7 @@ package com.gitee.starblues.extension; import com.gitee.starblues.factory.process.pipe.PluginPipeProcessorExtend; import com.gitee.starblues.factory.process.pipe.PluginPreProcessorExtend; +import com.gitee.starblues.factory.process.pipe.bean.PluginBeanRegistrarExtend; import com.gitee.starblues.factory.process.pipe.classs.PluginClassGroupExtend; import com.gitee.starblues.factory.process.post.PluginPostProcessorExtend; import com.gitee.starblues.factory.process.pipe.loader.PluginResourceLoader; @@ -33,6 +34,7 @@ public class ExtensionInitializer { private static final List RESOURCE_LOADERS_EXTENDS = new ArrayList<>(); private static final List PIPE_PROCESSOR_EXTENDS = new ArrayList<>(); + private static final List BEAN_REGISTRAR_EXTEND = new ArrayList<>(); private static final List CLASS_GROUP_EXTENDS = new ArrayList<>(); private static final List PRE_PROCESSOR_EXTENDS = new ArrayList<>(); private static final List POST_PROCESSOR_EXTENDS = new ArrayList<>(); @@ -70,29 +72,34 @@ public class ExtensionInitializer { StringBuilder debug = new StringBuilder(); debug.append("Plugin extension '").append(abstractExtension.key()).append("'") .append(" are ["); - iteration(abstractExtension.getPluginResourceLoader(), pluginResourceLoader->{ - RESOURCE_LOADERS_EXTENDS.add(pluginResourceLoader); - debug.append(pluginResourceLoader.key()).append("、"); + iteration(abstractExtension.getPluginResourceLoader(), extend->{ + RESOURCE_LOADERS_EXTENDS.add(extend); + debug.append(extend.key()).append("、"); }, bean -> bean.order()); - iteration(abstractExtension.getPluginPreProcessor(applicationContext), pluginPreProcessorExtend->{ - PRE_PROCESSOR_EXTENDS.add(pluginPreProcessorExtend); - debug.append(pluginPreProcessorExtend.key()).append("、"); + iteration(abstractExtension.getPluginPreProcessor(applicationContext), extend->{ + PRE_PROCESSOR_EXTENDS.add(extend); + debug.append(extend.key()).append("、"); }, bean -> bean.order()); - iteration(abstractExtension.getPluginPipeProcessor(applicationContext), pluginPipeProcessorExtend->{ - PIPE_PROCESSOR_EXTENDS.add(pluginPipeProcessorExtend); - debug.append(pluginPipeProcessorExtend.key()).append("、"); + iteration(abstractExtension.getPluginBeanRegistrar(applicationContext), extend->{ + BEAN_REGISTRAR_EXTEND.add(extend); + debug.append(extend.key()).append("、"); + }, null); + + iteration(abstractExtension.getPluginPipeProcessor(applicationContext), extend->{ + PIPE_PROCESSOR_EXTENDS.add(extend); + debug.append(extend.key()).append("、"); }, bean -> bean.order()); - iteration(abstractExtension.getPluginClassGroup(applicationContext), pluginClassGroupExtend->{ - CLASS_GROUP_EXTENDS.add(pluginClassGroupExtend); - debug.append(pluginClassGroupExtend.key()).append("、"); + iteration(abstractExtension.getPluginClassGroup(applicationContext), extend->{ + CLASS_GROUP_EXTENDS.add(extend); + debug.append(extend.key()).append("、"); }, null); - iteration(abstractExtension.getPluginPostProcessor(applicationContext), pluginResourceLoader->{ - POST_PROCESSOR_EXTENDS.add(pluginResourceLoader); - debug.append(pluginResourceLoader.key()); + iteration(abstractExtension.getPluginPostProcessor(applicationContext), extend->{ + POST_PROCESSOR_EXTENDS.add(extend); + debug.append(extend.key()); }, bean -> bean.order()); debug.append("] is registered"); @@ -113,6 +120,10 @@ public class ExtensionInitializer { return PIPE_PROCESSOR_EXTENDS; } + public static List getPluginBeanRegistrarExtends() { + return BEAN_REGISTRAR_EXTEND; + } + public static List getClassGroupExtends() { return CLASS_GROUP_EXTENDS; } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/PluginControllerProcessor.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/PluginControllerProcessor.java index 7b1b431c052e47d576cdc5f08a743a777b91a836..2f927778fc06b53a73d770fb8e4f7a4074768464 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/PluginControllerProcessor.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/extension/PluginControllerProcessor.java @@ -7,6 +7,7 @@ package com.gitee.starblues.extension; * @author starBlues * @version 1.0 */ +@Deprecated public interface PluginControllerProcessor { /** diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/DefaultPluginFactory.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/DefaultPluginFactory.java index 65dbbb2fd24c8f49d3bd74931613bbd571240834..772463b8f197e43b936f58f7604ebba0dbbe1e69 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/DefaultPluginFactory.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/DefaultPluginFactory.java @@ -7,14 +7,10 @@ import com.gitee.starblues.integration.IntegrationConfiguration; import com.gitee.starblues.integration.listener.PluginListener; import com.gitee.starblues.integration.listener.PluginListenerFactory; import com.gitee.starblues.integration.listener.SwaggerListeningListener; -import com.gitee.starblues.utils.AopUtils; -import org.pf4j.PluginRuntimeException; import org.pf4j.PluginWrapper; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericApplicationContext; -import java.io.Closeable; -import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -62,7 +58,6 @@ public class DefaultPluginFactory implements PluginFactory { this.pluginListenerFactory = pluginListenerFactory; } configuration = applicationContext.getBean(IntegrationConfiguration.class); - AopUtils.registered(applicationContext); } @@ -87,18 +82,17 @@ public class DefaultPluginFactory implements PluginFactory { if(!buildContainer.isEmpty() && buildType == 2){ throw new IllegalAccessException("Unable to Registry operate. Because there's no build"); } - AopUtils.resolveAop(pluginWrapper); try { pluginPipeProcessor.registry(pluginRegistryInfo); registerPluginInfoMap.put(pluginWrapper.getPluginId(), pluginRegistryInfo); buildContainer.add(pluginRegistryInfo); return this; } catch (Exception e) { + pluginListenerFactory.failure(pluginWrapper.getPluginId(), e); throw e; } finally { buildType = 1; - AopUtils.recoverAop(); } } @@ -116,6 +110,7 @@ public class DefaultPluginFactory implements PluginFactory { buildContainer.add(registerPluginInfo); return this; } catch (Exception e) { + registerPluginInfo.destroy(); pluginListenerFactory.failure(pluginId, e); throw e; } finally { @@ -140,13 +135,9 @@ public class DefaultPluginFactory implements PluginFactory { unRegistryBuild(); } } finally { - if(buildType == 1){ - AopUtils.recoverAop(); - } else { + if(buildType != 1){ for (PluginRegistryInfo pluginRegistryInfo : buildContainer) { - // 卸载classLoader - closeClassLoader(pluginRegistryInfo); - pluginRegistryInfo.clear(); + pluginRegistryInfo.destroy(); } } buildContainer.clear(); @@ -197,22 +188,7 @@ public class DefaultPluginFactory implements PluginFactory { } } - /** - * 卸载Close Loader - * @param registerPluginInfo registerPluginInfo - */ - private void closeClassLoader(PluginRegistryInfo registerPluginInfo) { - List pluginClassLoaders = registerPluginInfo.getPluginClassLoaders(); - for (ClassLoader pluginClassLoader : pluginClassLoaders) { - if (pluginClassLoader instanceof Closeable) { - try { - ((Closeable) pluginClassLoader).close(); - } catch (IOException e) { - throw new PluginRuntimeException(e, ""); - } - } - } - } + /** * 添加默认插件监听者 diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/PluginInfoContainer.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/PluginInfoContainer.java deleted file mode 100644 index b085447341a118928e576ce522f61990fe07315a..0000000000000000000000000000000000000000 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/PluginInfoContainer.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.gitee.starblues.factory; - -import org.springframework.util.StringUtils; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -/** - * 插件信息共享容器 - * - * @author starBlues - * @version 2.1.0 - */ -public class PluginInfoContainer { - - private PluginInfoContainer(){} - - - /** - * 全局插件中定义的BaneName - */ - private final static Map> REGISTER_BEAN_NAMES = new ConcurrentHashMap<>(); - - /** - * 添加注册的bean名称 - * @param pluginId 插件id - * @param beanName 注册的bean名称 - */ - public static synchronized void addRegisterBeanName(String pluginId, String beanName){ - if(!StringUtils.isEmpty(beanName)){ - Set beanNames = REGISTER_BEAN_NAMES.get(pluginId); - if(beanNames == null){ - beanNames = new HashSet<>(); - REGISTER_BEAN_NAMES.put(pluginId, beanNames); - } - beanNames.add(beanName); - } - } - - /** - * 移除注册的bean名称 - * @param pluginId 插件id - * @param beanName 注册的bean名称 - */ - public static synchronized void removeRegisterBeanName(String pluginId, String beanName){ - Set beanNames = REGISTER_BEAN_NAMES.get(pluginId); - if(beanNames != null){ - beanNames.remove(beanName); - } - } - - /** - * 是否存在bean名称 - * @param pluginId 插件id - * @param beanName 注册的bean名称 - * @return true 存在。false不存在 - */ - public static synchronized boolean existRegisterBeanName(String pluginId, String beanName){ - Set beanNames = REGISTER_BEAN_NAMES.get(pluginId); - if(beanNames != null){ - return beanNames.contains(beanName); - } else { - return false; - } - } - - /** - * 是否存在bean名称 - * @param beanName 注册的bean名称 - * @return true 存在。false不存在 - */ - public static synchronized boolean existRegisterBeanName(String beanName){ - for (Set beanNames : REGISTER_BEAN_NAMES.values()){ - if(beanNames.contains(beanName)){ - return true; - } - } - return false; - } - -} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/PluginRegistryInfo.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/PluginRegistryInfo.java index c6853db624da02f64c03e6208bf94f96674b2265..568c271cec028cc2937cecc5df5d0f970f52015b 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/PluginRegistryInfo.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/PluginRegistryInfo.java @@ -1,12 +1,18 @@ package com.gitee.starblues.factory; +import com.gitee.starblues.factory.process.pipe.PluginInfoContainers; import com.gitee.starblues.factory.process.pipe.loader.ResourceWrapper; import com.gitee.starblues.realize.BasePlugin; import org.pf4j.*; import org.pf4j.util.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.util.ClassUtils; +import java.io.Closeable; +import java.io.IOException; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -18,15 +24,13 @@ import java.util.concurrent.ConcurrentHashMap; */ public class PluginRegistryInfo { - /** - * 扩展存储项 - */ - private final Map extensionMap = new ConcurrentHashMap<>(); + private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final PluginWrapper pluginWrapper; private final PluginManager pluginManager; - private final GenericApplicationContext parentApplicationContext; + private final GenericApplicationContext mainApplicationContext; private final AnnotationConfigApplicationContext pluginApplicationContext; + private final SpringBeanRegister springBeanRegister; /** * 是否跟随主程序启动而初始化 @@ -35,44 +39,56 @@ public class PluginRegistryInfo { private final BasePlugin basePlugin; + /** + * 扩展存储项 + */ + private final Map extensionMap = new ConcurrentHashMap<>(); + + /** + * 插件中的配置单例bean + */ + private final Set configSingletonObjects = new HashSet<>(4); + /** * 插件中的Class */ - private final List> classes = new ArrayList<>(); + private final List> classes = new ArrayList<>(8); + /** * 插件加载的资源 */ - private final Map pluginLoadResources = new ConcurrentHashMap<>(); + private final Map pluginLoadResources = new ConcurrentHashMap<>(8); + /** * 插件中分类的Class */ - private final Map>> groupClasses = new ConcurrentHashMap<>(); + private final Map>> groupClasses = new ConcurrentHashMap<>(8); + /** * 处理者信息 */ - private final Map processorInfo = new ConcurrentHashMap<>(); + private final Map processorInfo = new ConcurrentHashMap<>(8); /** * 自定义策略插件类加载器缓存 */ - private final Map pluginClassLoaders = new ConcurrentHashMap<>(); + private final Map pluginClassLoaders = new ConcurrentHashMap<>(8); private PluginRegistryInfo(PluginWrapper pluginWrapper, PluginManager pluginManager, - GenericApplicationContext parentApplicationContext, + GenericApplicationContext mainApplicationContext, boolean followingInitial) { this.pluginWrapper = pluginWrapper; this.pluginManager = pluginManager; this.basePlugin = (BasePlugin) pluginWrapper.getPlugin(); - this.parentApplicationContext = parentApplicationContext; + this.mainApplicationContext = mainApplicationContext; this.followingInitial = followingInitial; // 生成插件Application - this.pluginApplicationContext = - new AnnotationConfigApplicationContext(); + this.pluginApplicationContext = new AnnotationConfigApplicationContext(); this.pluginApplicationContext.setClassLoader(basePlugin.getWrapper().getPluginClassLoader()); - + this.springBeanRegister = new SpringBeanRegister(pluginApplicationContext); } public static PluginRegistryInfo build(PluginWrapper pluginWrapper, @@ -189,9 +205,24 @@ public class PluginRegistryInfo { } /** - * 添加插件bean注册者信息 - * @param key 扩展的key - * @param value 扩展值 + * 添加插件中的配置对象 + * @param singletonObject 单例对象 + */ + public void addConfigSingleton(Object singletonObject){ + configSingletonObjects.add(singletonObject); + } + + /** + * 添加插件中的配置对象 + */ + public Set getConfigSingletons(){ + return Collections.unmodifiableSet(configSingletonObjects); + } + + /** + * 添加处理者信息 + * @param key key + * @param value value */ public void addProcessorInfo(String key, Object value){ processorInfo.put(key, value); @@ -209,14 +240,30 @@ public class PluginRegistryInfo { extensionMap.put(key, value); } - public GenericApplicationContext getParentApplicationContext() { - return parentApplicationContext; + /** + * 得到主程序的ApplicationContext + * @return GenericApplicationContext + */ + public GenericApplicationContext getMainApplicationContext() { + return mainApplicationContext; } - public AnnotationConfigApplicationContext getPluginApplicationContext() { + /** + * 得到当前插件的ApplicationContext + * @return AnnotationConfigApplicationContext + */ + public GenericApplicationContext getPluginApplicationContext() { return pluginApplicationContext; } + /** + * 得到当前插件Bean注册者 + * @return SpringBeanRegister + */ + public SpringBeanRegister getSpringBeanRegister() { + return springBeanRegister; + } + /** * 移除扩展数据 * @param key 扩展的key @@ -288,16 +335,49 @@ public class PluginRegistryInfo { } - void clear(){ + void destroy(){ + // 关闭ApplicationContext + try { + PluginInfoContainers.removePluginApplicationContext(getPluginWrapper().getPluginId()); + closePluginApplicationContext(); + } catch (Exception e){ + logger.error("Close plugin '{}'-ApplicationContext failure", getPluginWrapper().getPluginId(), e); + } + + // 关闭ClassClassLoader + try { + for (ClassLoader pluginClassLoader : pluginClassLoaders.values()) { + if (pluginClassLoader instanceof Closeable) { + try { + ((Closeable) pluginClassLoader).close(); + } catch (IOException e) { + logger.error("Close plugin '{}'-ClassLoader-'{}' failure", getPluginWrapper().getPluginId(), + pluginClassLoader.getClass().getName(), e); + } + } + } + } finally { + pluginClassLoaders.clear(); + } + + // 清除数据集合 try { extensionMap.clear(); classes.clear(); groupClasses.clear(); processorInfo.clear(); - pluginClassLoaders.clear(); pluginLoadResources.clear(); + configSingletonObjects.clear(); } catch (Exception e){ - e.printStackTrace(); + logger.error("Clear plugin '{}' failure", getPluginWrapper().getPluginId(), e); + } + } + + private void closePluginApplicationContext() { + try { + pluginApplicationContext.close(); + } catch (Exception e){ + logger.error("Close plugin '{}' ApplicationContext failure", getPluginWrapper().getPluginId(), e); } } @@ -306,4 +386,7 @@ public class PluginRegistryInfo { APD, ADP, PAD, DAP, DPA, PDA } + + + } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/SpringBeanRegister.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/SpringBeanRegister.java index 5f2ec71ecf3b9d02061f09520bf37513532a36f8..bf94f7d6c15a9cc072ca2961aea8852563a73424 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/SpringBeanRegister.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/SpringBeanRegister.java @@ -3,10 +3,9 @@ package com.gitee.starblues.factory; import com.gitee.starblues.factory.process.pipe.bean.name.PluginAnnotationBeanNameGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition; import org.springframework.beans.factory.support.BeanNameGenerator; -import org.springframework.context.ApplicationContext; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.support.GenericApplicationContext; import java.text.MessageFormat; @@ -22,10 +21,15 @@ public class SpringBeanRegister { private static final Logger logger = LoggerFactory.getLogger(SpringBeanRegister.class); - private final GenericApplicationContext applicationContext; + private final GenericApplicationContext pluginApplicationContext; - public SpringBeanRegister(ApplicationContext applicationContext){ - this.applicationContext = (GenericApplicationContext) applicationContext; + public SpringBeanRegister(GenericApplicationContext pluginApplicationContext){ + this.pluginApplicationContext = pluginApplicationContext; + } + + + public boolean exist(String name){ + return pluginApplicationContext.containsBean(name); } /** @@ -48,13 +52,13 @@ public class SpringBeanRegister { */ public String register(String pluginId, Class aClass, Consumer consumer) { - AnnotatedGenericBeanDefinition beanDefinition = new - AnnotatedGenericBeanDefinition(aClass); - + AnnotatedGenericBeanDefinition beanDefinition = new AnnotatedGenericBeanDefinition(aClass); + beanDefinition.setBeanClass(aClass); BeanNameGenerator beanNameGenerator = new PluginAnnotationBeanNameGenerator(pluginId); - String beanName = beanNameGenerator.generateBeanName(beanDefinition, applicationContext); - if(PluginInfoContainer.existRegisterBeanName((beanName))){ + String beanName = beanNameGenerator.generateBeanName(beanDefinition, pluginApplicationContext); + + if(pluginApplicationContext.containsBean(beanName)){ String error = MessageFormat.format("Bean name {0} already exist of {1}", beanName, aClass.getName()); logger.debug(error); @@ -63,13 +67,7 @@ public class SpringBeanRegister { if(consumer != null){ consumer.accept(beanDefinition); } - PluginInfoContainer.addRegisterBeanName(pluginId, beanName); - applicationContext.registerBeanDefinition(beanName, beanDefinition); - try { - applicationContext.getBean(beanName); - } catch (BeansException e) { - logger.debug(e.getMessage()); - } + pluginApplicationContext.registerBeanDefinition(beanName, beanDefinition); return beanName; } @@ -96,7 +94,7 @@ public class SpringBeanRegister { Consumer consumer) { AnnotatedGenericBeanDefinition beanDefinition = new AnnotatedGenericBeanDefinition(aClass); - if(PluginInfoContainer.existRegisterBeanName((beanName))){ + if(pluginApplicationContext.containsBean(beanName)){ String error = MessageFormat.format("Bean name {0} already exist of {1}", beanName, aClass.getName()); throw new RuntimeException(error); @@ -104,11 +102,32 @@ public class SpringBeanRegister { if(consumer != null){ consumer.accept(beanDefinition); } - applicationContext.registerBeanDefinition(beanName, beanDefinition); - PluginInfoContainer.addRegisterBeanName(pluginId, beanName); + pluginApplicationContext.registerBeanDefinition(beanName, beanDefinition); + } + + /** + * 注册单例 + * @param name 单例名称 + * @param object 对象 + */ + public void registerSingleton(String name, Object object){ + DefaultListableBeanFactory listableBeanFactory = pluginApplicationContext.getDefaultListableBeanFactory(); + if(!listableBeanFactory.containsSingleton(name)){ + listableBeanFactory.registerSingleton(name, object); + } } + /** + * 销毁单例 + * @param name 单例名称 + */ + public void destroySingleton(String name){ + DefaultListableBeanFactory listableBeanFactory = pluginApplicationContext.getDefaultListableBeanFactory(); + if(listableBeanFactory.containsSingleton(name)){ + listableBeanFactory.destroySingleton(name); + } + } /** * 卸载bean @@ -117,11 +136,9 @@ public class SpringBeanRegister { */ public void unregister(String pluginId, String beanName){ try { - applicationContext.removeBeanDefinition(beanName); + pluginApplicationContext.removeBeanDefinition(beanName); } catch (Exception e){ logger.error("Remove plugin '{}' bean {} error. {}", pluginId, beanName, e.getMessage()); - } finally { - PluginInfoContainer.removeRegisterBeanName(pluginId, beanName); } } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/PluginConfigBeanPipeProcessor.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/PluginConfigBeanPipeProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..52d4b944f9b6c5769e3e00ef3e994035697ec513 --- /dev/null +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/PluginConfigBeanPipeProcessor.java @@ -0,0 +1,64 @@ +package com.gitee.starblues.factory.process.pipe; + +import com.gitee.starblues.factory.PluginRegistryInfo; +import com.gitee.starblues.realize.ConfigBean; +import com.gitee.starblues.utils.PluginBeanUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author starBlues + * @version 1.0 + */ +public class PluginConfigBeanPipeProcessor implements PluginPipeProcessor{ + + private final static String KEY = "ConfigBeans"; + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public void initialize() throws Exception { + + } + + @Override + public void registry(PluginRegistryInfo pluginRegistryInfo) throws Exception { + List pluginBeans = PluginBeanUtils.getPluginBeans(pluginRegistryInfo.getPluginApplicationContext(), + ConfigBean.class); + if(pluginBeans.isEmpty()){ + return; + } + List successConfigBeans = new ArrayList<>(pluginBeans.size()); + for (ConfigBean pluginBean : pluginBeans) { + try { + pluginBean.initialize(); + successConfigBeans.add(pluginBean); + } catch (Exception e){ + logger.error("Plugin '{}' configBean '{}' initialize exception.", + pluginRegistryInfo.getPluginWrapper().getPluginId(), + pluginBean.getClass().getName(), e); + } + } + pluginRegistryInfo.addExtension(KEY, successConfigBeans); + } + + @Override + public void unRegistry(PluginRegistryInfo pluginRegistryInfo) throws Exception { + List pluginBeans = pluginRegistryInfo.getExtension(KEY); + if(pluginBeans == null || pluginBeans.isEmpty()){ + return; + } + for (ConfigBean pluginBean : pluginBeans) { + try { + pluginBean.destroy(); + } catch (Exception e){ + logger.error("Plugin '{}' configBean '{}' destroy exception.", + pluginRegistryInfo.getPluginWrapper().getPluginId(), + pluginBean.getClass().getName(), e); + } + } + } +} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/PluginInfoContainers.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/PluginInfoContainers.java new file mode 100644 index 0000000000000000000000000000000000000000..81fea362f88cd33b099b13d2d9fb190ecc451da4 --- /dev/null +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/PluginInfoContainers.java @@ -0,0 +1,45 @@ +package com.gitee.starblues.factory.process.pipe; + +import org.springframework.context.support.GenericApplicationContext; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 插件信息容器 + * @author starBlues + * @version 2.4.0 + */ +public class PluginInfoContainers { + + private final static Map PLUGIN_APPLICATION_CONTEXTS = + new ConcurrentHashMap<>(); + + + + public static void addPluginApplicationContext(String pluginId, GenericApplicationContext applicationContext){ + PLUGIN_APPLICATION_CONTEXTS.put(pluginId, applicationContext); + } + + public static void removePluginApplicationContext(String pluginId){ + PLUGIN_APPLICATION_CONTEXTS.remove(pluginId); + } + + static public GenericApplicationContext getPluginApplicationContext(String pluginId) { + GenericApplicationContext applicationContext = PLUGIN_APPLICATION_CONTEXTS.get(pluginId); + if(applicationContext == null){ + return null; + } + return applicationContext; + } + + static public List getPluginApplicationContexts() { + Collection values = PLUGIN_APPLICATION_CONTEXTS.values(); + if(values.isEmpty()){ + return Collections.emptyList(); + } + return new ArrayList<>(values); + } + + +} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/PluginPipeApplicationContextProcessor.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/PluginPipeApplicationContextProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..ca2505cbec27dc36cd4cc295a679e4eeb9ad80e6 --- /dev/null +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/PluginPipeApplicationContextProcessor.java @@ -0,0 +1,106 @@ +package com.gitee.starblues.factory.process.pipe; + +import com.gitee.starblues.extension.ExtensionInitializer; +import com.gitee.starblues.factory.PluginRegistryInfo; +import com.gitee.starblues.factory.process.pipe.bean.*; +import com.gitee.starblues.realize.PluginUtils; +import org.pf4j.util.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; + +import java.util.*; + +/** + * 插件的ApplicationContext 处理 + * 主要进行插件bean的扫描 + * @author starBlues + * @version 1.0 + */ +public class PluginPipeApplicationContextProcessor implements PluginPipeProcessor{ + + private final static Logger logger = LoggerFactory.getLogger(PluginPipeApplicationContextProcessor.class); + + private final List pluginBeanDefinitionRegistrars = new ArrayList<>(); + private final ApplicationContext mainApplicationContext; + + public PluginPipeApplicationContextProcessor(ApplicationContext mainApplicationContext) { + this.mainApplicationContext = mainApplicationContext; + } + + @Override + public void initialize() throws Exception { + pluginBeanDefinitionRegistrars.add(new ConfigBeanRegistrar()); + pluginBeanDefinitionRegistrars.add(new ConfigFileBeanRegistrar(mainApplicationContext)); + pluginBeanDefinitionRegistrars.add(new BasicBeanRegistrar()); + pluginBeanDefinitionRegistrars.add(new InvokeBeanRegistrar()); + pluginBeanDefinitionRegistrars.addAll(ExtensionInitializer.getPluginBeanRegistrarExtends()); + } + + @Override + public void registry(PluginRegistryInfo pluginRegistryInfo) throws Exception { + GenericApplicationContext pluginApplicationContext = pluginRegistryInfo.getPluginApplicationContext(); + // 进行bean注册 + for (PluginBeanRegistrar pluginBeanDefinitionRegistrar : pluginBeanDefinitionRegistrars) { + pluginBeanDefinitionRegistrar.registry(pluginRegistryInfo); + } + addBeanExtend(pluginRegistryInfo); + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(pluginRegistryInfo.getDefaultPluginClassLoader()); + pluginApplicationContext.refresh(); + } finally { + Thread.currentThread().setContextClassLoader(contextClassLoader); + } + + // 向插件静态容器中新增插件的ApplicationContext + String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); + PluginInfoContainers.addPluginApplicationContext(pluginId, pluginApplicationContext); + } + + @Override + public void unRegistry(PluginRegistryInfo pluginRegistryInfo) throws Exception { + for (PluginBeanRegistrar registrar : pluginBeanDefinitionRegistrars) { + try { + registrar.unRegistry(pluginRegistryInfo); + } catch (Exception e){ + logger.error("Plugin '{}'-'{}' unRegistry failure.", + pluginRegistryInfo.getPluginWrapper().getPluginId(), + registrar.getClass().getName()); + } + } + removeBeanExtend(pluginRegistryInfo); + } + + + /** + * 向插件ApplicationContext容器中添加扩展的bean + * @param pluginRegistryInfo 插件注册信息 + */ + private void addBeanExtend(PluginRegistryInfo pluginRegistryInfo){ + GenericApplicationContext parentApplicationContext = pluginRegistryInfo.getMainApplicationContext(); + GenericApplicationContext pluginApplicationContext = pluginRegistryInfo.getPluginApplicationContext(); + PluginUtils pluginUtils = new PluginUtils(parentApplicationContext, + pluginApplicationContext, + pluginRegistryInfo.getPluginWrapper().getDescriptor()); + String name = pluginUtils.getClass().getName(); + pluginApplicationContext.getBeanFactory().registerSingleton(name, pluginUtils); + pluginRegistryInfo.addExtension("PluginUtilsName", name); + } + + + /** + * 移除扩展绑定 + * @param pluginRegistryInfo 插件注册信息 + */ + private void removeBeanExtend(PluginRegistryInfo pluginRegistryInfo) { + String pluginUtilsName = pluginRegistryInfo.getExtension("PluginUtilsName"); + if(StringUtils.isNullOrEmpty(pluginUtilsName)){ + return; + } + GenericApplicationContext pluginApplicationContext = pluginRegistryInfo.getPluginApplicationContext(); + pluginApplicationContext.getDefaultListableBeanFactory().destroySingleton(pluginUtilsName); + } + +} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/PluginPipeProcessorFactory.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/PluginPipeProcessorFactory.java index f86a11feb62ef2abc1b737e4b0537d0b195b7d14..1c859a96287cde6aa5607293c98a20592d6c7217 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/PluginPipeProcessorFactory.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/PluginPipeProcessorFactory.java @@ -2,10 +2,6 @@ package com.gitee.starblues.factory.process.pipe; import com.gitee.starblues.extension.ExtensionInitializer; import com.gitee.starblues.factory.PluginRegistryInfo; -import com.gitee.starblues.factory.process.pipe.bean.BasicBeanProcessor; -import com.gitee.starblues.factory.process.pipe.bean.ConfigBeanProcessor; -import com.gitee.starblues.factory.process.pipe.bean.ConfigFileBeanProcessor; -import com.gitee.starblues.factory.process.pipe.bean.OneselfListenerStopEventProcessor; import com.gitee.starblues.factory.process.pipe.classs.PluginClassProcess; import com.gitee.starblues.factory.process.pipe.loader.PluginResourceLoadFactory; import org.slf4j.Logger; @@ -39,16 +35,14 @@ public class PluginPipeProcessorFactory implements PluginPipeProcessor { // 以下顺序不能更改 // 插件资源加载者, 必须放在第一位 pluginPipeProcessors.add(new PluginResourceLoadFactory()); - // OneselfListenerStopEventProcessor 触发停止事件 - pluginPipeProcessors.add(new OneselfListenerStopEventProcessor(applicationContext)); + // 插件类处理者 pluginPipeProcessors.add(new PluginClassProcess()); - // 配置文件在所有bean中第一个初始化。 - pluginPipeProcessors.add(new ConfigFileBeanProcessor(applicationContext)); - // 接下来初始化插件中配置bean的初始化 - pluginPipeProcessors.add(new ConfigBeanProcessor(applicationContext)); // 添加前置扩展 pluginPipeProcessors.addAll(ExtensionInitializer.getPreProcessorExtends()); - pluginPipeProcessors.add(new BasicBeanProcessor(applicationContext)); + // 插件的ApplicationContext处理者 + pluginPipeProcessors.add(new PluginPipeApplicationContextProcessor(applicationContext)); + // 插件ConfigBean处理者 + pluginPipeProcessors.add(new PluginConfigBeanPipeProcessor()); // 添加扩展 pluginPipeProcessors.addAll(ExtensionInitializer.getPipeProcessorExtends()); diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/BasicBeanProcessor.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/BasicBeanProcessor.java deleted file mode 100644 index 96270eab5627568a8c4a1ae2020c7daf7b644004..0000000000000000000000000000000000000000 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/BasicBeanProcessor.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.gitee.starblues.factory.process.pipe.bean; - -import com.gitee.starblues.factory.PluginRegistryInfo; -import com.gitee.starblues.factory.SpringBeanRegister; -import com.gitee.starblues.factory.process.pipe.PluginPipeProcessor; -import com.gitee.starblues.factory.process.pipe.classs.group.ComponentGroup; -import com.gitee.starblues.factory.process.pipe.classs.group.ConfigurationGroup; -import com.gitee.starblues.factory.process.pipe.classs.group.OneselfListenerGroup; -import com.gitee.starblues.factory.process.pipe.classs.group.RepositoryGroup; -import java.lang.reflect.Field; -import java.util.*; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator; -import org.springframework.context.ApplicationContext; -import org.springframework.util.ReflectionUtils; - -/** - * 基础bean注册 - * - * @author starBlues - * @version 2.3 - */ -public class BasicBeanProcessor implements PluginPipeProcessor { - - private static final Logger LOGGER = LoggerFactory.getLogger(BasicBeanProcessor.class); - - private static final String KEY = "BasicBeanProcessor"; - - private final SpringBeanRegister springBeanRegister; - private final ApplicationContext applicationContext; - - public BasicBeanProcessor(ApplicationContext applicationContext){ - Objects.requireNonNull(applicationContext); - this.applicationContext = applicationContext; - this.springBeanRegister = new SpringBeanRegister(applicationContext); - } - - @Override - public void initialize() throws Exception { - - } - - @Override - public void registry(PluginRegistryInfo pluginRegistryInfo) throws Exception { - Set beanNames = new HashSet<>(); - List> springComponents = pluginRegistryInfo - .getGroupClasses(ComponentGroup.GROUP_ID); - List> springConfigurations = pluginRegistryInfo - .getGroupClasses(ConfigurationGroup.GROUP_ID); - List> springRepository = pluginRegistryInfo - .getGroupClasses(RepositoryGroup.GROUP_ID); - List> oneselfListener = pluginRegistryInfo.getGroupClasses(OneselfListenerGroup.GROUP_ID); - - register(pluginRegistryInfo, springComponents, beanNames); - register(pluginRegistryInfo, springConfigurations, beanNames); - register(pluginRegistryInfo, springRepository, beanNames); - register(pluginRegistryInfo, oneselfListener, beanNames); - pluginRegistryInfo.addProcessorInfo(KEY, beanNames); - } - - @Override - public void unRegistry(PluginRegistryInfo pluginRegistryInfo) throws Exception { - Set beanNames = pluginRegistryInfo.getProcessorInfo(KEY); - String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); - if(beanNames != null){ - for (String beanName : beanNames) { - springBeanRegister.unregister(pluginId, beanName); - } - removeProxyBeanName(beanNames, pluginId); - } - } - - /** - * 往Spring注册bean - * @param pluginRegistryInfo 插件注册的信息 - * @param classes 要注册的类集合 - * @param beanNames 存储bean名称集合 - */ - private void register(PluginRegistryInfo pluginRegistryInfo, - List> classes, - Set beanNames){ - if(classes == null || classes.isEmpty()){ - return; - } - String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); - for (Class aClass : classes) { - if(aClass == null){ - continue; - } - String beanName = springBeanRegister.register(pluginId, aClass); - beanNames.add(beanName); - } - } - - /** - * 移除代理类的Bean - * @param beanNames bean名称 - * @param pluginId 插件id - */ - @SuppressWarnings("unchecked") - private void removeProxyBeanName(Set beanNames, String pluginId) { - AbstractAutoProxyCreator proxyCreator = applicationContext.getBean(AbstractAutoProxyCreator.class); - try { - Class aClass = proxyCreator.getClass(); - Field proxyTypesField = ReflectionUtils.findField(aClass, "proxyTypes"); - Map> proxyTypes = null; - if(proxyTypesField != null){ - if (!proxyTypesField.isAccessible()) { - proxyTypesField.setAccessible(true); - } - proxyTypes = (Map>) proxyTypesField.get(proxyCreator); - } - - Field advisedBeansField = ReflectionUtils.findField(aClass, "advisedBeans"); - Map advisedBeans = null; - if(advisedBeansField != null){ - if (!advisedBeansField.isAccessible()) { - advisedBeansField.setAccessible(true); - } - advisedBeans = (Map) advisedBeansField.get(proxyCreator); - } - - for (String beanName : beanNames) { - if(proxyTypes != null){ - proxyTypes.remove(beanName); - } - if(advisedBeans != null){ - advisedBeans.remove(beanName); - } - } - } catch (Exception e) { - LOGGER.error("Remove plugin '{}' proxy bean failure. {}", pluginId, e.getMessage(), e); - } - } - -} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/BasicBeanRegistrar.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/BasicBeanRegistrar.java new file mode 100644 index 0000000000000000000000000000000000000000..69077fbdf4e2ffb541b7c37094624902f0c578e8 --- /dev/null +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/BasicBeanRegistrar.java @@ -0,0 +1,59 @@ +package com.gitee.starblues.factory.process.pipe.bean; + +import com.gitee.starblues.factory.PluginRegistryInfo; +import com.gitee.starblues.factory.SpringBeanRegister; +import com.gitee.starblues.factory.process.pipe.classs.group.ComponentGroup; +import com.gitee.starblues.factory.process.pipe.classs.group.OneselfListenerGroup; +import com.gitee.starblues.factory.process.pipe.classs.group.RepositoryGroup; + +import java.util.*; + +/** + * 基础bean注册 + * + * @author starBlues + * @version 2.4.0 + */ +public class BasicBeanRegistrar implements PluginBeanRegistrar { + + + public BasicBeanRegistrar(){ + } + + @Override + public void registry(PluginRegistryInfo pluginRegistryInfo) throws Exception { + List> springComponents = pluginRegistryInfo + .getGroupClasses(ComponentGroup.GROUP_ID); + List> springRepository = pluginRegistryInfo + .getGroupClasses(RepositoryGroup.GROUP_ID); + List> oneselfListener = pluginRegistryInfo + .getGroupClasses(OneselfListenerGroup.GROUP_ID); + + register(pluginRegistryInfo, springComponents); + register(pluginRegistryInfo, springRepository); + register(pluginRegistryInfo, oneselfListener); + } + + /** + * 往Spring注册bean + * @param pluginRegistryInfo 插件注册的信息 + * @param classes 要注册的类集合 + */ + private void register(PluginRegistryInfo pluginRegistryInfo, + List> classes){ + if(classes == null || classes.isEmpty()){ + return; + } + String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); + SpringBeanRegister springBeanRegister = pluginRegistryInfo.getSpringBeanRegister(); + for (Class aClass : classes) { + if(aClass == null){ + continue; + } + String beanName = springBeanRegister.register(pluginId, aClass); + } + } + + + +} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/ConfigBeanProcessor.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/ConfigBeanRegistrar.java similarity index 32% rename from springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/ConfigBeanProcessor.java rename to springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/ConfigBeanRegistrar.java index 73ce242d9380b434aa5de13852ae5167327c0c60..eff5e403a85a9aaa794557928cc12b490bc3aaa9 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/ConfigBeanProcessor.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/ConfigBeanRegistrar.java @@ -2,12 +2,8 @@ package com.gitee.starblues.factory.process.pipe.bean; import com.gitee.starblues.factory.PluginRegistryInfo; import com.gitee.starblues.factory.SpringBeanRegister; -import com.gitee.starblues.factory.process.pipe.PluginPipeProcessor; import com.gitee.starblues.factory.process.pipe.classs.group.ConfigBeanGroup; import com.gitee.starblues.realize.ConfigBean; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; import java.util.*; @@ -16,26 +12,13 @@ import java.util.*; * @see ConfigBean * * @author starBlues - * @version 2.2.2 + * @version 2.4.0 */ -public class ConfigBeanProcessor implements PluginPipeProcessor { +public class ConfigBeanRegistrar implements PluginBeanRegistrar { - private final Logger log = LoggerFactory.getLogger(this.getClass()); - - private static final String KEY = "ConfigBeanProcessor"; - - private final SpringBeanRegister springBeanRegister; - private final ApplicationContext applicationContext; - - public ConfigBeanProcessor(ApplicationContext applicationContext) { - this.springBeanRegister = new SpringBeanRegister(applicationContext); - this.applicationContext = applicationContext; - } - - - @Override - public void initialize() throws Exception { + public final static String KEY = "ConfigBeanNames"; + public ConfigBeanRegistrar() { } @Override @@ -46,42 +29,13 @@ public class ConfigBeanProcessor implements PluginPipeProcessor { return; } String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); - Map configBeanMap = new HashMap<>(); + SpringBeanRegister springBeanRegister = pluginRegistryInfo.getSpringBeanRegister(); for (Class aClass : configBeans) { if(aClass == null){ continue; } - String name = springBeanRegister.register(pluginId, aClass); - Object bean = applicationContext.getBean(name); - if(bean instanceof ConfigBean){ - ConfigBean configBean = (ConfigBean) bean; - configBean.initialize(); - configBeanMap.put(name, configBean); - } - } - pluginRegistryInfo.addProcessorInfo(KEY, configBeanMap); - } - - @Override - public void unRegistry(PluginRegistryInfo pluginRegistryInfo) throws Exception { - Map configBeanMap = pluginRegistryInfo.getProcessorInfo(KEY); - if(configBeanMap == null){ - return; + springBeanRegister.register(pluginId, aClass); } - String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); - configBeanMap.forEach((beanName, configBean)->{ - if(configBean == null){ - return; - } - try { - configBean.destroy(); - } catch (Exception e) { - log.error("ConfigBean '' destroy exception. {}", e.getMessage(), e); - } - springBeanRegister.unregister(pluginId, beanName); - }); - } - } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/ConfigFileBeanProcessor.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/ConfigFileBeanRegistrar.java similarity index 57% rename from springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/ConfigFileBeanProcessor.java rename to springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/ConfigFileBeanRegistrar.java index 1b40d8349daf6837361c0c515ca19218c14f37bd..f6cee2a61714cea566bb979630f3981003e7a2e2 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/ConfigFileBeanProcessor.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/ConfigFileBeanRegistrar.java @@ -1,50 +1,36 @@ package com.gitee.starblues.factory.process.pipe.bean; import com.gitee.starblues.annotation.ConfigDefinition; -import com.gitee.starblues.factory.PluginInfoContainer; import com.gitee.starblues.factory.PluginRegistryInfo; -import com.gitee.starblues.factory.process.pipe.PluginPipeProcessor; +import com.gitee.starblues.factory.SpringBeanRegister; import com.gitee.starblues.factory.process.pipe.bean.configuration.ConfigurationParser; import com.gitee.starblues.factory.process.pipe.bean.configuration.PluginConfigDefinition; import com.gitee.starblues.factory.process.pipe.bean.configuration.YamlConfigurationParser; import com.gitee.starblues.factory.process.pipe.classs.group.ConfigDefinitionGroup; import com.gitee.starblues.integration.IntegrationConfiguration; import org.pf4j.RuntimeMode; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.pf4j.util.StringUtils; import org.springframework.context.ApplicationContext; -import org.springframework.util.StringUtils; -import java.util.HashSet; import java.util.List; -import java.util.Set; /** * 插件中配置文件 bean 的处理者。包括配置文件 * @author starBlues * @version 2.4.0 */ -public class ConfigFileBeanProcessor implements PluginPipeProcessor { - - private static final String KEY = "ConfigFileBeanProcessor"; +public class ConfigFileBeanRegistrar implements PluginBeanRegistrar { private final ConfigurationParser configurationParser; - private final DefaultListableBeanFactory defaultListableBeanFactory; private final IntegrationConfiguration integrationConfiguration; - public ConfigFileBeanProcessor(ApplicationContext mainApplicationContext) { + public ConfigFileBeanRegistrar(ApplicationContext mainApplicationContext) { integrationConfiguration = mainApplicationContext.getBean(IntegrationConfiguration.class); this.configurationParser = new YamlConfigurationParser(integrationConfiguration); - this.defaultListableBeanFactory = (DefaultListableBeanFactory) - mainApplicationContext.getAutowireCapableBeanFactory(); } - @Override - public void initialize() throws Exception { - - } - @Override public void registry(PluginRegistryInfo pluginRegistryInfo) throws Exception { List> configDefinitions = @@ -52,30 +38,8 @@ public class ConfigFileBeanProcessor implements PluginPipeProcessor { if(configDefinitions == null || configDefinitions.isEmpty()){ return; } - String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); - Set beanNames = new HashSet<>(); for (Class aClass : configDefinitions) { - String beanName = registry(pluginRegistryInfo, aClass); - if(!StringUtils.isEmpty(beanName)){ - beanNames.add(beanName); - PluginInfoContainer.addRegisterBeanName(pluginId, beanName); - } - } - pluginRegistryInfo.addProcessorInfo(KEY, beanNames); - } - - @Override - public void unRegistry(PluginRegistryInfo pluginRegistryInfo) throws Exception { - Set beanNames = pluginRegistryInfo.getProcessorInfo(KEY); - if(beanNames == null){ - return; - } - String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); - for (String beanName : beanNames) { - if(defaultListableBeanFactory.containsSingleton(beanName)){ - defaultListableBeanFactory.destroySingleton(beanName); - PluginInfoContainer.removeRegisterBeanName(pluginId, beanName); - } + registry(pluginRegistryInfo, aClass); } } @@ -91,32 +55,41 @@ public class ConfigFileBeanProcessor implements PluginPipeProcessor { if(configDefinition == null){ return null; } - String fileName = getConfigFileName(configDefinition, aClass); - PluginConfigDefinition pluginConfigDefinition = - new PluginConfigDefinition(fileName, aClass); - Object parseObject = configurationParser.parse(pluginRegistryInfo, - pluginConfigDefinition); + String fileName = getConfigFileName(configDefinition); + Object parseObject = null; + if(!StringUtils.isNullOrEmpty(fileName)){ + PluginConfigDefinition pluginConfigDefinition = + new PluginConfigDefinition(fileName, aClass); + parseObject = configurationParser.parse(pluginRegistryInfo, + pluginConfigDefinition); + } else { + parseObject = aClass.newInstance(); + } + String name = configDefinition.beanName(); - if(StringUtils.isEmpty(name)){ + if(StringUtils.isNullOrEmpty(name)){ name = aClass.getName(); } name = name + "@" + pluginRegistryInfo.getPluginWrapper().getPluginId(); - if(!defaultListableBeanFactory.containsSingleton(name)){ - defaultListableBeanFactory.registerSingleton(name, parseObject); - } + SpringBeanRegister springBeanRegister = pluginRegistryInfo.getSpringBeanRegister(); + springBeanRegister.registerSingleton(name, parseObject); + pluginRegistryInfo.addConfigSingleton(parseObject); return name; } /** * 根据项目运行环境模式来获取配置文件 * @param configDefinition 配置的注解 - * @param aClass 当前配置类 * @return 文件名称 */ - private String getConfigFileName(ConfigDefinition configDefinition, Class aClass){ + private String getConfigFileName(ConfigDefinition configDefinition){ + // TODO 后期移除 value String fileName = configDefinition.value(); - if(StringUtils.isEmpty(fileName)){ - throw new IllegalArgumentException(aClass.getName() + " configDefinition value is null"); + if(StringUtils.isNullOrEmpty(fileName)){ + fileName = configDefinition.fileName(); + if(StringUtils.isNullOrEmpty(fileName)){ + return null; + } } String fileNamePrefix; diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/InvokeBeanRegistrar.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/InvokeBeanRegistrar.java new file mode 100644 index 0000000000000000000000000000000000000000..d040e4e478cc22d1d2bc442882232a4262080ba9 --- /dev/null +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/InvokeBeanRegistrar.java @@ -0,0 +1,310 @@ +package com.gitee.starblues.factory.process.pipe.bean; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.gitee.starblues.annotation.Caller; +import com.gitee.starblues.annotation.Supplier; +import com.gitee.starblues.factory.PluginRegistryInfo; +import com.gitee.starblues.factory.SpringBeanRegister; +import com.gitee.starblues.factory.process.pipe.PluginInfoContainers; +import com.gitee.starblues.factory.process.pipe.classs.group.CallerGroup; +import com.gitee.starblues.factory.process.pipe.classs.group.SupplierGroup; +import com.gitee.starblues.factory.process.post.bean.PluginInvokePostProcessor; +import org.pf4j.util.StringUtils; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.support.GenericBeanDefinition; +import org.springframework.util.ClassUtils; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.text.MessageFormat; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 插件互相调用的bean注册者 + * @author starBlues + * @version 2.4.0 + */ +public class InvokeBeanRegistrar implements PluginBeanRegistrar{ + + private final static Map> PLUGIN_SUPPER_MAP = new ConcurrentHashMap<>(4); + + public static final String SUPPLIER_KEY = "Invoke_Supplier"; + + @Override + public void registry(PluginRegistryInfo pluginRegistryInfo) throws Exception { + registrySupper(pluginRegistryInfo); + registryCall(pluginRegistryInfo); + } + + @Override + public void unRegistry(PluginRegistryInfo pluginRegistryInfo) throws Exception { + PLUGIN_SUPPER_MAP.remove(pluginRegistryInfo.getPluginWrapper().getPluginId()); + } + + /** + * 处理被调用者 + * @param pluginRegistryInfo 插件注册的信息 + * @throws Exception 处理异常 + */ + private void registrySupper(PluginRegistryInfo pluginRegistryInfo) throws Exception { + List> supperClasses = pluginRegistryInfo.getGroupClasses(SupplierGroup.GROUP_ID); + if(supperClasses.isEmpty()){ + return; + } + String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); + SpringBeanRegister springBeanRegister = pluginRegistryInfo.getSpringBeanRegister(); + Set beanNames = new HashSet<>(supperClasses.size()); + for (Class supperClass : supperClasses) { + if(supperClass == null){ + continue; + } + Supplier supplier = supperClass.getAnnotation(Supplier.class); + if(supplier == null){ + continue; + } + String beanName = supplier.value(); + if(springBeanRegister.exist(beanName)){ + String error = MessageFormat.format( + "Plugin {0} : Bean @Supplier name {1} already exist of {2}", + pluginRegistryInfo.getPluginWrapper().getPluginId(), beanName, supperClass.getName()); + throw new Exception(error); + } + springBeanRegister.registerOfSpecifyName(pluginId, beanName, supperClass); + beanNames.add(beanName); + } + pluginRegistryInfo.addExtension(SUPPLIER_KEY, beanNames); + } + + + private void registryCall(PluginRegistryInfo pluginRegistryInfo) { + List> callerClasses = pluginRegistryInfo.getGroupClasses(CallerGroup.GROUP_ID); + if(callerClasses == null || callerClasses.isEmpty()){ + return; + } + String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); + SpringBeanRegister springBeanRegister = pluginRegistryInfo.getSpringBeanRegister(); + for (Class callerClass : callerClasses) { + Caller caller = callerClass.getAnnotation(Caller.class); + if(caller == null){ + continue; + } + springBeanRegister.register(pluginId, callerClass, (beanDefinition) ->{ + beanDefinition.getPropertyValues().add("callerInterface", callerClass); + beanDefinition.getPropertyValues().add("callerAnnotation", caller); + beanDefinition.setBeanClass(CallerInterfaceFactory.class); + beanDefinition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE); + }); + } + + } + + public static void addSupper(String pluginId, String name, Object o){ + Map superMap = PLUGIN_SUPPER_MAP.computeIfAbsent(pluginId, k -> new HashMap<>(4)); + superMap.put(name, o); + } + + public static Object getSupper(String name){ + for (Map superMap : PLUGIN_SUPPER_MAP.values()) { + Object o = superMap.get(name); + if(o != null){ + return o; + } + } + return null; + } + + public static Object getSupper(String pluginId, String name){ + Map superMap = PLUGIN_SUPPER_MAP.get(pluginId); + if(superMap == null || superMap.isEmpty()){ + return null; + } + return superMap.get(name); + } + + + /** + * 调用者的接口工厂 + * @param 接口泛型 + */ + private static class CallerInterfaceFactory implements FactoryBean { + + private Class callerInterface; + private Caller callerAnnotation; + + @Override + public T getObject() throws Exception { + ClassLoader classLoader = callerInterface.getClassLoader(); + Class[] interfaces = new Class[]{callerInterface}; + ProxyHandler proxy = new ProxyHandler(callerAnnotation); + return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy); + } + + @Override + public Class getObjectType() { + return callerInterface; + } + + @Override + public boolean isSingleton() { + return true; + } + + public Class getCallerInterface() { + return callerInterface; + } + + public void setCallerInterface(Class callerInterface) { + this.callerInterface = callerInterface; + } + + public Caller getCallerAnnotation() { + return callerAnnotation; + } + + public void setCallerAnnotation(Caller callerAnnotation) { + this.callerAnnotation = callerAnnotation; + } + } + + + + /** + * 代理类 + */ + private static class ProxyHandler implements InvocationHandler { + + private final Caller callerAnnotation; + + private final static ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + private ProxyHandler(Caller callerAnnotation) { + this.callerAnnotation = callerAnnotation; + } + + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + Object supplierObject = null; + String pluginId = callerAnnotation.pluginId(); + if(StringUtils.isNullOrEmpty(pluginId)){ + supplierObject = getSupper(callerAnnotation.value()); + } else { + supplierObject = getSupper(pluginId, callerAnnotation.value()); + } + if(supplierObject == null){ + if(StringUtils.isNullOrEmpty(pluginId)){ + throw new Exception("Not found '" + callerAnnotation.value() + "' supplier object"); + } else { + throw new Exception("Not found '" + callerAnnotation.value() + "' supplier object in plugin '" + + pluginId + "'"); + } + } + + Caller.Method callerMethod = method.getAnnotation(Caller.Method.class); + if(args == null){ + args = new Object[]{}; + } + if(callerMethod == null){ + return notAnnotationInvoke(method, supplierObject, args); + } else { + return annotationInvoke(method, callerMethod, supplierObject, args); + } + } + + /** + * 有注解的调用 + * @param method 调用接口的方法 + * @param callerMethod 调用者方法注解 + * @param supplierObject 调用者对象 + * @param args 传入参数 + * @return 返回值 + * @throws Throwable 异常 + */ + private Object annotationInvoke(Method method, Caller.Method callerMethod, + Object supplierObject, Object[] args) throws Throwable{ + + String callerMethodName = callerMethod.value(); + Class supplierClass = supplierObject.getClass(); + Method[] methods = supplierClass.getMethods(); + Method supplierMethod = null; + for (Method m : methods) { + Supplier.Method supplierMethodAnnotation = m.getAnnotation(Supplier.Method.class); + if(supplierMethodAnnotation == null){ + continue; + } + if(Objects.equals(supplierMethodAnnotation.value(), callerMethodName)){ + supplierMethod = m; + break; + } + } + if(supplierMethod == null){ + // 如果为空, 说明没有找到被调用者的注解, 则走没有注解的代理调用。 + return notAnnotationInvoke(method, supplierObject, args); + } + Class[] parameterTypes = supplierMethod.getParameterTypes(); + if(parameterTypes.length != args.length){ + // 参数不匹配 + return notAnnotationInvoke(method, supplierObject, args); + } + Object[] supplierArgs = new Object[args.length]; + for (int i = 0; i < parameterTypes.length; i++) { + Class parameterType = parameterTypes[i]; + Object arg = args[i]; + if(parameterType == arg.getClass()){ + supplierArgs[i] = arg; + } else { + // 类型不匹配, 尝试使用json序列化 + String json = OBJECT_MAPPER.writeValueAsString(arg); + Object serializeObject = OBJECT_MAPPER.readValue(json, parameterType); + supplierArgs[i] = serializeObject; + } + } + Object invokeReturn = supplierMethod.invoke(supplierObject, supplierArgs); + return getReturnObject(invokeReturn, method); + } + + /** + * 没有注解调用 + * @param method 调用接口的方法 + * @param supplierObject 提供者对象 + * @param args 传入参数 + * @return 返回值 + * @throws Throwable 异常 + */ + private Object notAnnotationInvoke(Method method, Object supplierObject, Object[] args) throws Throwable{ + String name = method.getName(); + Class[] argClasses = new Class[args.length]; + for (int i = 0; i < args.length; i++) { + argClasses[i] = args[i].getClass(); + } + Class supplierClass = supplierObject.getClass(); + Method supplierMethod = supplierClass.getMethod(name, argClasses); + Object invokeReturn = supplierMethod.invoke(supplierObject, args); + return getReturnObject(invokeReturn, method); + } + + + /** + * 得到返回值对象 + * @param invokeReturn 反射调用后返回的对象 + * @param method 调用接口的方法 + * @return 返回值对象 + * @throws Throwable Throwable + */ + private Object getReturnObject(Object invokeReturn, Method method) throws Throwable{ + if(invokeReturn == null){ + return null; + } + Class returnType = method.getReturnType(); + if(ClassUtils.isAssignable(invokeReturn.getClass(),returnType)){ + return invokeReturn; + } else { + String json = OBJECT_MAPPER.writeValueAsString(invokeReturn); + return OBJECT_MAPPER.readValue(json, OBJECT_MAPPER.getTypeFactory().constructType(method.getGenericReturnType()) ); + } + } + } + +} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/OneselfListenerStopEventProcessor.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/OneselfListenerStopEventProcessor.java deleted file mode 100644 index 7388f1557c71036147321a7e1eed052274263443..0000000000000000000000000000000000000000 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/OneselfListenerStopEventProcessor.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.gitee.starblues.factory.process.pipe.bean; - -import com.gitee.starblues.factory.PluginRegistryInfo; -import com.gitee.starblues.factory.process.pipe.PluginPipeProcessor; -import com.gitee.starblues.factory.process.post.bean.PluginOneselfStartEventProcessor; -import com.gitee.starblues.integration.application.PluginApplication; -import com.gitee.starblues.integration.user.PluginUser; -import com.gitee.starblues.realize.BasePlugin; -import com.gitee.starblues.realize.OneselfListener; -import com.gitee.starblues.utils.CommonUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; - -import java.util.List; -import java.util.Objects; - -/** - * 执行插件自监听器的停止事件的处理者。必须在所有处理者中第一个执行。否则会导致所依赖的bean被卸载。 - * - * @see PluginOneselfStartEventProcessor 触发启动事件 - * @author starBlues - * @version 2.2.1 - */ -public class OneselfListenerStopEventProcessor implements PluginPipeProcessor { - - private final Logger log = LoggerFactory.getLogger(this.getClass()); - - private final PluginUser pluginUser; - - public OneselfListenerStopEventProcessor(ApplicationContext applicationContext){ - Objects.requireNonNull(applicationContext); - PluginApplication pluginApplication = applicationContext.getBean(PluginApplication.class); - this.pluginUser = pluginApplication.getPluginUser(); - } - - - @Override - public void initialize() throws Exception { - - } - - @Override - public void registry(PluginRegistryInfo pluginRegistryInfo) throws Exception {} - - @Override - public void unRegistry(PluginRegistryInfo pluginRegistryInfo) throws Exception { - BasePlugin basePlugin = pluginRegistryInfo.getBasePlugin(); - String pluginId = basePlugin.getWrapper().getPluginId(); - List oneselfListeners = pluginUser.getPluginBeans(pluginId, OneselfListener.class); - oneselfListeners.stream() - .sorted(CommonUtils.orderPriority(oneselfListener -> oneselfListener.order())) - .forEach(oneselfListener -> { - try { - oneselfListener.stopEvent(basePlugin); - } catch (Exception e){ - log.error("OneselfListener {} execute stopEvent exception. {}", - oneselfListener.getClass().getName(), e.getMessage(), e); - } - }); - } -} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/PluginBeanRegister.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/PluginBeanRegister.java deleted file mode 100644 index c3a1106c523b31a3c6c391bb2e0222097e70d16e..0000000000000000000000000000000000000000 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/PluginBeanRegister.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.gitee.starblues.factory.process.pipe.bean; - -import com.gitee.starblues.factory.PluginRegistryInfo; - -/** - * 插件bean注册者 - * - * @author starBlues - * @version 2.1.0 - */ -public interface PluginBeanRegister { - - /** - * 注册者的唯一标识 - * @return String - */ - String key(); - - - /** - * 注册插件中的bane - * @param registerPluginInfo 插件信息 - * @return 返回注册的bean的标识。卸载时,会将该参数传入 - * @throws Exception 插件bean工厂异常 - */ - T registry(PluginRegistryInfo registerPluginInfo) throws Exception; - - /** - * 卸载插件中的bean - * @param registerPluginInfo 插件信息 - * @param t 注册时返回的参数 - * @throws Exception 插件bean工厂异常 - */ - void unRegistry(PluginRegistryInfo registerPluginInfo, T t) throws Exception; - - -} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/PluginBeanRegistrar.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/PluginBeanRegistrar.java new file mode 100644 index 0000000000000000000000000000000000000000..8168c1703f42c43b4c1438afc9fdc3e50562ff6e --- /dev/null +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/PluginBeanRegistrar.java @@ -0,0 +1,26 @@ +package com.gitee.starblues.factory.process.pipe.bean; + +import com.gitee.starblues.factory.PluginRegistryInfo; +import com.gitee.starblues.factory.process.pipe.PluginInfoContainers; + +/** + * @author starBlues + * @version 1.0 + */ +public interface PluginBeanRegistrar { + + + /** + * 处理该插件的注册 + * @throws Exception 处理异常 + */ + void registry(PluginRegistryInfo pluginRegistryInfo) throws Exception; + + /** + * 处理该插件的卸载 + * @param pluginRegistryInfo 插件注册的信息 + * @throws Exception 处理异常 + */ + default void unRegistry(PluginRegistryInfo pluginRegistryInfo) throws Exception{} + +} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/PluginBeanRegistrarExtend.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/PluginBeanRegistrarExtend.java new file mode 100644 index 0000000000000000000000000000000000000000..d9446b1627ead0bd618ee62cd204dfab1dcb5ff4 --- /dev/null +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/PluginBeanRegistrarExtend.java @@ -0,0 +1,15 @@ +package com.gitee.starblues.factory.process.pipe.bean; + +/** + * @author starBlues + * @version 1.0 + */ +public interface PluginBeanRegistrarExtend extends PluginBeanRegistrar { + + /** + * 扩展key + * @return String + */ + String key(); + +} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/configuration/AbstractConfigurationParser.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/configuration/AbstractConfigurationParser.java index 53144b069ff31aba2d495ccdbd3b245614d47da8..89065fa20348f118dd6f7fd96ef05ea207add70b 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/configuration/AbstractConfigurationParser.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/bean/configuration/AbstractConfigurationParser.java @@ -5,7 +5,6 @@ import com.gitee.starblues.integration.IntegrationConfiguration; import com.gitee.starblues.factory.process.pipe.loader.PluginResourceLoader; import com.gitee.starblues.factory.process.pipe.loader.ResourceWrapper; import com.gitee.starblues.factory.process.pipe.loader.load.PluginConfigFileLoader; -import com.gitee.starblues.realize.BasePlugin; import org.springframework.core.io.Resource; import java.util.List; diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/classs/PluginClassProcess.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/classs/PluginClassProcess.java index 497ec7a0e7c972d55443815c87ed91e240b71aee..d85adcc9d5ba963a6969cbe25035b5425b3f1430 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/classs/PluginClassProcess.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/classs/PluginClassProcess.java @@ -47,7 +47,6 @@ public class PluginClassProcess implements PluginPipeProcessor { pluginClassGroups.add(new ComponentGroup()); pluginClassGroups.add(new ControllerGroup()); pluginClassGroups.add(new RepositoryGroup()); - pluginClassGroups.add(new ConfigurationGroup()); pluginClassGroups.add(new ConfigDefinitionGroup()); pluginClassGroups.add(new ConfigBeanGroup()); pluginClassGroups.add(new SupplierGroup()); diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/classs/group/ComponentGroup.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/classs/group/ComponentGroup.java index feef6cc12a7c4f031248c989930b5d9355f186e4..e6819ed0477e6835196d792619268a4f5c510ad3 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/classs/group/ComponentGroup.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/classs/group/ComponentGroup.java @@ -3,8 +3,11 @@ package com.gitee.starblues.factory.process.pipe.classs.group; import com.gitee.starblues.factory.process.pipe.classs.PluginClassGroup; import com.gitee.starblues.realize.BasePlugin; import com.gitee.starblues.utils.AnnotationsUtils; +import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; +import org.springframework.stereotype.Controller; import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; @@ -47,7 +50,8 @@ public class ComponentGroup implements PluginClassGroup { @Override public boolean filter(Class aClass) { - boolean have = AnnotationsUtils.haveAnnotations(aClass, false, Component.class, Service.class); + boolean have = AnnotationsUtils.haveAnnotations(aClass, false, Component.class, Service.class, + Controller.class, RestController.class, Configuration.class); if(!have){ return false; } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/classs/group/ConfigurationGroup.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/classs/group/ConfigurationGroup.java deleted file mode 100644 index fc53fb7a0b7678db50fb43f76c35adb1af35ea45..0000000000000000000000000000000000000000 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/classs/group/ConfigurationGroup.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.gitee.starblues.factory.process.pipe.classs.group; - -import com.gitee.starblues.factory.process.pipe.classs.PluginClassGroup; -import com.gitee.starblues.realize.BasePlugin; -import com.gitee.starblues.utils.AnnotationsUtils; -import org.springframework.context.annotation.Configuration; - -/** - * 分组存在注解: @Configuration - * - * @author starBlues - * @version 2.1.0 - */ -public class ConfigurationGroup implements PluginClassGroup { - - /** - * spring @CONFIGURATION 注解bean - */ - public static final String GROUP_ID = "spring_configuration"; - - - @Override - public String groupId() { - return GROUP_ID; - } - - @Override - public void initialize(BasePlugin basePlugin) { - - } - - @Override - public boolean filter(Class aClass) { - return AnnotationsUtils.haveAnnotations(aClass, false, Configuration.class); - } -} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/loader/PluginResource.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/loader/PluginResource.java index 55e15cdb31ed0fd9c05990d6044e945a70bee884..846daa3962d5e603c438168aad7207ca39ccf5d1 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/loader/PluginResource.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/loader/PluginResource.java @@ -28,7 +28,7 @@ public class PluginResource implements Resource { private final static Logger log = LoggerFactory.getLogger(PluginResource.class); - private final ClassLoader classLoader; + private ClassLoader classLoader; private final PluginWrapper pluginWrapper; private final long lastModified; @@ -48,12 +48,15 @@ public class PluginResource implements Resource { this.path = pathToUse; PluginWrapper pluginWrapper = pluginRegistryInfo.getPluginWrapper(); - this.classLoader = pluginRegistryInfo.getPluginClassLoader(PluginRegistryInfo.ClassLoaderStrategy.PAD); + this.classLoader = pluginRegistryInfo.getDefaultPluginClassLoader(); this.pluginWrapper = pluginWrapper; this.lastModified = pluginRegistryInfo.getBasePlugin().getBasePluginExtend().getStartTimestamp(); } + public void setClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } @Override public InputStream getInputStream() throws IOException { diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/loader/load/PluginConfigFileLoader.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/loader/load/PluginConfigFileLoader.java index b741de6eec2a845e043cae27730c0ba510f6c12b..b47373e655d875d4307b99af45b64dfa5e50db69 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/loader/load/PluginConfigFileLoader.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/pipe/loader/load/PluginConfigFileLoader.java @@ -50,7 +50,7 @@ public class PluginConfigFileLoader implements PluginResourceLoader { BasePlugin basePlugin = pluginRegistryInfo.getBasePlugin(); suppliers.add(findConfigRoot()); suppliers.add(findPluginRoot(basePlugin)); - suppliers.add(findClassPath(pluginRegistryInfo.getPluginClassLoader(PluginRegistryInfo.ClassLoaderStrategy.PAD))); + suppliers.add(findClassPath(pluginRegistryInfo.getDefaultPluginClassLoader())); for (Supplier supplier : suppliers) { diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/PluginPostProcessorFactory.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/PluginPostProcessorFactory.java index b6bc0cb671e5e1c77d301087ec9bee1fe276dca5..20adf9035713b8e6837a76b968571b2886ad0c82 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/PluginPostProcessorFactory.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/PluginPostProcessorFactory.java @@ -21,25 +21,21 @@ public class PluginPostProcessorFactory implements PluginPostProcessor { private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); private final List pluginPostProcessors = new ArrayList<>(); - private final ApplicationContext applicationContext; + private final ApplicationContext mainApplicationContext; - public PluginPostProcessorFactory(ApplicationContext applicationContext){ - this.applicationContext = applicationContext; + public PluginPostProcessorFactory(ApplicationContext mainApplicationContext){ + this.mainApplicationContext = mainApplicationContext; } @Override public void initialize() throws Exception{ - + // 以下顺序不能更改 + pluginPostProcessors.add(new PluginInvokePostProcessor(mainApplicationContext)); + pluginPostProcessors.add(new PluginControllerPostProcessor(mainApplicationContext)); + // 主要触发启动监听事件,因此在最后一个执行。配合 OneselfListenerStopEventProcessor 该类触发启动、停止事件。 + pluginPostProcessors.add(new PluginOneselfStartEventProcessor()); // 添加扩展 pluginPostProcessors.addAll(ExtensionInitializer.getPostProcessorExtends()); - // 以下顺序不能更改。 - pluginPostProcessors.add(new PluginConfigurationPostProcessor(applicationContext)); - pluginPostProcessors.add(new PluginInvokePostProcessor(applicationContext)); - - pluginPostProcessors.add(new PluginControllerPostProcessor(applicationContext)); - // 主要触发启动监听事件,因此在最后一个执行。配合 OneselfListenerStopEventProcessor 该类触发启动、停止事件。 - pluginPostProcessors.add(new PluginOneselfStartEventProcessor(applicationContext)); - // 进行初始化 for (PluginPostProcessor pluginPostProcessor : pluginPostProcessors) { diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginConfigurationPostProcessor.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginConfigurationPostProcessor.java deleted file mode 100644 index 87a985027989ea8266bfdcaa3020f3c7bc946cae..0000000000000000000000000000000000000000 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginConfigurationPostProcessor.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.gitee.starblues.factory.process.post.bean; - -import com.gitee.starblues.factory.PluginRegistryInfo; -import com.gitee.starblues.factory.process.post.PluginPostProcessor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.ConfigurationClassPostProcessor; -import org.springframework.context.support.GenericApplicationContext; - -import java.util.List; -import java.util.Objects; - -/** - * 插件中Configuration处理者 - * - * @author starBlues - * @version 2.1.0 - */ -public class PluginConfigurationPostProcessor implements PluginPostProcessor { - - private final Logger log = LoggerFactory.getLogger(this.getClass()); -; - private final GenericApplicationContext applicationContext; - - public PluginConfigurationPostProcessor(ApplicationContext applicationContext){ - Objects.requireNonNull(applicationContext); - this.applicationContext = (GenericApplicationContext) applicationContext; - } - - - @Override - public void initialize() throws Exception { - - } - - @Override - public void registry(List pluginRegistryInfos) throws Exception { - ConfigurationClassPostProcessor configurationClassPostProcessor = - applicationContext.getBean(ConfigurationClassPostProcessor.class); - configurationClassPostProcessor.processConfigBeanDefinitions(applicationContext); - } - - @Override - public void unRegistry(List pluginRegistryInfos) throws Exception { - - } - -} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginControllerPostProcessor.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginControllerPostProcessor.java index cfa29fe7b941ea940061e58cda49fc2c3a66c458..1d9a3f19e5991936110889bfde863c689cf4dfb7 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginControllerPostProcessor.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginControllerPostProcessor.java @@ -1,19 +1,15 @@ package com.gitee.starblues.factory.process.post.bean; -import com.gitee.starblues.extension.PluginControllerProcessor; import com.gitee.starblues.factory.PluginRegistryInfo; -import com.gitee.starblues.factory.SpringBeanRegister; import com.gitee.starblues.factory.process.pipe.classs.group.ControllerGroup; import com.gitee.starblues.factory.process.post.PluginPostProcessor; import com.gitee.starblues.integration.IntegrationConfiguration; -import com.gitee.starblues.utils.AopUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; @@ -36,15 +32,11 @@ public class PluginControllerPostProcessor implements PluginPostProcessor { private static final String KEY = "PluginControllerPostProcessor"; - private final SpringBeanRegister springBeanRegister; - private final GenericApplicationContext applicationContext; private final RequestMappingHandlerMapping requestMappingHandlerMapping; private final IntegrationConfiguration configuration; public PluginControllerPostProcessor(ApplicationContext applicationContext){ Objects.requireNonNull(applicationContext); - this.springBeanRegister = new SpringBeanRegister(applicationContext); - this.applicationContext = (GenericApplicationContext) applicationContext; this.requestMappingHandlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class); this.configuration = applicationContext.getBean(IntegrationConfiguration.class); } @@ -58,33 +50,24 @@ public class PluginControllerPostProcessor implements PluginPostProcessor { @Override public void registry(List pluginRegistryInfos) throws Exception { for (PluginRegistryInfo pluginRegistryInfo : pluginRegistryInfos) { - AopUtils.resolveAop(pluginRegistryInfo.getPluginWrapper()); - - try { - List> groupClasses = pluginRegistryInfo.getGroupClasses(ControllerGroup.GROUP_ID); - if(groupClasses == null || groupClasses.isEmpty()){ + List> groupClasses = pluginRegistryInfo.getGroupClasses(ControllerGroup.GROUP_ID); + if(groupClasses == null || groupClasses.isEmpty()){ + continue; + } + List controllerBeanWrappers = new ArrayList<>(); + for (Class groupClass : groupClasses) { + if(groupClass == null){ continue; } - List controllerBeanWrappers = new ArrayList<>(); - for (Class groupClass : groupClasses) { - if(groupClass == null){ - continue; - } - try { - ControllerBeanWrapper controllerBeanWrapper = registry(pluginRegistryInfo, groupClass); - process(1, pluginRegistryInfo.getPluginWrapper().getPluginId(), groupClass); - controllerBeanWrappers.add(controllerBeanWrapper); - } catch (Exception e){ - pluginRegistryInfo.addProcessorInfo(getKey(pluginRegistryInfo), controllerBeanWrappers); - throw e; - } + try { + ControllerBeanWrapper controllerBeanWrapper = registry(pluginRegistryInfo, groupClass); + controllerBeanWrappers.add(controllerBeanWrapper); + } catch (Exception e){ + pluginRegistryInfo.addProcessorInfo(getKey(pluginRegistryInfo), controllerBeanWrappers); + throw e; } - - pluginRegistryInfo.addProcessorInfo(getKey(pluginRegistryInfo), controllerBeanWrappers); - } finally { - AopUtils.recoverAop(); } - + pluginRegistryInfo.addProcessorInfo(getKey(pluginRegistryInfo), controllerBeanWrappers); } } @@ -98,17 +81,12 @@ public class PluginControllerPostProcessor implements PluginPostProcessor { if(controllerBeanWrappers == null || controllerBeanWrappers.isEmpty()){ continue; } - String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); for (ControllerBeanWrapper controllerBeanWrapper : controllerBeanWrappers) { if(controllerBeanWrapper == null){ continue; } - unregister(pluginId, controllerBeanWrapper); - process(2, - pluginRegistryInfo.getPluginWrapper().getPluginId(), - controllerBeanWrapper.getBeanClass()); + unregister(controllerBeanWrapper); } - } } @@ -122,18 +100,10 @@ public class PluginControllerPostProcessor implements PluginPostProcessor { private ControllerBeanWrapper registry(PluginRegistryInfo pluginRegistryInfo, Class aClass) throws Exception { String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); - String beanName = springBeanRegister.register(pluginId, aClass); - if(beanName == null || "".equals(beanName)){ - throw new IllegalArgumentException("registry "+ aClass.getName() + "failure!"); - } + GenericApplicationContext pluginApplicationContext = pluginRegistryInfo.getPluginApplicationContext(); try { - Object object = applicationContext.getBean(beanName); - if(object == null){ - throw new Exception("registry "+ aClass.getName() + "failure! " + - "Not found The instance of" + aClass.getName()); - } + Object object = pluginApplicationContext.getBean(aClass); ControllerBeanWrapper controllerBeanWrapper = new ControllerBeanWrapper(); - controllerBeanWrapper.setBeanName(beanName); setPathPrefix(pluginId, aClass); Method getMappingForMethod = ReflectionUtils.findMethod(RequestMappingHandlerMapping.class, "getMappingForMethod", Method.class, Class.class); @@ -153,7 +123,6 @@ public class PluginControllerPostProcessor implements PluginPostProcessor { return controllerBeanWrapper; } catch (Exception e){ // 出现异常, 卸载该 controller bean - springBeanRegister.unregister(pluginId, beanName); throw e; } } @@ -161,24 +130,18 @@ public class PluginControllerPostProcessor implements PluginPostProcessor { /** * 卸载具体的Controller操作 - * @param pluginId 插件id * @param controllerBeanWrapper controllerBean包装 */ - private void unregister(String pluginId, ControllerBeanWrapper controllerBeanWrapper) { + private void unregister(ControllerBeanWrapper controllerBeanWrapper) { Set requestMappingInfos = controllerBeanWrapper.getRequestMappingInfos(); if(requestMappingInfos != null && !requestMappingInfos.isEmpty()){ for (RequestMappingInfo requestMappingInfo : requestMappingInfos) { requestMappingHandlerMapping.unregisterMapping(requestMappingInfo); } } - String beanName = controllerBeanWrapper.getBeanName(); - if(!StringUtils.isEmpty(beanName)){ - springBeanRegister.unregister(pluginId, beanName); - } } - /** * 得到往RegisterPluginInfo->processorInfo 保存的key * @param registerPluginInfo 注册的插件信息 @@ -280,33 +243,33 @@ public class PluginControllerPostProcessor implements PluginPostProcessor { } } - private void process(int type, String pluginId, Class aClass){ - PluginControllerProcessor pluginControllerProcessor = null; - try { - pluginControllerProcessor = applicationContext.getBean(PluginControllerProcessor.class); - }catch (Exception e){ - pluginControllerProcessor = null; - } - if(pluginControllerProcessor == null){ - return; - } - if(type == 1){ - try { - pluginControllerProcessor.registry(pluginId, aClass); - }catch (Exception e){ - log.error("PluginControllerProcessor process {} {} error of registry", - pluginId, aClass.getName()); - } - } else { - try { - pluginControllerProcessor.unRegistry(pluginId, aClass); - }catch (Exception e){ - log.error("PluginControllerProcessor process {} {} error of unRegistry", - pluginId, aClass.getName()); - } - } - - } +// private void process(int type, String pluginId, Class aClass){ +// PluginControllerProcessor pluginControllerProcessor = null; +// try { +// pluginControllerProcessor = applicationContext.getBean(PluginControllerProcessor.class); +// }catch (Exception e){ +// pluginControllerProcessor = null; +// } +// if(pluginControllerProcessor == null){ +// return; +// } +// if(type == 1){ +// try { +// pluginControllerProcessor.registry(pluginId, aClass); +// }catch (Exception e){ +// log.error("PluginControllerProcessor process {} {} error of registry", +// pluginId, aClass.getName()); +// } +// } else { +// try { +// pluginControllerProcessor.unRegistry(pluginId, aClass); +// }catch (Exception e){ +// log.error("PluginControllerProcessor process {} {} error of unRegistry", +// pluginId, aClass.getName()); +// } +// } +// +// } /** * Controller Bean的包装 diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginInvokePostProcessor.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginInvokePostProcessor.java index 052a8199c413701d2713dd549a0a4446ef42d41d..dd64f87c9a4675dfa268866918031193cccf7d06 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginInvokePostProcessor.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginInvokePostProcessor.java @@ -1,52 +1,29 @@ package com.gitee.starblues.factory.process.post.bean; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.gitee.starblues.annotation.Caller; -import com.gitee.starblues.annotation.Supplier; -import com.gitee.starblues.factory.PluginInfoContainer; import com.gitee.starblues.factory.PluginRegistryInfo; -import com.gitee.starblues.factory.SpringBeanRegister; -import com.gitee.starblues.factory.process.pipe.classs.group.CallerGroup; -import com.gitee.starblues.factory.process.pipe.classs.group.SupplierGroup; +import com.gitee.starblues.factory.process.pipe.bean.InvokeBeanRegistrar; import com.gitee.starblues.factory.process.post.PluginPostProcessor; -import com.gitee.starblues.utils.AopUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericApplicationContext; -import org.springframework.util.ClassUtils; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.text.MessageFormat; -import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; /** - * 处理插件中类之间相互调用的的功能 + * 处理插件中类之间相互调用的的功能. 主要获取被调用者的对象, 然后存储到被调用者容器中 * * @author starBlues - * @version 2.1.0 + * @version 2.4.0 */ public class PluginInvokePostProcessor implements PluginPostProcessor { private final Logger log = LoggerFactory.getLogger(this.getClass()); - private final String KEY_SUPPERS = "PluginInvokePostProcessorSuppers"; - private final String KEY_CALLERS = "PluginInvokePostProcessorCallers"; - - private final GenericApplicationContext applicationContext; - private final SpringBeanRegister springBeanRegister; - public PluginInvokePostProcessor(ApplicationContext applicationContext){ Objects.requireNonNull(applicationContext); - this.applicationContext = (GenericApplicationContext) applicationContext; - this.springBeanRegister = new SpringBeanRegister(applicationContext); } @@ -58,27 +35,21 @@ public class PluginInvokePostProcessor implements PluginPostProcessor { @Override public void registry(List pluginRegistryInfos) throws Exception { for (PluginRegistryInfo pluginRegistryInfo : pluginRegistryInfos) { - AopUtils.resolveAop(pluginRegistryInfo.getPluginWrapper()); + String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); try { - List> suppers = pluginRegistryInfo.getGroupClasses(SupplierGroup.GROUP_ID); - if(suppers == null){ + Set supperBeanNames = pluginRegistryInfo.getExtension(InvokeBeanRegistrar.SUPPLIER_KEY); + if(supperBeanNames == null || supperBeanNames.isEmpty()){ continue; } - processSupper(pluginRegistryInfo, suppers); - } finally { - AopUtils.recoverAop(); - } - } - for (PluginRegistryInfo pluginRegistryInfo : pluginRegistryInfos) { - AopUtils.resolveAop(pluginRegistryInfo.getPluginWrapper()); - try { - List> callers = pluginRegistryInfo.getGroupClasses(CallerGroup.GROUP_ID); - if(callers == null){ - continue; + GenericApplicationContext pluginApplicationContext = pluginRegistryInfo.getPluginApplicationContext(); + for (String supperBeanName : supperBeanNames) { + if(pluginApplicationContext.containsBean(supperBeanName)){ + Object bean = pluginApplicationContext.getBean(supperBeanName); + InvokeBeanRegistrar.addSupper(pluginId, supperBeanName, bean); + } } - processCaller(pluginRegistryInfo, callers); - } finally { - AopUtils.recoverAop(); + } catch (Exception e){ + log.error("Process plugin '{}' supper bean exception.", pluginId, e); } } } @@ -86,264 +57,9 @@ public class PluginInvokePostProcessor implements PluginPostProcessor { @Override public void unRegistry(List pluginRegistryInfos) throws Exception{ - for (PluginRegistryInfo pluginRegistryInfo : pluginRegistryInfos) { - Set supperNames = pluginRegistryInfo.getProcessorInfo(getKey(KEY_SUPPERS, pluginRegistryInfo)); - Set callerNames = pluginRegistryInfo.getProcessorInfo(getKey(KEY_CALLERS, pluginRegistryInfo)); - String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); - unregister(pluginId, supperNames); - unregister(pluginId, callerNames); - } + // 什么也不做 } - /** - * 处理被调用者 - * @param pluginRegistryInfo 插件注册的信息 - * @param supperClasses 被调用者集合 - * @throws Exception 处理异常 - */ - private void processSupper(PluginRegistryInfo pluginRegistryInfo, - List> supperClasses) throws Exception { - if(supperClasses.isEmpty()){ - return; - } - Set beanNames = new HashSet<>(); - String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); - for (Class supperClass : supperClasses) { - if(supperClass == null){ - continue; - } - Supplier supplier = supperClass.getAnnotation(Supplier.class); - if(supplier == null){ - continue; - } - String beanName = supplier.value(); - if(PluginInfoContainer.existRegisterBeanName(beanName)){ - String error = MessageFormat.format( - "Plugin {0} : Bean @Supplier name {1} already exist of {2}", - pluginRegistryInfo.getPluginWrapper().getPluginId(), beanName, supperClass.getName()); - throw new Exception(error); - } - springBeanRegister.registerOfSpecifyName(pluginId, beanName, supperClass); - beanNames.add(beanName); - } - pluginRegistryInfo.addProcessorInfo(getKey(KEY_SUPPERS, pluginRegistryInfo), beanNames); - } - /** - * 处理调用者 - * @param pluginRegistryInfo 插件注册的信息 - * @param callerClasses 调用者集合 - * @throws Exception 处理异常 - */ - private void processCaller(PluginRegistryInfo pluginRegistryInfo, List> callerClasses) throws Exception { - if(callerClasses == null || callerClasses.isEmpty()){ - return; - } - Set beanNames = new HashSet<>(); - String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId(); - for (Class callerClass : callerClasses) { - Caller caller = callerClass.getAnnotation(Caller.class); - if(caller == null){ - continue; - } - Object supper = applicationContext.getBean(caller.value()); - if(supper == null){ - return; - } - String beanName = springBeanRegister.register(pluginId, callerClass, (beanDefinition) ->{ - beanDefinition.getPropertyValues().add("callerInterface", callerClass); - beanDefinition.getPropertyValues().add("supper", supper); - beanDefinition.setBeanClass(CallerInterfaceFactory.class); - beanDefinition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE); - }); - beanNames.add(beanName); - } - pluginRegistryInfo.addProcessorInfo(getKey(KEY_CALLERS, pluginRegistryInfo), beanNames); - } - - /** - * 得到往RegisterPluginInfo->processorInfo 保存的key - * @param key key前缀 - * @param pluginRegistryInfo 插件注册的信息 - * @return String - */ - private String getKey(String key, PluginRegistryInfo pluginRegistryInfo){ - return key + "_" + pluginRegistryInfo.getPluginWrapper().getPluginId(); - } - - /** - * 通过beanName卸载 - * @param pluginId 插件id - * @param beanNames beanNames集合 - */ - private void unregister(String pluginId, Set beanNames){ - if(beanNames == null || beanNames.isEmpty()){ - return; - } - for (String beanName : beanNames) { - springBeanRegister.unregister(pluginId, beanName); - } - } - - /** - * 代理类 - */ - private static class ProxyHandler implements InvocationHandler { - - private final Object supplier; - private final static ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - - private ProxyHandler(Object supplier) { - this.supplier = supplier; - } - - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - - Caller.Method callerMethod = method.getAnnotation(Caller.Method.class); - if(callerMethod == null){ - return notAnnotationInvoke(method, args); - } else { - return annotationInvoke(method, callerMethod, args); - } - } - - /** - * 有注解的调用 - * @param method 调用接口的方法 - * @param callerMethod 调用者方法注解 - * @param args 传入参数 - * @return 返回值 - * @throws Throwable 异常 - */ - private Object annotationInvoke(Method method, Caller.Method callerMethod, Object[] args) throws Throwable{ - String callerMethodName = callerMethod.value(); - Class aClass = supplier.getClass(); - Method[] methods = aClass.getMethods(); - Method supplierMethod = null; - for (Method m : methods) { - Supplier.Method supplierMethodAnnotation = m.getAnnotation(Supplier.Method.class); - if(supplierMethodAnnotation == null){ - continue; - } - if(Objects.equals(supplierMethodAnnotation.value(), callerMethodName)){ - supplierMethod = m; - break; - } - } - if(supplierMethod == null){ - // 如果为空, 说明没有找到被调用者的注解, 则走没有注解的代理调用。 - return notAnnotationInvoke(method, args); - } - Class[] parameterTypes = supplierMethod.getParameterTypes(); - if(parameterTypes.length != args.length){ - // 参数不匹配 - return notAnnotationInvoke(method, args); - } - Object[] supplierArgs = new Object[args.length]; - for (int i = 0; i < parameterTypes.length; i++) { - Class parameterType = parameterTypes[i]; - Object arg = args[i]; - if(parameterType == arg.getClass()){ - supplierArgs[i] = arg; - } else { - // 类型不匹配, 尝试使用json序列化 - String json = OBJECT_MAPPER.writeValueAsString(arg); - Object serializeObject = OBJECT_MAPPER.readValue(json, parameterType); - supplierArgs[i] = serializeObject; - } - } - Object invokeReturn = supplierMethod.invoke(supplier, supplierArgs); - return getReturnObject(invokeReturn, method); - } - - /** - * 没有注解调用 - * @param method 调用接口的方法 - * @param args 传入参数 - * @return 返回值 - * @throws Throwable 异常 - */ - private Object notAnnotationInvoke(Method method, Object[] args) throws Throwable{ - String name = method.getName(); - Class[] argClasses = new Class[args.length]; - for (int i = 0; i < args.length; i++) { - argClasses[i] = args[i].getClass(); - } - Method supplierMethod = supplier.getClass().getMethod(name, argClasses); - Object invokeReturn = supplierMethod.invoke(supplier, args); - return getReturnObject(invokeReturn, method); - } - - - /** - * 得到返回值对象 - * @param invokeReturn 反射调用后返回的对象 - * @param method 调用接口的方法 - * @return 返回值对象 - * @throws Throwable Throwable - */ - private Object getReturnObject(Object invokeReturn, Method method) throws Throwable{ - if(invokeReturn == null){ - return null; - } - Class returnType = method.getReturnType(); - if(ClassUtils.isAssignable(invokeReturn.getClass(),returnType)){ - return invokeReturn; - } else { - String json = OBJECT_MAPPER.writeValueAsString(invokeReturn); - return OBJECT_MAPPER.readValue(json, OBJECT_MAPPER.getTypeFactory().constructType(method.getGenericReturnType()) ); - } - } - - - } - - /** - * 调用者的接口工厂 - * @param 接口泛型 - */ - private static class CallerInterfaceFactory implements FactoryBean { - - private Class callerInterface; - private Object supper; - - - @Override - public T getObject() throws Exception { - ClassLoader classLoader = callerInterface.getClassLoader(); - Class[] interfaces = new Class[]{callerInterface}; - ProxyHandler proxy = new ProxyHandler(supper); - return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy); - } - - @Override - public Class getObjectType() { - return callerInterface; - } - - - @Override - public boolean isSingleton() { - return true; - } - - public Class getCallerInterface() { - return callerInterface; - } - - public void setCallerInterface(Class callerInterface) { - this.callerInterface = callerInterface; - } - - public Object getSupper() { - return supper; - } - - public void setSupper(Object supper) { - this.supper = supper; - } - } } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginOneselfStartEventProcessor.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginOneselfStartEventProcessor.java index c7d64d4935f4a093a239ab46cd00be068f09d386..0e89d6ed74c5e1fa300f3c906382be395a4ff4fc 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginOneselfStartEventProcessor.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginOneselfStartEventProcessor.java @@ -1,37 +1,29 @@ package com.gitee.starblues.factory.process.post.bean; import com.gitee.starblues.factory.PluginRegistryInfo; -import com.gitee.starblues.factory.process.pipe.bean.OneselfListenerStopEventProcessor; import com.gitee.starblues.factory.process.post.PluginPostProcessor; -import com.gitee.starblues.integration.application.PluginApplication; -import com.gitee.starblues.integration.user.PluginUser; import com.gitee.starblues.realize.BasePlugin; import com.gitee.starblues.realize.OneselfListener; -import com.gitee.starblues.utils.AopUtils; import com.gitee.starblues.utils.CommonUtils; +import com.gitee.starblues.utils.PluginBeanUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; +import java.util.ArrayList; import java.util.List; -import java.util.Objects; /** * 插件中 OneselfListener 监听者处理者。主要执行监听器的启动事件。 - * @see OneselfListenerStopEventProcessor 触发停止事件 * @author starBlues * @version 2.1.0 */ public class PluginOneselfStartEventProcessor implements PluginPostProcessor { private final Logger log = LoggerFactory.getLogger(this.getClass()); + private final static String KEY = "OneselfListeners"; - private final PluginUser pluginUser; - - public PluginOneselfStartEventProcessor(ApplicationContext applicationContext){ - Objects.requireNonNull(applicationContext); - PluginApplication pluginApplication = applicationContext.getBean(PluginApplication.class); - this.pluginUser = pluginApplication.getPluginUser(); + public PluginOneselfStartEventProcessor(){ } @@ -43,35 +35,52 @@ public class PluginOneselfStartEventProcessor implements PluginPostProcessor { @Override public void registry(List pluginRegistryInfos) throws Exception { for (PluginRegistryInfo pluginRegistryInfo : pluginRegistryInfos) { - AopUtils.resolveAop(pluginRegistryInfo.getPluginWrapper()); + BasePlugin basePlugin = pluginRegistryInfo.getBasePlugin(); try { - BasePlugin basePlugin = pluginRegistryInfo.getBasePlugin(); - String pluginId = basePlugin.getWrapper().getPluginId(); - - List oneselfListeners = pluginUser.getPluginBeans(pluginId, OneselfListener.class); + GenericApplicationContext pluginApplicationContext = pluginRegistryInfo.getPluginApplicationContext(); + List oneselfListeners = PluginBeanUtils.getPluginBeans(pluginApplicationContext, OneselfListener.class); + List saveOneselfListeners = new ArrayList<>(oneselfListeners.size()); oneselfListeners.stream() + .filter(oneselfListener -> oneselfListener != null) .sorted(CommonUtils.orderPriority(oneselfListener -> oneselfListener.order())) .forEach(oneselfListener -> { try { oneselfListener.startEvent(basePlugin); } catch (Exception e){ - log.error("OneselfListener {} execute startEvent exception. {}", + log.error("OneselfListener {} execute stopEvent exception. {}", oneselfListener.getClass().getName(), e.getMessage(), e); + } finally { + saveOneselfListeners.add(oneselfListener); } }); - } finally { - AopUtils.recoverAop(); + if(!saveOneselfListeners.isEmpty()){ + pluginRegistryInfo.addExtension(KEY, saveOneselfListeners); + } + } catch (Exception e){ + log.error("Plugin '{}' OneselfListener process exception.", basePlugin.getWrapper().getPluginId(), e); } } } - @Override public void unRegistry(List pluginRegistryInfos) { - // 此处不卸载调用。 + for (PluginRegistryInfo pluginRegistryInfo : pluginRegistryInfos) { + BasePlugin basePlugin = pluginRegistryInfo.getBasePlugin(); + List oneselfListeners = pluginRegistryInfo.getExtension(KEY); + if(oneselfListeners == null || oneselfListeners.isEmpty()){ + continue; + } + for (OneselfListener oneselfListener : oneselfListeners) { + try { + oneselfListener.stopEvent(basePlugin); + } catch (Exception e){ + log.error("OneselfListener {} execute stopEvent exception. {}", + oneselfListener.getClass().getName(), e.getMessage(), e); + } + } + } } - } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/AutoIntegrationConfiguration.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/AutoIntegrationConfiguration.java index efdf1d90c442a05818ae0ad597b3ab8719b13eef..8ac3c568248c773f6346c56ed0bfcbf5df5e906a 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/AutoIntegrationConfiguration.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/AutoIntegrationConfiguration.java @@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; +import java.util.List; import java.util.Set; /** @@ -64,11 +65,33 @@ public class AutoIntegrationConfiguration extends DefaultIntegrationConfiguratio @Value("${enableSwaggerRefresh:true}") private Boolean enableSwaggerRefresh; + /** + * 在卸载插件后, 备份插件的目录 + */ + @Value("${backupPath:}") + private String backupPath; + + /** + * 上传的插件所存储的临时目录 + */ + @Value("${uploadTempPath:}") + private String uploadTempPath; + + /** + * 启用的插件id + */ + private Set enablePluginIds; + /** * 禁用的插件id, 禁用后系统不会启动该插件 * 如果禁用所有插件, 则Set集合中返回一个字符: * */ - public Set disablePluginIds; + private Set disablePluginIds; + + /** + * 设置初始化时插件启动的顺序 + */ + private List sortInitPluginIds; @Override public RuntimeMode environment() { @@ -94,14 +117,21 @@ public class AutoIntegrationConfiguration extends DefaultIntegrationConfiguratio return enable; } + @Override public String uploadTempPath() { - return super.uploadTempPath(); + if(StringUtils.isNullOrEmpty(uploadTempPath)){ + return super.uploadTempPath(); + } + return uploadTempPath; } @Override public String backupPath() { - return super.backupPath(); + if(StringUtils.isNullOrEmpty(backupPath)){ + return super.backupPath(); + } + return backupPath; } @Override @@ -122,6 +152,12 @@ public class AutoIntegrationConfiguration extends DefaultIntegrationConfiguratio } } + + @Override + public Set enablePluginIds() { + return enablePluginIds; + } + @Override public Set disablePluginIds() { return disablePluginIds; @@ -188,6 +224,30 @@ public class AutoIntegrationConfiguration extends DefaultIntegrationConfiguratio this.enableSwaggerRefresh = enableSwaggerRefresh; } + public String getBackupPath() { + return backupPath; + } + + public void setBackupPath(String backupPath) { + this.backupPath = backupPath; + } + + public String getUploadTempPath() { + return uploadTempPath; + } + + public void setUploadTempPath(String uploadTempPath) { + this.uploadTempPath = uploadTempPath; + } + + public Set getEnablePluginIds() { + return enablePluginIds; + } + + public void setEnablePluginIds(Set enablePluginIds) { + this.enablePluginIds = enablePluginIds; + } + public Set getDisablePluginIds() { return disablePluginIds; } @@ -195,4 +255,12 @@ public class AutoIntegrationConfiguration extends DefaultIntegrationConfiguratio public void setDisablePluginIds(Set disablePluginIds) { this.disablePluginIds = disablePluginIds; } + + public List getSortInitPluginIds() { + return sortInitPluginIds; + } + + public void setSortInitPluginIds(List sortInitPluginIds) { + this.sortInitPluginIds = sortInitPluginIds; + } } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/ConfigurationBuilder.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/ConfigurationBuilder.java index 52ada61d14846fe0c41024711358105b127a74f8..6e973a782ce225bad11cc8b697346136dfa555bf 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/ConfigurationBuilder.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/ConfigurationBuilder.java @@ -3,6 +3,7 @@ package com.gitee.starblues.integration; import org.pf4j.RuntimeMode; import org.springframework.util.StringUtils; +import java.util.List; import java.util.Objects; import java.util.Set; @@ -26,7 +27,9 @@ public class ConfigurationBuilder extends DefaultIntegrationConfiguration{ private Boolean enablePluginIdRestPathPrefix; + private Set enablePluginIds; private Set disablePluginIds; + private List sortInitPluginIds; private Boolean enableSwaggerRefresh; public ConfigurationBuilder(Builder builder) { @@ -38,7 +41,10 @@ public class ConfigurationBuilder extends DefaultIntegrationConfiguration{ this.backupPath = builder.backupPath; this.pluginRestPathPrefix = builder.pluginRestPathPrefix; this.enablePluginIdRestPathPrefix = builder.enablePluginIdRestPathPrefix; + this.enablePluginIds = builder.enablePluginIds; this.disablePluginIds = builder.disablePluginIds; + this.sortInitPluginIds = builder.sortInitPluginIds; + if(builder.enable == null){ this.enable = true; } else { @@ -68,7 +74,9 @@ public class ConfigurationBuilder extends DefaultIntegrationConfiguration{ private String pluginRestPathPrefix; private Boolean enablePluginIdRestPathPrefix; + private Set enablePluginIds; private Set disablePluginIds; + private List sortInitPluginIds; private Boolean enableSwaggerRefresh; public Builder runtimeMode(RuntimeMode runtimeMode){ @@ -111,10 +119,21 @@ public class ConfigurationBuilder extends DefaultIntegrationConfiguration{ return this; } + public Builder enablePluginIds(Set enablePluginIds){ + this.enablePluginIds = enablePluginIds; + return this; + } + public Builder disablePluginIds(Set disablePluginIds){ this.disablePluginIds = disablePluginIds; return this; } + + public Builder sortInitPluginIds(List sortInitPluginIds){ + this.sortInitPluginIds = sortInitPluginIds; + return this; + } + public Builder enableSwaggerRefresh(Boolean enableSwaggerRefresh){ this.enableSwaggerRefresh = enableSwaggerRefresh; return this; @@ -184,8 +203,26 @@ public class ConfigurationBuilder extends DefaultIntegrationConfiguration{ return enable; } + @Override + public Set enablePluginIds() { + return enablePluginIds; + } + @Override public Set disablePluginIds() { return disablePluginIds; } + + @Override + public List sortInitPluginIds() { + return sortInitPluginIds; + } + + @Override + public boolean enableSwaggerRefresh() { + if(enableSwaggerRefresh == null){ + super.enableSwaggerRefresh(); + } + return enableSwaggerRefresh; + } } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/DefaultIntegrationConfiguration.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/DefaultIntegrationConfiguration.java index 9a9b8c2a71503d38f7086024e5cccc91d90ea19d..6a56d5386f4d0296d21e0c8ad91a028f144b8e8b 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/DefaultIntegrationConfiguration.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/DefaultIntegrationConfiguration.java @@ -1,5 +1,6 @@ package com.gitee.starblues.integration; +import java.util.List; import java.util.Set; /** @@ -35,6 +36,10 @@ public abstract class DefaultIntegrationConfiguration implements IntegrationConf return true; } + @Override + public Set enablePluginIds() { + return null; + } @Override public Set disablePluginIds() { @@ -45,4 +50,9 @@ public abstract class DefaultIntegrationConfiguration implements IntegrationConf public boolean enableSwaggerRefresh() { return true; } + + @Override + public List sortInitPluginIds() { + return null; + } } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/IntegrationConfiguration.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/IntegrationConfiguration.java index ddf3245158f9156b7edb73577031dd5410b4088c..a15d55f79886337938b6a581fa22dc088c4af0fa 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/IntegrationConfiguration.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/IntegrationConfiguration.java @@ -2,6 +2,7 @@ package com.gitee.starblues.integration; import org.pf4j.RuntimeMode; +import java.util.List; import java.util.Set; @@ -65,6 +66,12 @@ public interface IntegrationConfiguration { */ boolean enable(); + /** + * 启用的插件id + * @return Set + */ + Set enablePluginIds(); + /** * 禁用的插件id, 禁用后系统不会启动该插件 * 如果禁用所有插件, 则Set集合中返回一个字符: * @@ -78,4 +85,10 @@ public interface IntegrationConfiguration { */ boolean enableSwaggerRefresh(); + /** + * 设置初始化时插件启动的顺序. + * @return 有顺序的插件id + */ + List sortInitPluginIds(); + } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/application/DefaultPluginApplication.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/application/DefaultPluginApplication.java index 26ec551c81978bb3398266e60b0f2476e7338909..7814b7dffc37541949d62d06f98313eff6b57b2c 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/application/DefaultPluginApplication.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/application/DefaultPluginApplication.java @@ -91,7 +91,7 @@ public class DefaultPluginApplication extends AbstractPluginApplication { pluginManager, this.listenerFactory ); - return new PluginOperatorWrapper(pluginOperator, configuration, applicationContext); + return new PluginOperatorWrapper(pluginOperator, configuration); } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/operator/PluginOperatorWrapper.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/operator/PluginOperatorWrapper.java index 31e7982b0b4cb477680a59b072475ae43562d958..b1418004d10a371e9540a69caf9e20aacedf9869 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/operator/PluginOperatorWrapper.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/operator/PluginOperatorWrapper.java @@ -1,15 +1,17 @@ package com.gitee.starblues.integration.operator; -import com.gitee.starblues.extension.ExtensionConfigUtils; +import com.gitee.starblues.factory.process.pipe.PluginInfoContainers; import com.gitee.starblues.integration.IntegrationConfiguration; import com.gitee.starblues.integration.listener.PluginInitializerListener; import com.gitee.starblues.integration.operator.module.PluginInfo; +import com.gitee.starblues.realize.PluginUtils; import com.gitee.starblues.realize.UnRegistryValidator; +import com.gitee.starblues.utils.PluginBeanUtils; import org.pf4j.PluginWrapper; import org.pf4j.util.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; import org.springframework.web.multipart.MultipartFile; import java.nio.file.Path; @@ -28,14 +30,11 @@ public class PluginOperatorWrapper implements PluginOperator{ private final PluginOperator pluginOperator; private final IntegrationConfiguration integrationConfiguration; - private final ApplicationContext applicationContext; public PluginOperatorWrapper(PluginOperator pluginOperator, - IntegrationConfiguration integrationConfiguration, - ApplicationContext applicationContext) { + IntegrationConfiguration integrationConfiguration) { this.pluginOperator = pluginOperator; this.integrationConfiguration = integrationConfiguration; - this.applicationContext = applicationContext; } @Override @@ -184,20 +183,24 @@ public class PluginOperatorWrapper implements PluginOperator{ * @throws Exception 检查异常 */ private void checkIsUnRegistry(String pluginId) throws Exception{ - UnRegistryValidator unRegistryValidator = ExtensionConfigUtils - .getConfig(applicationContext, pluginId, UnRegistryValidator.class); - if(unRegistryValidator == null){ + GenericApplicationContext pluginApplicationContext = PluginInfoContainers.getPluginApplicationContext(pluginId); + if(pluginApplicationContext == null){ + log.error("Plugin '{}' Not found ApplicationContext. So cannot found and execute unRegistryValidator", + pluginId); return; } - UnRegistryValidator.Result result = unRegistryValidator.verify(); - if(result.isVerify()){ - return; - } - String message = result.getMessage(); - if(StringUtils.isNullOrEmpty(message)){ - message = "Plugin [" + pluginId + "] Stop or Uninstall be banned"; + List unRegistryValidators = PluginBeanUtils.getPluginBeans(pluginApplicationContext, UnRegistryValidator.class); + for (UnRegistryValidator unRegistryValidator : unRegistryValidators) { + UnRegistryValidator.Result result = unRegistryValidator.verify(); + if(result.isVerify()){ + return; + } + String message = result.getMessage(); + if(StringUtils.isNullOrEmpty(message)){ + message = "Plugin [" + pluginId + "] Stop or Uninstall be banned"; + } + throw new Exception(message); } - throw new Exception(message); } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/pf4j/ConfigPluginStatusProvider.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/pf4j/ConfigPluginStatusProvider.java index 75f39f077c6f614b5c39466e49ce222f8e6cacf1..ff16b489e8cda94aedf41e9a7ec2775ee5c63d6b 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/pf4j/ConfigPluginStatusProvider.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/pf4j/ConfigPluginStatusProvider.java @@ -11,13 +11,18 @@ import java.util.Set; */ public class ConfigPluginStatusProvider implements PluginStatusProvider { + private Set enablePluginIds = new HashSet<>(); private Set disabledPlugins = new HashSet<>(); public ConfigPluginStatusProvider() { - this(null); + this(null, null); } - public ConfigPluginStatusProvider(Set disabledPluginIds) { + public ConfigPluginStatusProvider(Set enablePluginIds, + Set disabledPluginIds) { + if(enablePluginIds != null && !enablePluginIds.isEmpty()){ + this.enablePluginIds.addAll(enablePluginIds); + } if(disabledPluginIds != null && !disabledPluginIds.isEmpty()){ this.disabledPlugins.addAll(disabledPluginIds); } @@ -29,10 +34,11 @@ public class ConfigPluginStatusProvider implements PluginStatusProvider { if(disabledPlugins.contains("*")){ return true; } - if(pluginId == null || "".equals(pluginId)){ + if (disabledPlugins.contains(pluginId)) { return true; } - return disabledPlugins.contains(pluginId); + + return !enablePluginIds.isEmpty() && !enablePluginIds.contains(pluginId); } @Override @@ -41,6 +47,7 @@ public class ConfigPluginStatusProvider implements PluginStatusProvider { return; } disabledPlugins.add(pluginId); + enablePluginIds.remove(pluginId); } @Override @@ -49,5 +56,6 @@ public class ConfigPluginStatusProvider implements PluginStatusProvider { return; } disabledPlugins.remove(pluginId); + enablePluginIds.add(pluginId); } } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/pf4j/DefaultPf4jFactory.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/pf4j/DefaultPf4jFactory.java index fe811ec166d28bdd777a887771ab8a66fea3a827..2294e88542e1b9ed1548d7caab2c23b427b86a9d 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/pf4j/DefaultPf4jFactory.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/pf4j/DefaultPf4jFactory.java @@ -5,6 +5,7 @@ import org.pf4j.*; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.List; import java.util.Objects; /** @@ -30,10 +31,18 @@ public class DefaultPf4jFactory implements Pf4jFactory { if(environment == null){ throw new RuntimeException("Configuration RuntimeMode is null" + configuration.environment()); } + List sortInitPluginIds = configuration.sortInitPluginIds(); if(RuntimeMode.DEVELOPMENT == environment){ // 开发环境下的插件管理者 Path path = Paths.get(getDevPluginDir(configuration)); return new DefaultPluginManager(path){ + + @Override + protected void initialize() { + super.initialize(); + dependencyResolver = new SortDependencyResolver(sortInitPluginIds, versionManager); + } + @Override public RuntimeMode getRuntimeMode() { System.setProperty("pf4j.mode", RuntimeMode.DEVELOPMENT.toString()); @@ -53,17 +62,21 @@ public class DefaultPf4jFactory implements Pf4jFactory { @Override protected PluginStatusProvider createPluginStatusProvider() { - return new ConfigPluginStatusProvider(configuration.disablePluginIds()); + return new ConfigPluginStatusProvider( + configuration.enablePluginIds(), + configuration.disablePluginIds()); } + }; } else if(RuntimeMode.DEPLOYMENT == environment){ // 运行环境下的插件管理者 Path path = Paths.get(getProdPluginDir(configuration)); return new DefaultPluginManager(path){ + @Override - protected PluginRepository createPluginRepository() { - return new CompoundPluginRepository() - .add(new JarPluginRepository(getPluginsRoot())); + protected void initialize() { + super.initialize(); + dependencyResolver = new SortDependencyResolver(sortInitPluginIds, versionManager); } @Override @@ -73,7 +86,9 @@ public class DefaultPf4jFactory implements Pf4jFactory { @Override protected PluginStatusProvider createPluginStatusProvider() { - return new ConfigPluginStatusProvider(configuration.disablePluginIds()); + return new ConfigPluginStatusProvider( + configuration.enablePluginIds(), + configuration.disablePluginIds()); } @Override diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/pf4j/SortDependencyResolver.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/pf4j/SortDependencyResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..7e02bf48cf461aeaf0c5f9e88b793c9f1c7a69bc --- /dev/null +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/pf4j/SortDependencyResolver.java @@ -0,0 +1,81 @@ +package com.gitee.starblues.integration.pf4j; + +import org.pf4j.DependencyResolver; +import org.pf4j.PluginDescriptor; +import org.pf4j.VersionManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +/** + * @author starBlues + * @version 1.0 + */ +public class SortDependencyResolver extends DependencyResolver { + + private final static Logger LOGGER = LoggerFactory.getLogger(SortDependencyResolver.class); + + private final List sortInitPluginIds; + + public SortDependencyResolver(List sortInitPluginIds, VersionManager versionManager) { + super(versionManager); + this.sortInitPluginIds = sortInitPluginIds; + } + + @Override + public Result resolve(List plugins) { + Result resolve = super.resolve(plugins); + if(sortInitPluginIds == null || sortInitPluginIds.isEmpty()){ + return resolve; + } + List sortedPlugins = resolve.getSortedPlugins(); + List newSortPluginIds = new ArrayList<>(sortedPlugins.size()); + for (String sortPluginId : sortInitPluginIds) { + Iterator iterator = sortedPlugins.iterator(); + while (iterator.hasNext()){ + String id = iterator.next(); + if(Objects.equals(id, sortPluginId)){ + newSortPluginIds.add(id); + iterator.remove(); + } + } + } + if(!sortedPlugins.isEmpty()){ + newSortPluginIds.addAll(sortedPlugins); + } + + return getSortResult(resolve, newSortPluginIds); + } + + @SuppressWarnings("unchecked") + private Result getSortResult(Result resolve, List newSortPluginIds ){ + try { + Field sortedPluginsField = ReflectionUtils.findField(Result.class, "sortedPlugins"); + List sortedPlugins = null; + if(sortedPluginsField != null){ + if (!sortedPluginsField.isAccessible()) { + sortedPluginsField.setAccessible(true); + } + sortedPlugins = (List) sortedPluginsField.get(resolve); + } + if(sortedPlugins == null){ + return resolve; + } + sortedPlugins.clear(); + sortedPlugins.addAll(newSortPluginIds); + return resolve; + } catch (Exception e){ + LOGGER.error("Set plugin init sort failure. use default sort init plugin. " + e.getMessage()); + return resolve; + } + } + + + +} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/user/DefaultPluginUser.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/user/DefaultPluginUser.java index 96ed61990d1708b95b3540c7721b322f73e19dd5..b65c62b2fd8588d5e60682afaa7325e98440b713 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/user/DefaultPluginUser.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/user/DefaultPluginUser.java @@ -1,6 +1,7 @@ package com.gitee.starblues.integration.user; -import com.gitee.starblues.factory.PluginInfoContainer; +import com.gitee.starblues.factory.process.pipe.PluginInfoContainers; +import com.gitee.starblues.utils.PluginBeanUtils; import org.pf4j.PluginManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -8,7 +9,6 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericApplicationContext; import java.util.*; -import java.util.stream.Collectors; /** * 默认插件使用者 @@ -19,13 +19,14 @@ public class DefaultPluginUser implements PluginUser{ protected final Logger log = LoggerFactory.getLogger(this.getClass()); - protected final GenericApplicationContext applicationContext; + protected final GenericApplicationContext parentApplicationContext; + protected final PluginManager pluginManager; - public DefaultPluginUser(ApplicationContext applicationContext, PluginManager pluginManager) { - Objects.requireNonNull(applicationContext, "ApplicationContext can't be null"); + public DefaultPluginUser(ApplicationContext parentApplicationContext, PluginManager pluginManager) { + Objects.requireNonNull(parentApplicationContext, "ApplicationContext can't be null"); Objects.requireNonNull(pluginManager, "PluginManager can't be null"); - this.applicationContext = (GenericApplicationContext)applicationContext; + this.parentApplicationContext = (GenericApplicationContext)parentApplicationContext; this.pluginManager = pluginManager; } @@ -37,24 +38,17 @@ public class DefaultPluginUser implements PluginUser{ */ @Override public T getBean(String name){ - Object bean = applicationContext.getBean(name); - if(bean == null){ - return null; - } - return (T) bean; + return getBean(name, true); } @Override public T getBean(Class aClass) { - return applicationContext.getBean(aClass); + return getBean(aClass, true); } @Override public T getPluginBean(String name) { - if(isPluginBean(name)){ - return getBean(name); - } - return null; + return getBean(name, false); } /** @@ -65,29 +59,12 @@ public class DefaultPluginUser implements PluginUser{ */ @Override public List getBeans(Class aClass){ - Map beansOfTypeMap = applicationContext.getBeansOfType(aClass); - if(beansOfTypeMap == null){ - return Collections.emptyList(); - } - return beansOfTypeMap.values() - .stream() - .filter(beansOfType-> beansOfTypeMap != null) - .collect(Collectors.toList()); + return getBeans(aClass, 3); } @Override public List getMainBeans(Class aClass) { - Map beansOfTypeMap = applicationContext.getBeansOfType(aClass); - if(beansOfTypeMap == null){ - return Collections.emptyList(); - } - List beans = new ArrayList<>(); - beansOfTypeMap.forEach((beanName, bean)->{ - if(!isPluginBean(beanName)){ - beans.add(bean); - } - }); - return beans; + return getBeans(aClass, 1); } /** @@ -98,32 +75,17 @@ public class DefaultPluginUser implements PluginUser{ */ @Override public List getPluginBeans(Class aClass) { - Map beansOfTypeMap = applicationContext.getBeansOfType(aClass); - if(beansOfTypeMap == null){ - return Collections.emptyList(); - } - List beans = new ArrayList<>(); - beansOfTypeMap.forEach((beanName, bean)->{ - if(isPluginBean(beanName)){ - beans.add(bean); - } - }); - return beans; + return getBeans(aClass, 2); } @Override public List getPluginBeans(String pluginId, Class aClass) { - Map beansOfTypeMap = applicationContext.getBeansOfType(aClass); - if(beansOfTypeMap == null){ + GenericApplicationContext pluginApplicationContext = + PluginInfoContainers.getPluginApplicationContext(pluginId); + if(pluginApplicationContext == null){ return Collections.emptyList(); } - List beans = new ArrayList<>(); - beansOfTypeMap.forEach((beanName, bean)->{ - if(PluginInfoContainer.existRegisterBeanName(pluginId, beanName)){ - beans.add(bean); - } - }); - return beans; + return PluginBeanUtils.getPluginBeans(pluginApplicationContext, aClass); } @Override @@ -131,13 +93,21 @@ public class DefaultPluginUser implements PluginUser{ if(object == null){ return null; } - try { - Object newObject = applicationContext.getDefaultListableBeanFactory() - .createBean(object.getClass()); - return (T) newObject; - } catch (Exception e) { - throw new RuntimeException(e); + List pluginApplicationContexts = PluginInfoContainers.getPluginApplicationContexts(); + pluginApplicationContexts.add(parentApplicationContext); + Class aClass = object.getClass(); + for (GenericApplicationContext pluginApplicationContext : pluginApplicationContexts) { + try { + // 判断是否存在 + pluginApplicationContext.getBean(aClass); + Object newBean = pluginApplicationContext.getBeanFactory() + .createBean(aClass); + return (T) newBean; + } catch (Exception e){ + // 忽略 + } } + return null; } @@ -152,16 +122,67 @@ public class DefaultPluginUser implements PluginUser{ return pluginManager.getExtensions(tClass); } + + private T getBean(String name, boolean haveParent){ + List pluginApplicationContexts = PluginInfoContainers.getPluginApplicationContexts(); + if(haveParent){ + pluginApplicationContexts.add(parentApplicationContext); + } + for (GenericApplicationContext pluginApplicationContext : pluginApplicationContexts) { + if(pluginApplicationContext.containsBean(name)){ + return (T) pluginApplicationContext.getBean(name); + } + } + return null; + } + + private T getBean(Class aClass, boolean haveParent) { + List pluginApplicationContexts = PluginInfoContainers.getPluginApplicationContexts(); + if(haveParent){ + pluginApplicationContexts.add(parentApplicationContext); + } + for (GenericApplicationContext pluginApplicationContext : pluginApplicationContexts) { + try { + T bean = pluginApplicationContext.getBean(aClass); + if(bean != null){ + return bean; + } + } catch (Exception e){ + // 忽略 + } + } + return null; + } + /** - * 是否是插件中的bean - * @param beanName bean名称 - * @return boolean + * 获取多个bean. + * @param aClass 接口或者抽象类类类型 + * @param type 1 获取主程序的, 2 获取插件中的, 3 获取所有的 + * @param 类类型 + * @return List */ - protected boolean isPluginBean(String beanName){ - if(beanName == null){ - return false; + private List getBeans(Class aClass, int type) { + List pluginApplicationContexts = new ArrayList<>(1); + + if(type == 1){ + pluginApplicationContexts.add(parentApplicationContext); + } else if(type == 2){ + pluginApplicationContexts.addAll(PluginInfoContainers.getPluginApplicationContexts()); + } else if(type == 3){ + pluginApplicationContexts.add(parentApplicationContext); + pluginApplicationContexts.addAll(PluginInfoContainers.getPluginApplicationContexts()); + } else { + return Collections.emptyList(); + } + + List result = new ArrayList<>(); + for (GenericApplicationContext pluginApplicationContext : pluginApplicationContexts) { + List pluginBeans = PluginBeanUtils.getPluginBeans(pluginApplicationContext, aClass); + if(!pluginBeans.isEmpty()){ + result.addAll(pluginBeans); + } } - return PluginInfoContainer.existRegisterBeanName(beanName); + return result; } } diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/user/PluginUser.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/user/PluginUser.java index 1eb2e64349b9c351e7b825b17e8fe3944e89c1d6..8adc50f0f86b4dc2138712616cc0bb0a65f2daa7 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/user/PluginUser.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/user/PluginUser.java @@ -94,9 +94,11 @@ public interface PluginUser { * @param 实例泛型 * @return 新实例对象 */ + @Deprecated T generateNewInstance(T object); + /** * 使用场景: * 1. 在主程序定义接口(该接口需要继承 ExtensionPoint 接口)。 diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/realize/PluginUtils.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/realize/PluginUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..c2970b9cb8624c704c7356919c0fd3d6d52886c5 --- /dev/null +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/realize/PluginUtils.java @@ -0,0 +1,89 @@ +package com.gitee.starblues.realize; + +import com.gitee.starblues.integration.operator.module.PluginInfo; +import com.gitee.starblues.utils.PluginBeanUtils; +import org.pf4j.PluginDescriptor; +import org.pf4j.PluginWrapper; +import org.springframework.context.ApplicationContext; + +import java.util.List; + +/** + * 插件工具类 + * @author starBlues + * @version 1.0 + */ +public class PluginUtils { + + protected final ApplicationContext parentApplicationContext; + protected final ApplicationContext pluginApplicationContext; + protected final PluginDescriptor pluginDescriptor; + + public PluginUtils(ApplicationContext parentApplicationContext, + ApplicationContext pluginApplicationContext, + PluginDescriptor pluginDescriptor) { + this.parentApplicationContext = parentApplicationContext; + this.pluginApplicationContext = pluginApplicationContext; + this.pluginDescriptor = pluginDescriptor; + } + + /** + * 获取主程序的 ApplicationContext + * @return ApplicationContext + */ + public ApplicationContext getMainApplicationContext() { + return parentApplicationContext; + } + + /** + * 获取当前插件的 ApplicationContext + * @return ApplicationContext + */ + public ApplicationContext getPluginApplicationContext() { + return pluginApplicationContext; + } + + /** + * 获取当前插件的描述信息 + * @return PluginDescriptor + */ + public PluginDescriptor getPluginDescriptor(){ + return pluginDescriptor; + } + + + /** + * 获取bean名称得到主程序中的bean + * @param name bean 名称 + * @param bean 类型 + * @return bean + */ + public T getMainBean(String name){ + Object bean = parentApplicationContext.getBean(name); + if(bean == null){ + return null; + } + return (T) bean; + } + + /** + * 通过bean类型得到主程序中的bean + * @param aClass bean 类型 + * @param bean 类型 + * @return bean + */ + public T getMainBean(Class aClass) { + return parentApplicationContext.getBean(aClass); + } + + /** + * 通过接口或者抽象类型得到主程序中的多个实现类型 + * @param aClass bean 类型 + * @param bean 类型 + * @return bean + */ + public List getMainBeans(Class aClass){ + return PluginBeanUtils.getPluginBeans(parentApplicationContext, aClass); + } + +} diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/utils/AopUtils.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/utils/AopUtils.java index 3269add45bd54c51a21ee603895e0bb44e57a367..bd5774b62c929cf2d87d98bf752228754316176d 100644 --- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/utils/AopUtils.java +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/utils/AopUtils.java @@ -20,6 +20,7 @@ import java.util.concurrent.atomic.AtomicBoolean; * @author starBlues * @version 1.0 */ +@Deprecated public class AopUtils { private static final Logger LOG = LoggerFactory.getLogger(AopUtils.class); diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/utils/PluginBeanUtils.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/utils/PluginBeanUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..4dca9389d886b3df797dad8a9ae785728813ff46 --- /dev/null +++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/utils/PluginBeanUtils.java @@ -0,0 +1,43 @@ +package com.gitee.starblues.utils; + +import org.springframework.context.ApplicationContext; +import org.springframework.util.ClassUtils; + +import java.util.*; + +/** + * 插件bean工具类 + * @author starBlues + * @version 1.0 + */ +public class PluginBeanUtils { + + public static List getPluginBeans(ApplicationContext applicationContext, Class aClass) { + Map beansOfTypeMap = applicationContext.getBeansOfType(aClass); + if(beansOfTypeMap.isEmpty()){ + return Collections.emptyList(); + } + return new ArrayList<>(beansOfTypeMap.values()); + } + + /** + * 得到某个接口的实现对象 + * @param sourceObject 遍历的对象 + * @param interfaceClass 接口类类型 + * @return Object + */ + public static T getObjectByInterfaceClass(Set sourceObject, Class interfaceClass){ + if(sourceObject == null || sourceObject.isEmpty()){ + return null; + } + for (Object configSingletonObject : sourceObject) { + Set> allInterfacesForClassAsSet = ClassUtils + .getAllInterfacesAsSet(configSingletonObject); + if(allInterfacesForClassAsSet.contains(interfaceClass)){ + return (T) configSingletonObject; + } + } + return null; + } + +}