diff --git a/example/basic-example/basic-example-main/pom.xml b/example/basic-example/basic-example-main/pom.xml
index 8ae868c38239e3b2d04c92059b7ece5c03553082..82b23e6cfde3109ee8ccec33ac89350897f339dd 100644
--- a/example/basic-example/basic-example-main/pom.xml
+++ b/example/basic-example/basic-example-main/pom.xml
@@ -13,13 +13,14 @@
 
     com.gitee.starblues
     basic-example-main
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     jar
 
     
         2.7.0
+        2.3.2
         1.6
-        2.2.2-RELEASE
+        2.2.3-RELEASE
     
 
     
@@ -39,6 +40,12 @@
             spring-boot-starter-web
         
 
+        
+            org.quartz-scheduler
+            quartz
+            ${quartz.version}
+        
+
 
         
             io.springfox
diff --git a/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/config/CommonBeanConfig.java b/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/config/CommonBeanConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..767b47f1bbfc422ceab2f091ac073c7a12a35d7c
--- /dev/null
+++ b/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/config/CommonBeanConfig.java
@@ -0,0 +1,22 @@
+package com.basic.example.main.config;
+
+import org.quartz.SchedulerFactory;
+import org.quartz.impl.StdSchedulerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 公用bean的配置
+ *
+ * @author zhangzhuo
+ * @version 1.0
+ */
+@Configuration
+public class CommonBeanConfig {
+
+    @Bean
+    public SchedulerFactory schedulerFactory(){
+        return new StdSchedulerFactory();
+    }
+
+}
diff --git a/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/config/PluginBeanConfig.java b/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/config/PluginBeanConfig.java
index ab802c0cb7286e1133cb5efcd7f1e2072365e925..343c9b359630688fcf54920ac3461d649db32146 100644
--- a/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/config/PluginBeanConfig.java
+++ b/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/config/PluginBeanConfig.java
@@ -1,8 +1,10 @@
 package com.basic.example.main.config;
 
+import com.basic.example.main.quartz.QuartzJobManager;
 import com.gitee.starblues.integration.application.DefaultPluginApplication;
 import com.gitee.starblues.integration.application.PluginApplication;
 import com.gitee.starblues.integration.application.AutoPluginApplication;
+import org.quartz.SchedulerFactory;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -22,7 +24,8 @@ public class PluginBeanConfig {
      * @return PluginApplication
      */
     @Bean
-    public PluginApplication pluginApplication(PluginListener pluginListener){
+    public PluginApplication pluginApplication(PluginListener pluginListener,
+                                               SchedulerFactory schedulerFactory){
         AutoPluginApplication autoPluginApplication = new AutoPluginApplication();
         autoPluginApplication.setPluginInitializerListener(pluginListener);
         autoPluginApplication.addListener(ExamplePluginListener.class);
diff --git a/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/quartz/QuartzJob.java b/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/quartz/QuartzJob.java
new file mode 100644
index 0000000000000000000000000000000000000000..6b6168414dda14f057cbfae812a0adf1c3bae1c7
--- /dev/null
+++ b/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/quartz/QuartzJob.java
@@ -0,0 +1,63 @@
+package com.basic.example.main.quartz;
+
+import org.quartz.Job;
+
+import java.util.Map;
+
+/**
+ * Quartz框架job定义的统一接口
+ *
+ * @author zhangzhuo
+ * @version 1.0
+ */
+public interface QuartzJob {
+
+    /**
+     * 是否启用
+     * @return true 启用。false 禁用
+     */
+    boolean enable();
+
+
+    /**
+     * job 名称
+     * @return String
+     */
+    String jobName();
+
+    /**
+     * 触发器名称
+     * @return String
+     */
+    String triggerName();
+
+    /**
+     * cron 表达式
+     * @return  cron 表达式
+     */
+    String cron();
+
+    /**
+     * 延迟执行秒数
+     * @return 秒数
+     */
+    int delaySeconds();
+
+
+    /**
+     * job 执行类型
+     * @return Job 实现类
+     */
+    Class extends Job>jobClass();
+
+
+    /**
+     * 传入到job中的数据
+     * @return Map
+     */
+    Map jobData();
+
+
+
+
+}
diff --git a/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/quartz/QuartzJobManager.java b/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/quartz/QuartzJobManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..30ef1a868cd3bfaab801b4e900f7bfccf6e89b4b
--- /dev/null
+++ b/example/basic-example/basic-example-main/src/main/java/com/basic/example/main/quartz/QuartzJobManager.java
@@ -0,0 +1,155 @@
+package com.basic.example.main.quartz;
+
+import com.gitee.starblues.integration.application.PluginApplication;
+import com.gitee.starblues.integration.listener.PluginListener;
+import org.quartz.*;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.*;
+
+/**
+ * QuartzJob 管理器
+ *
+ * @author zhangzhuo
+ * @version 1.0
+ */
+public class QuartzJobManager implements PluginListener {
+
+    private final static String TRIGGER_GROUP = "QuartzTriggerGroup";
+    private final static String JOB_GROUP = "QuartzJobGroup";
+
+
+    private final Scheduler scheduler;
+    private final PluginApplication pluginApplication;
+
+    /**
+     * 缓存启动的job. 用于停止时使用
+     */
+    private final Map> startJobMap = new HashMap<>();
+
+
+    public QuartzJobManager(SchedulerFactory schedulerFactory,
+                            PluginApplication pluginApplication) throws SchedulerException {
+        this.scheduler = schedulerFactory.getScheduler();
+        this.pluginApplication = pluginApplication;
+    }
+
+
+    @Override
+    public void registry(String pluginId) {
+        List quartzJobs = pluginApplication.getPluginUser().getPluginBeans(pluginId, QuartzJob.class);
+        if(quartzJobs == null || quartzJobs.isEmpty()){
+            return;
+        }
+        for (QuartzJob quartzJob : quartzJobs) {
+            try {
+                if(startJob(quartzJob)){
+                    List quartzJobsList = startJobMap.get(pluginId);
+                    if(quartzJobsList == null){
+                        quartzJobsList = new ArrayList<>();
+                        startJobMap.put(pluginId, quartzJobsList);
+                    }
+                    quartzJobsList.add(quartzJob);
+                }
+            } catch (SchedulerException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @Override
+    public void unRegistry(String pluginId) {
+        List quartzJobs = startJobMap.remove(pluginId);
+        if(quartzJobs == null){
+            return;
+        }
+        for (QuartzJob quartzJob : quartzJobs) {
+            try {
+                stopJob(quartzJob);
+            } catch (SchedulerException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @Override
+    public void failure(String pluginId, Throwable throwable) {
+
+    }
+
+    /**
+     * 启动job
+     * @param quartzJob job接口
+     */
+    private boolean startJob(QuartzJob quartzJob) throws SchedulerException {
+        if(quartzJob == null){
+            return false;
+        }
+        if(!quartzJob.enable()){
+            // 不启用
+            return false;
+        }
+        JobBuilder jobBuilder = JobBuilder.newJob(quartzJob.jobClass())
+                .withIdentity(quartzJob.jobName(), JOB_GROUP);
+        Map jobData = quartzJob.jobData();
+        if(jobData != null){
+            jobBuilder.setJobData(new JobDataMap(jobData));
+        }
+        JobDetail jobDetail = jobBuilder.build();
+        Trigger trigger = configTrigger(quartzJob);
+        scheduler.scheduleJob(jobDetail, trigger);
+        synchronized (scheduler) {
+            if (!scheduler.isStarted()) {
+                scheduler.start();
+            }
+        }
+        return true;
+    }
+
+
+    /**
+     * 停止job
+     * @param quartzJob job接口
+     */
+    private void stopJob(QuartzJob quartzJob) throws SchedulerException {
+
+        String jobName = quartzJob.jobName();
+        String triggerName = quartzJob.triggerName();
+
+        // 停止触发器
+        scheduler.pauseTrigger(TriggerKey.triggerKey(triggerName, TRIGGER_GROUP));
+        // 停止任务
+        scheduler.pauseJob(JobKey.jobKey(jobName, JOB_GROUP));
+
+        // 停止该触发器的任务
+        scheduler.unscheduleJob(TriggerKey.triggerKey(triggerName, TRIGGER_GROUP));
+        // 删除任务
+        scheduler.deleteJob(JobKey.jobKey(jobName, JOB_GROUP));
+    }
+
+
+    /**
+     * 配置触发器
+     * @param quartzJob quartzJob
+     * @return 触发器
+     */
+    private Trigger configTrigger(QuartzJob quartzJob) {
+        //0 56 09 ? * *
+        TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger()
+                .withIdentity(quartzJob.triggerName(), TRIGGER_GROUP)
+                .withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.cron()));
+
+        int delaySeconds = quartzJob.delaySeconds();
+        if(delaySeconds <= 0L){
+            triggerBuilder.startNow();
+        } else {
+            LocalDateTime localDateTime = LocalDateTime.now();
+            localDateTime = localDateTime.plusSeconds(60);
+            Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
+            triggerBuilder.startAt(date);
+        }
+        return triggerBuilder.build();
+    }
+
+}
diff --git a/example/basic-example/basic-example-runner/pom.xml b/example/basic-example/basic-example-runner/pom.xml
index f15d476ab480918678ad5df34da2d6ba7a9c5d4d..2e56acf0f248507e1d7c0b0b8656a6bf36d8bf01 100644
--- a/example/basic-example/basic-example-runner/pom.xml
+++ b/example/basic-example/basic-example-runner/pom.xml
@@ -14,7 +14,7 @@
 
     com.gitee.starblues
     basic-example-runner
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     pom
 
     
diff --git a/example/basic-example/package.bat b/example/basic-example/package.bat
index 4be1bfecf79c9452da119af364a8923038c9f00e..1d57fb28b1b9561db343a69d7f6eab46005c8b6f 100644
--- a/example/basic-example/package.bat
+++ b/example/basic-example/package.bat
@@ -27,4 +27,3 @@ cd dist
 REM run main
 rename basic-example-main-*-exec.jar basic-example-start.jar
 rename application-prod.yml application.yml
-java -jar basic-example-start.jar --spring.config.location=application.yml
\ No newline at end of file
diff --git a/example/basic-example/plugins/basic-example-plugin1/plugin.properties b/example/basic-example/plugins/basic-example-plugin1/plugin.properties
index a62fec6bce54866ef729418a5d44723e622e7348..ee944499c1c602459cb21019164fb239dc639d74 100644
--- a/example/basic-example/plugins/basic-example-plugin1/plugin.properties
+++ b/example/basic-example/plugins/basic-example-plugin1/plugin.properties
@@ -1,4 +1,4 @@
 plugin.id=basic-example-plugin1
 plugin.class=com.basic.example.plugin1.DefinePlugin
-plugin.version=2.2.2-RELEASE
+plugin.version=2.2.3-RELEASE
 plugin.provider=StarBlues
\ No newline at end of file
diff --git a/example/basic-example/plugins/basic-example-plugin1/pom.xml b/example/basic-example/plugins/basic-example-plugin1/pom.xml
index d5024f7c155da49415650b63efce368bff6c87de..9fe66f330d924a5acda1ae14f242881713c70951 100644
--- a/example/basic-example/plugins/basic-example-plugin1/pom.xml
+++ b/example/basic-example/plugins/basic-example-plugin1/pom.xml
@@ -8,12 +8,12 @@
     
         com.gitee.starblues
         basic-example-plugin-parent
-        2.2.2-RELEASE
+        2.2.3-RELEASE
         ../pom.xml
     
 
     basic-example-plugin1
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     jar
 
     
diff --git a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/config/PluginConfig1.java b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/config/PluginConfig1.java
index bd964e31e6f1848130b2a33969ae38b9f9cd48fe..efd5be3326fb7c09fbf4fa836943398502aa2beb 100644
--- a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/config/PluginConfig1.java
+++ b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/config/PluginConfig1.java
@@ -16,6 +16,8 @@ public class PluginConfig1 {
 
     private String name;
     private String plugin;
+    private Boolean jobEnable;
+    private String jobCron;
     private Set setString;
     private List listInteger;
 
@@ -25,7 +27,6 @@ public class PluginConfig1 {
 
 
 
-
     public String getName() {
         return name;
     }
@@ -42,6 +43,22 @@ public class PluginConfig1 {
         this.plugin = plugin;
     }
 
+    public Boolean getJobEnable() {
+        return jobEnable;
+    }
+
+    public void setJobEnable(Boolean jobEnable) {
+        this.jobEnable = jobEnable;
+    }
+
+    public String getJobCron() {
+        return jobCron;
+    }
+
+    public void setJobCron(String jobCron) {
+        this.jobCron = jobCron;
+    }
+
     public Set getSetString() {
         return setString;
     }
@@ -76,13 +93,17 @@ public class PluginConfig1 {
 
     @Override
     public String toString() {
-        return "BasePluginExtension{" +
+        return "PluginConfig1{" +
                 "name='" + name + '\'' +
                 ", plugin='" + plugin + '\'' +
+                ", jobEnable=" + jobEnable +
+                ", jobCron='" + jobCron + '\'' +
                 ", setString=" + setString +
                 ", listInteger=" + listInteger +
                 ", defaultValue='" + defaultValue + '\'' +
+                ", subConfig=" + subConfig +
                 '}';
     }
 
+
 }
diff --git a/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/job/Plugin1QuartzJob.java b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/job/Plugin1QuartzJob.java
new file mode 100644
index 0000000000000000000000000000000000000000..d0781ed3de026418b2d653bfe347990cf4e297a9
--- /dev/null
+++ b/example/basic-example/plugins/basic-example-plugin1/src/main/java/com/basic/example/plugin1/job/Plugin1QuartzJob.java
@@ -0,0 +1,84 @@
+package com.basic.example.plugin1.job;
+
+import com.basic.example.main.quartz.QuartzJob;
+import com.basic.example.plugin1.config.PluginConfig1;
+import org.quartz.Job;
+import org.quartz.JobDataMap;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 插件1 job
+ *
+ * @author zhangzhuo
+ * @version 1.0
+ */
+@Component
+public class Plugin1QuartzJob implements QuartzJob {
+
+
+
+    private static final String JOB_NAME = "plugin-job";
+    private static final String TRIGGER_NAME = "plugin-trigger";
+
+    private final PluginConfig1 pluginConfig1;
+
+    public Plugin1QuartzJob(PluginConfig1 pluginConfig1) {
+        this.pluginConfig1 = pluginConfig1;
+    }
+
+
+    @Override
+    public boolean enable() {
+        return pluginConfig1.getJobEnable();
+    }
+
+    @Override
+    public String jobName() {
+        return JOB_NAME;
+    }
+
+    @Override
+    public String triggerName() {
+        return TRIGGER_NAME;
+    }
+
+    @Override
+    public String cron() {
+        return pluginConfig1.getJobCron();
+    }
+
+    @Override
+    public int delaySeconds() {
+        return 0;
+    }
+
+    @Override
+    public Class extends Job> jobClass() {
+        return JobImpl.class;
+    }
+
+    @Override
+    public Map jobData() {
+        Map jobData = new HashMap<>();
+        jobData.put(JOB_NAME, JOB_NAME);
+        return jobData;
+    }
+
+
+
+    public static class JobImpl implements Job{
+
+        @Override
+        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+            JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
+            String string = jobDataMap.getString(JOB_NAME);
+            System.out.println("plugin1 job start = " + string);
+        }
+    }
+
+}
diff --git a/example/basic-example/plugins/basic-example-plugin1/src/main/resources/plugin1.yml b/example/basic-example/plugins/basic-example-plugin1/src/main/resources/plugin1.yml
index 9da193a84a728ec17030975a049139aa4f1576c9..8f851e47c57ba12abea6150ea94ae7dea62c7eca 100644
--- a/example/basic-example/plugins/basic-example-plugin1/src/main/resources/plugin1.yml
+++ b/example/basic-example/plugins/basic-example-plugin1/src/main/resources/plugin1.yml
@@ -1,5 +1,7 @@
 name: plugin1
 plugin: examplePlugin1
+jobEnable: true
+jobCron: "*/5 * * * * ?"
 setString:
   - set1
   - set2
diff --git a/example/basic-example/plugins/basic-example-plugin2/plugin.properties b/example/basic-example/plugins/basic-example-plugin2/plugin.properties
index b1bef3ebfe73bfea4f73fd5fc6636825a2bae08d..00c6e52ff75cdb39fb4ac5cce736dcb23524b949 100644
--- a/example/basic-example/plugins/basic-example-plugin2/plugin.properties
+++ b/example/basic-example/plugins/basic-example-plugin2/plugin.properties
@@ -1,4 +1,4 @@
 plugin.id=basic-example-plugin2
 plugin.class=com.basic.example.plugin2.DefinePlugin
-plugin.version=2.2.2-RELEASE
+plugin.version=2.2.3-RELEASE
 plugin.provider=StarBlues
\ No newline at end of file
diff --git a/example/basic-example/plugins/basic-example-plugin2/pom.xml b/example/basic-example/plugins/basic-example-plugin2/pom.xml
index 530c2eb2116bfa6b11a8bf45f33890a99ecd285b..599b3c71fc004347ee1b34f8df98f99bc2c9a8d9 100644
--- a/example/basic-example/plugins/basic-example-plugin2/pom.xml
+++ b/example/basic-example/plugins/basic-example-plugin2/pom.xml
@@ -8,12 +8,12 @@
     
         com.gitee.starblues
         basic-example-plugin-parent
-        2.2.2-RELEASE
+        2.2.3-RELEASE
         ../pom.xml
     
 
     basic-example-plugin2
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     jar
 
     
diff --git a/example/basic-example/plugins/pom.xml b/example/basic-example/plugins/pom.xml
index bb9d2b37b68c11675ced4f457ce7cfbe625f37ac..533e70ff790ff9b1d8da0a514a0170537b570f31 100644
--- a/example/basic-example/plugins/pom.xml
+++ b/example/basic-example/plugins/pom.xml
@@ -7,7 +7,7 @@
 
     com.gitee.starblues
     basic-example-plugin-parent
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     pom
 
     
diff --git a/example/basic-example/pom.xml b/example/basic-example/pom.xml
index 39c94007f24198423216fb8f146f18d0a483d766..bc91e56feb3032687e238199328dd5980a9125d2 100644
--- a/example/basic-example/pom.xml
+++ b/example/basic-example/pom.xml
@@ -6,7 +6,7 @@
 
     com.gitee.starblues
     basic-example
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     pom
     基本案例
 
diff --git a/example/integration-mybatis/integration-mybatis-main/pom.xml b/example/integration-mybatis/integration-mybatis-main/pom.xml
index f74887412a674cf80e79cb8295a9e99c5fdc5a63..f601315e4a7320d126dd0c882efa5617a6a54e3f 100644
--- a/example/integration-mybatis/integration-mybatis-main/pom.xml
+++ b/example/integration-mybatis/integration-mybatis-main/pom.xml
@@ -14,14 +14,14 @@
 
     com.gitee.starblues
     integration-mybatis-main
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     jar
     主程序模块
 
     
-        2.2.2-RELEASE
-        2.2.2-RELEASE
-        2.2.2-RELEASE
+        2.2.3-RELEASE
+        2.2.3-RELEASE
+        2.2.3-RELEASE
         2.0.1
         2.7.0
         1.6
diff --git a/example/integration-mybatis/integration-mybatis-main/src/main/java/com/mybatis/main/rest/PluginResource.java b/example/integration-mybatis/integration-mybatis-main/src/main/java/com/mybatis/main/rest/PluginResource.java
index b31c699f713c1bbde6f1911e484191937305523e..9e93fd511a59eb9d7abcedf0bcaeeb0af15fd259 100644
--- a/example/integration-mybatis/integration-mybatis-main/src/main/java/com/mybatis/main/rest/PluginResource.java
+++ b/example/integration-mybatis/integration-mybatis-main/src/main/java/com/mybatis/main/rest/PluginResource.java
@@ -103,9 +103,13 @@ public class PluginResource {
      * @return 返回操作结果
      */
     @PostMapping("/uninstall/{id}")
-    public String uninstall(@PathVariable("id") String id){
+    public String uninstall(@PathVariable("id") String id,
+                            @RequestParam(value = "isBack", required = false) Boolean isBack){
         try {
-            if(pluginOperator.uninstall(id, true)){
+            if(isBack == null){
+                isBack = true;
+            }
+            if(pluginOperator.uninstall(id, isBack)){
                 return "plugin '" + id +"' uninstall success";
             } else {
                 return "plugin '" + id +"' uninstall failure";
diff --git a/example/integration-mybatis/integration-mybatis-plugin-parent/pom.xml b/example/integration-mybatis/integration-mybatis-plugin-parent/pom.xml
index 269bb1fb804874b557d8b88213625700ca59479b..cbb086511576d169d882bca99abfee58e3f73a8e 100644
--- a/example/integration-mybatis/integration-mybatis-plugin-parent/pom.xml
+++ b/example/integration-mybatis/integration-mybatis-plugin-parent/pom.xml
@@ -7,7 +7,7 @@
 
     com.gitee.starblues
     integration-mybatis-plugin-parent
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     pom
 
     
diff --git a/example/integration-mybatis/integration-mybatis-runner/pom.xml b/example/integration-mybatis/integration-mybatis-runner/pom.xml
index afa68f0867134a78bd02fe6a8b3aaf652dfa2a42..a10c71ae6704d97806486a9a638034ca1f9a3e7d 100644
--- a/example/integration-mybatis/integration-mybatis-runner/pom.xml
+++ b/example/integration-mybatis/integration-mybatis-runner/pom.xml
@@ -14,7 +14,7 @@
 
     com.gitee.starblues
     integration-mybatis-runner
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     jar
     启动程序模块。将启动类配置到该模块下
 
diff --git a/example/integration-mybatis/plugins/integration-mybatis-plugin1/plugin.properties b/example/integration-mybatis/plugins/integration-mybatis-plugin1/plugin.properties
index 086145a78b317607b74ce5a14fea7a831d218022..4ff6f8fcfbcee627f443207c468ccc63719ca6c6 100644
--- a/example/integration-mybatis/plugins/integration-mybatis-plugin1/plugin.properties
+++ b/example/integration-mybatis/plugins/integration-mybatis-plugin1/plugin.properties
@@ -1,4 +1,4 @@
 plugin.id=integration-mybatis-plugin1
 plugin.class=com.mybatis.plugin1.ExamplePlugin1
-plugin.version=2.2.2-RELEASE
+plugin.version=2.2.3-RELEASE
 plugin.provider=StarBlues
\ No newline at end of file
diff --git a/example/integration-mybatis/plugins/integration-mybatis-plugin1/pom.xml b/example/integration-mybatis/plugins/integration-mybatis-plugin1/pom.xml
index 51ed59e0cf99fcf6177c82646e1feb3be4217958..d509a5cb609708f60f9bf624c31fb7077bb1a235 100644
--- a/example/integration-mybatis/plugins/integration-mybatis-plugin1/pom.xml
+++ b/example/integration-mybatis/plugins/integration-mybatis-plugin1/pom.xml
@@ -8,12 +8,12 @@
     
         com.gitee.starblues
         integration-mybatis-plugin-parent
-        2.2.2-RELEASE
+        2.2.3-RELEASE
         ../../integration-mybatis-plugin-parent/pom.xml
     
 
     integration-mybatis-plugin1
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     jar
 
     
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 35e12e413dc40a8983326076bf695a0c6a6a7fe9..2878eeeed0c4264015862502cfdb6a2a17b9f560 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
@@ -4,11 +4,9 @@ import com.mybatis.main.entity.User;
 import com.mybatis.main.mapper.UserMapper;
 import com.mybatis.main.service.TestTestTransactional;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.List;
 
 /**
@@ -40,9 +38,6 @@ public class UserController {
         return userMapper.getById(id);
     }
 
-
-
-
     @GetMapping("/transactional")
     public void testTestTransactional(){
         testTestTransactional.transactional();
diff --git a/example/integration-mybatis/plugins/integration-mybatis-plugin2/plugin.properties b/example/integration-mybatis/plugins/integration-mybatis-plugin2/plugin.properties
index ae4c430545b6a0171047a0ade978bcc6ce9ac4c5..9fc286a24fbc02f67996a0ee7f3ab95f92fcea26 100644
--- a/example/integration-mybatis/plugins/integration-mybatis-plugin2/plugin.properties
+++ b/example/integration-mybatis/plugins/integration-mybatis-plugin2/plugin.properties
@@ -1,4 +1,4 @@
 plugin.id=integration-mybatis-plugin2
 plugin.class=com.mybatis.plugin2.ExamplePlugin2
-plugin.version=2.2.2-RELEASE
+plugin.version=2.2.3-RELEASE
 plugin.provider=StarBlues
\ No newline at end of file
diff --git a/example/integration-mybatis/plugins/integration-mybatis-plugin2/pom.xml b/example/integration-mybatis/plugins/integration-mybatis-plugin2/pom.xml
index d4580c8c4cd375d37f62bbc5f1bd52ac1ed24f34..7fa63280ac1f35a507358891b5bcf3dee92ee328 100644
--- a/example/integration-mybatis/plugins/integration-mybatis-plugin2/pom.xml
+++ b/example/integration-mybatis/plugins/integration-mybatis-plugin2/pom.xml
@@ -8,12 +8,12 @@
     
         com.gitee.starblues
         integration-mybatis-plugin-parent
-        2.2.2-RELEASE
+        2.2.3-RELEASE
         ../../integration-mybatis-plugin-parent/pom.xml
     
 
     integration-mybatis-plugin2
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     jar
 
     
diff --git a/example/integration-mybatis/pom.xml b/example/integration-mybatis/pom.xml
index 4f25fa28917037e7e4b83a39493b67ff039a3404..3faec6d6d397a871128620d9caabc9c0197ad483 100644
--- a/example/integration-mybatis/pom.xml
+++ b/example/integration-mybatis/pom.xml
@@ -7,7 +7,7 @@
 
     com.gitee.starblues
     integration-mybatis
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     pom
     集成mybatis案例
 
diff --git a/example/integration-mybatisplus/integration-mybatisplus-main/pom.xml b/example/integration-mybatisplus/integration-mybatisplus-main/pom.xml
index 5868bc659c8e31467ac8e8b3a258570106d1e687..b6184620d1d65a16435ceb06e73bef3a392d9924 100644
--- a/example/integration-mybatisplus/integration-mybatisplus-main/pom.xml
+++ b/example/integration-mybatisplus/integration-mybatisplus-main/pom.xml
@@ -13,7 +13,7 @@
 
 
     com.gitee.starblues
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     integration-mybatisplus-main
     jar
     集成mybatis-plus 案例--主程序
@@ -27,8 +27,8 @@
         2.0.1
         3.2.0
 
-        2.2.2-RELEASE
-        2.2.2-RELEASE
+        2.2.3-RELEASE
+        2.2.3-RELEASE
         2.7.0
         1.6
     
diff --git a/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/plugin.properties b/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/plugin.properties
index 88aa9fe6e1e1ade077e5adad241f48362834caa8..6bff82a262aaf37ac365ac7fa04b95513e36acb0 100644
--- a/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/plugin.properties
+++ b/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/plugin.properties
@@ -1,4 +1,4 @@
 plugin.id=integration-mybatisplus-plugin
 plugin.class=com.mybatisplus.plugin.MybatisPlusPlugin
-plugin.version=2.2.2-RELEASE
+plugin.version=2.2.3-RELEASE
 plugin.provider=StarBlues
\ No newline at end of file
diff --git a/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/pom.xml b/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/pom.xml
index b8cce26281f2791a04f4e3af8af05e313497727c..76505b078c574ddc6362dce63517eaa7e1270db4 100644
--- a/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/pom.xml
+++ b/example/integration-mybatisplus/plugins/integration-mybatisplus-plugin/pom.xml
@@ -6,7 +6,7 @@
 
     com.gitee.starblues
     integration-mybatisplus-plugin
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     jar
 
     
diff --git a/example/integration-mybatisplus/pom.xml b/example/integration-mybatisplus/pom.xml
index 71cdb2429c3b39ea52886c02518465387507dfc3..75ce9178cda64cf7022f88b10c59109843e544c1 100644
--- a/example/integration-mybatisplus/pom.xml
+++ b/example/integration-mybatisplus/pom.xml
@@ -6,7 +6,7 @@
 
     com.gitee.starblues
     integration-mybatisplus
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     pom
     集成mybatis-plus案例
 
diff --git a/example/pom.xml b/example/pom.xml
index 1cac07c4283e1ee87ed540c95a70baa12aeb07ab..4df045d2fc040ba9a7201046e33832c03880f727 100644
--- a/example/pom.xml
+++ b/example/pom.xml
@@ -6,7 +6,7 @@
 
     com.gitee.starblues
     springboot-plugin-framework-example
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     pom
 
     
diff --git a/pom.xml b/pom.xml
index a03328d3951df541e5a15e79c5b31f850cce2394..44a212a8c6eeb086ed2ced26e2ab3fb2f0f191e6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
     com.gitee.starblues
     springboot-plugin-framework-parent
     pom
-    2.2.2-RELEASE
+    2.2.3-RELEASE
 
     spring boot 插件开发集成包
 
diff --git a/springboot-plugin-framework-extension/pom.xml b/springboot-plugin-framework-extension/pom.xml
index c05a6f640a8c5bc517ae26270f343324f0112657..f418c24b05ba3fe22a9f2b2edd7c587078d25b78 100644
--- a/springboot-plugin-framework-extension/pom.xml
+++ b/springboot-plugin-framework-extension/pom.xml
@@ -9,7 +9,7 @@
     com.gitee.starblues
     springboot-plugin-framework-extension
     pom
-    2.2.2-RELEASE
+    2.2.3-RELEASE
 
     spring boot 插件式开发集成包--扩展模块
     
diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/pom.xml b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/pom.xml
index 49b92e18fca0777ac8defa7ff0c74d0904211ea8..205f27b6254b7943d519b3df6fd22c46f359fa0d 100644
--- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/pom.xml
+++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-mybatis/pom.xml
@@ -13,7 +13,7 @@
 
     com.gitee.starblues
     springboot-plugin-framework-extension-mybatis
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     jar
 
     插件扩展-spring boot mybatis 集成扩展
@@ -64,7 +64,7 @@
         3.1.0
         1.6
 
-        2.2.2-RELEASE
+        2.2.3-RELEASE
         2.0.1
         3.2.0
     
diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/pom.xml b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/pom.xml
index b2c77d02b1b3035dd7189f49f5aa7c400ed04269..ed9286d53521dab6c618edc8ecee51f9f838630f 100644
--- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/pom.xml
+++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/pom.xml
@@ -13,7 +13,7 @@
 
     com.gitee.starblues
     springboot-plugin-framework-extension-resources
-    2.2.2-RELEASE
+    2.2.3-RELEASE
     jar
 
     插件扩展-通过url读取插件中的静态资源
@@ -69,7 +69,7 @@
         5.0.7.RELEASE
         4.0.1
 
-        2.2.2-RELEASE
+        2.2.3-RELEASE
         2.1.1.RELEASE
     
 
diff --git a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/resolver/ResourceWebMvcConfigurer.java b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/resolver/ResourceWebMvcConfigurer.java
index 8c1f91eec52b09b6b197ad95cad8a82f63a9380b..2c07742e8af8b4f7bb49b257b7dc4c0136bcf8fc 100644
--- a/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/resolver/ResourceWebMvcConfigurer.java
+++ b/springboot-plugin-framework-extension/springboot-plugin-framework-extension-resources/src/main/java/com/gitee/starblues/extension/resources/resolver/ResourceWebMvcConfigurer.java
@@ -26,6 +26,8 @@ public class ResourceWebMvcConfigurer implements WebMvcConfigurer {
         CacheControl cacheControl = StaticResourceExtension.getPluginStaticResourcesCacheControl();
         if(cacheControl != null){
             resourceHandlerRegistration.setCacheControl(cacheControl);
+        } else {
+            resourceHandlerRegistration.setCacheControl(CacheControl.noStore());
         }
         resourceHandlerRegistration
                 .resourceChain(false)
diff --git a/springboot-plugin-framework/pom.xml b/springboot-plugin-framework/pom.xml
index 4d2d893d062ddc783448aa536e9f87bdfd6c6d57..6269ed48717dc4d19c79c5bdbf28417c1ec9d7c2 100644
--- a/springboot-plugin-framework/pom.xml
+++ b/springboot-plugin-framework/pom.xml
@@ -13,7 +13,7 @@
     com.gitee.starblues
     springboot-plugin-framework
     jar
-    2.2.2-RELEASE
+    2.2.3-RELEASE
 
     spring boot 插件式开发集成包
 
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 781bf32e0d738c64028efd23f59cc3bfa6fc04a3..730709564131487e83345166f147316d2dbd9dfd 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
@@ -25,13 +25,15 @@ public abstract class AbstractExtension {
     }
 
     /**
-     * 扩展key
+     * 扩展唯一的key
      * @return String
      */
     public abstract String key();
 
     /**
      * 该扩展初始化的操作
+     * 主要是在插件初始化阶段被调用
+     * @param applicationContext applicationContext
      * @throws Exception 初始化异常
      */
     public void initialize(ApplicationContext applicationContext) throws Exception{
@@ -39,7 +41,8 @@ public abstract class AbstractExtension {
 
 
     /**
-     * 得到插件的资源加载者
+     * 返回插件的资源加载者。
+     * 主要是加载插件中的某些资源,比如文件、图片等。
      * @return List PluginResourceLoader
      */
     public List getPluginResourceLoader(){
@@ -47,7 +50,8 @@ public abstract class AbstractExtension {
     }
 
     /**
-     * 得到扩展的插件中的类分组器
+     * 返回扩展的插件中的类分组器。
+     * 该扩展主要是对插件中的Class文件分组,然后供 PluginPipeProcessor、PluginPostProcessor 阶段使用。
      * @param applicationContext 主程序ApplicationContext
      * @return List PluginPipeProcessorExtend
      */
@@ -57,7 +61,8 @@ public abstract class AbstractExtension {
 
 
     /**
-     * 得到扩展的流插件处理者
+     * 返回扩展的流插件处理者。
+     * 该扩展主要是对每一个插件进行处理
      * @param applicationContext 主程序ApplicationContext
      * @return List PluginPipeProcessorExtend
      */
@@ -66,7 +71,8 @@ public abstract class AbstractExtension {
     }
 
     /**
-     * 得到扩展的插件后置处理者
+     * 返回扩展的插件后置处理者。
+     * 该扩展主要是对全部插件进行处理。
      * @param applicationContext 主程序ApplicationContext
      * @return List PluginPostProcessorExtend
      */
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 0a3c2ba025c7ce0d1e0ad3aa4ac0f4f2b9c0c1f9..7eec53e946d25039df7525a4b0d5e0a7ea4bec32 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
@@ -79,8 +79,8 @@ public class SpringBeanRegister {
         if(PluginInfoContainer.existRegisterBeanName((beanName))){
             String error = MessageFormat.format("Bean name {0} already exist of {1}",
                     beanName, aClass.getName());
-            logger.error(error);
-            return null;
+            logger.debug(error);
+            return beanName;
         }
         if(consumer != null){
             consumer.accept(beanDefinition);
@@ -133,8 +133,8 @@ public class SpringBeanRegister {
      * @param beanName bean名称
      */
     public void unregister(String pluginId, String beanName){
-        applicationContext.removeBeanDefinition(beanName);
         PluginInfoContainer.removeRegisterBeanName(pluginId, beanName);
+        applicationContext.removeBeanDefinition(beanName);
     }
 
 
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/ConfigBeanProcessor.java
index 802b30d04bc13a742a472bd9c7e3c19b657c607c..17dbebb132f7a10623b50f22e7aff906079c3447 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/ConfigBeanProcessor.java
@@ -5,11 +5,11 @@ 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.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  * 插件中实现 ConfigBean 接口的的处理者
@@ -20,6 +20,8 @@ import java.util.Set;
  */
 public class ConfigBeanProcessor implements PluginPipeProcessor {
 
+    private final Logger log = LoggerFactory.getLogger(this.getClass());
+
     private static final String KEY = "ConfigBeanProcessor";
 
     private final SpringBeanRegister springBeanRegister;
@@ -44,33 +46,41 @@ public class ConfigBeanProcessor implements PluginPipeProcessor {
             return;
         }
         String pluginId = pluginRegistryInfo.getPluginWrapper().getPluginId();
-        Set beanNames = new HashSet<>();
+        Map configBeanMap = new HashMap<>();
         for (Class> aClass : configBeans) {
             if(aClass == null){
                 continue;
             }
             String name = springBeanRegister.register(pluginId, aClass);
-            beanNames.add(name);
             Object bean = applicationContext.getBean(name);
             if(bean instanceof ConfigBean){
-                ((ConfigBean)bean).initialize();
+                ConfigBean configBean = (ConfigBean) bean;
+                configBean.initialize();
+                configBeanMap.put(name, configBean);
             }
         }
-        pluginRegistryInfo.addProcessorInfo(KEY, beanNames);
+        pluginRegistryInfo.addProcessorInfo(KEY, configBeanMap);
     }
 
     @Override
     public void unRegistry(PluginRegistryInfo pluginRegistryInfo) throws Exception {
-        Set beanNames = pluginRegistryInfo.getProcessorInfo(KEY);
-        if(beanNames == null){
+        Map configBeanMap = pluginRegistryInfo.getProcessorInfo(KEY);
+        if(configBeanMap == null){
             return;
         }
-        for (String beanName : beanNames) {
-            Object bean = applicationContext.getBean(beanName);
-            if(bean instanceof ConfigBean){
-                ((ConfigBean)bean).destroy();
+        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/post/bean/PluginInvokePostProcessor.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/factory/process/post/bean/PluginInvokePostProcessor.java
index 2afd5594d5a1a2f375cb7ff9efbb1a4a733f1cc6..d97746b115981770f494c5a7d73e67da82568a1b 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
@@ -16,6 +16,7 @@ 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;
@@ -288,11 +289,11 @@ public class PluginInvokePostProcessor implements PluginPostProcessor {
                 return null;
             }
             Class> returnType = method.getReturnType();
-            if(returnType == invokeReturn.getClass()){
+            if(ClassUtils.isAssignable(invokeReturn.getClass(),returnType)){
                 return invokeReturn;
             } else {
                 String json = OBJECT_MAPPER.writeValueAsString(invokeReturn);
-                return OBJECT_MAPPER.readValue(json, returnType);
+                return OBJECT_MAPPER.readValue(json, OBJECT_MAPPER.getTypeFactory().constructType(method.getGenericReturnType()) );
             }
         }
 
diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java
index 54a008a003956e1b2a1961a50b3c6af22e0d51fc..542cdbb7f7981fb58321fab9e3394aad348086be 100644
--- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java
+++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java
@@ -131,6 +131,9 @@ public class DefaultPluginOperator implements PluginOperator {
 
     @Override
     public boolean install(Path path) throws Exception {
+        if(isDev()){
+            throw new RuntimeException("Plugin cannot be installed in 'dev' environment");
+        }
         if(path == null){
             throw new IllegalArgumentException("Method:install param 'pluginId' can not be empty");
         }
@@ -199,19 +202,19 @@ public class DefaultPluginOperator implements PluginOperator {
         if(pluginWrapper == null){
             throw new Exception("Plugin uninstall failure, Not found plugin '" + pluginId + "'");
         }
-        if(pluginWrapper.getPluginState() != PluginState.STARTED){
-            throw new Exception("This plugin '" + pluginId + "' is not started");
-        }
+
         Exception exception = null;
-        try {
-            pluginFactory.unRegistry(pluginId);
-            pluginFactory.build();
-        } catch (Exception e){
-            log.error("Plugin '{}' uninstall failure, {}", pluginId, e.getMessage());
-            exception = e;
+        if(pluginWrapper.getPluginState() == PluginState.STARTED){
+            try {
+                pluginFactory.unRegistry(pluginId);
+                pluginFactory.build();
+            } catch (Exception e){
+                log.error("Plugin '{}' uninstall failure, {}", pluginId, e.getMessage());
+                exception = e;
+            }
         }
-        try {
 
+        try {
             if (pluginManager.unloadPlugin(pluginId)) {
                 Path pluginPath = pluginWrapper.getPluginPath();
                 if(isBackup){
@@ -301,6 +304,9 @@ public class DefaultPluginOperator implements PluginOperator {
 
     @Override
     public boolean uploadPluginAndStart(MultipartFile pluginFile) throws Exception {
+        if(isDev()){
+            throw new RuntimeException("Plugin cannot be installed in the 'dev' environment");
+        }
         if(pluginFile == null){
             throw new IllegalArgumentException("Method:uploadPluginAndStart param 'pluginFile' can not be null");
         }
@@ -372,20 +378,31 @@ public class DefaultPluginOperator implements PluginOperator {
         return startedPlugins.stream()
                 .filter(pluginWrapper -> pluginWrapper != null)
                 .map(pw -> {
-                    return new PluginInfo(pw.getDescriptor(), pw.getPluginState(),
-                            pw.getPluginPath().toAbsolutePath().toString());
+                    return getPluginInfo(pw);
                 })
                 .collect(Collectors.toList());
     }
 
+
+
     @Override
     public PluginInfo getPluginInfo(String pluginId) {
         PluginWrapper pluginWrapper = pluginManager.getPlugin(pluginId);
         if(pluginWrapper == null){
             throw new RuntimeException("Not found plugin '" + pluginId + "'");
         }
+        return getPluginInfo(pluginWrapper);
+    }
+
+    /**
+     * 通过PluginWrapper得到插件信息
+     * @param pluginWrapper pluginWrapper
+     * @return PluginInfo
+     */
+    private PluginInfo getPluginInfo(PluginWrapper pluginWrapper) {
         return new PluginInfo(pluginWrapper.getDescriptor(), pluginWrapper.getPluginState(),
-                pluginWrapper.getPluginPath().toAbsolutePath().toString());
+                pluginWrapper.getPluginPath().toAbsolutePath().toString(),
+                pluginManager.getRuntimeMode().toString());
     }
 
 
@@ -469,6 +486,7 @@ public class DefaultPluginOperator implements PluginOperator {
     /**
      * 得到插件包装类
      * @param pluginId 插件id
+     * @param errorMsg 错误信息
      * @return PluginWrapper
      * @throws Exception 插件装配异常
      */
diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/operator/module/PluginInfo.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/operator/module/PluginInfo.java
index ae08b02cb10c8c24ba154c329247d6be4f02a32b..c3830010079047862a887387a861f47a639a5d3e 100644
--- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/operator/module/PluginInfo.java
+++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/integration/operator/module/PluginInfo.java
@@ -26,10 +26,20 @@ public class PluginInfo {
      */
     private String path;
 
-    public PluginInfo(PluginDescriptor pluginDescriptor, PluginState pluginState, String path) {
+    /**
+     * 允许模式
+     */
+    private String runMode;
+
+
+    public PluginInfo(PluginDescriptor pluginDescriptor,
+                      PluginState pluginState,
+                      String path,
+                      String runMode) {
         this.pluginDescriptor = pluginDescriptor;
         this.pluginState = pluginState;
         this.path = path;
+        this.runMode = runMode;
     }
 
     public PluginDescriptor getPluginDescriptor() {
@@ -47,4 +57,8 @@ public class PluginInfo {
     public String getPath() {
         return path;
     }
+
+    public String getRunMode() {
+        return runMode;
+    }
 }
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 5542b4e5fee84e0b81115ff5691373fbe4916a90..8caec980001188a5245dbbdc68a4b5b23cc92364 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
@@ -86,9 +86,11 @@ public interface PluginUser {
      */
      List getPluginBeans(String pluginId, Class aClass);
 
+
     /**
-     * 生成一个新的实例
-     * @param object 元实例对象
+     * 生成一个新的Spring实例Bean.
+     * 使用场景:主要用于非单例对象的生成。
+     * @param object 旧实例对象
      * @param  实例泛型
      * @return 新实例对象
      */
diff --git a/springboot-plugin-framework/src/main/java/com/gitee/starblues/utils/ScanUtils.java b/springboot-plugin-framework/src/main/java/com/gitee/starblues/utils/ScanUtils.java
index d30a55faf31d8a2b56b2cb51c874fe1607d18c2a..77d2b8b8fdc5097660f12287f79213dc57310a96 100644
--- a/springboot-plugin-framework/src/main/java/com/gitee/starblues/utils/ScanUtils.java
+++ b/springboot-plugin-framework/src/main/java/com/gitee/starblues/utils/ScanUtils.java
@@ -8,6 +8,7 @@ import java.io.IOException;
 import java.net.JarURLConnection;
 import java.net.URL;
 import java.nio.file.Files;
+import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Enumeration;
 import java.util.HashSet;
@@ -16,6 +17,7 @@ import java.util.Set;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * 扫描工具类
@@ -29,26 +31,61 @@ public class ScanUtils {
      * 扫描指定包中的类。包括子包中的类
      *
      * @param basePackage 包名
-     * @param baseClass   当前操作的基础类
-     * @return 类全路径
+     * @param baseClass  当前操作的基础类
+     * @return 类全路径(形如:xx.bb.cc)
      * @throws IOException 扫描异常
      */
     public static Set scanClassPackageName(String basePackage, Class baseClass) throws IOException {
+        String osName = System.getProperty("os.name");
+        if (osName.startsWith("Windows")) {
+            // windows
+            return scanClassPackageNameOfWindows(basePackage, baseClass);
+        } else {
+            // unix or linux
+            return scanClassPackageNameOfOther(basePackage, baseClass);
+        }
+    }
+
+    /**
+     * 扫描windows环境下的类。包括子包中的类
+     * @param basePackage 包名
+     * @param baseClass 当前操作的基础类
+     * @return 类全路径(形如:xx.bb.cc)
+     * @throws IOException 扫描异常
+     */
+    private static Set scanClassPackageNameOfWindows(String basePackage, Class baseClass) throws IOException {
+        String classpathRootPath = baseClass.getResource("/").getPath();
+        final String classpath = classpathRootPath
+                .replace("/","\\")
+                .replaceFirst("\\\\","");
+        // 把包名 packageName 转换为路径名
+        basePackage = basePackage.replace(".", File.separator);
+        // class 文件全路径
+        String fullPath = classpath + basePackage;
+
+        return filterPath(fullPath).map(path -> {
+                    String pathString = path.toString();
+                    return pathString
+                            .replace(classpath, "")
+                            .replace("\\",".")
+                            .replace(".class","");
+                }).collect(Collectors.toSet());
+    }
+
+
+    /**
+     * 扫描linux/unix/mac环境下的类。包括子包中的类
+     * @param basePackage 包名
+     * @param baseClass 当前操作的基础类
+     * @return 类全路径(形如:xx.bb.cc)
+     * @throws IOException 扫描异常
+     */
+    private static Set scanClassPackageNameOfOther(String basePackage, Class baseClass) throws IOException {
         final String classpath = baseClass.getResource("/").getPath();
         // class 文件全路径
         String fullPath = classpath + ClassUtils.classPackageAsResourcePath(baseClass);
 
-        return Files.walk(Paths.get(fullPath))
-                .filter(Objects::nonNull)
-                .filter(Files::isRegularFile)
-                .filter(path -> {
-                    String fileName = path.getFileName().toString();
-                    if (fileName == null) {
-                        return false;
-                    }
-                    return fileName.endsWith(".class");
-                })
-                .map(path -> {
+        return filterPath(fullPath).map(path -> {
                     String pathString = path.toString();
                     // 去头去尾
                     pathString = pathString
@@ -59,6 +96,25 @@ public class ScanUtils {
                 }).collect(Collectors.toSet());
     }
 
+    /**
+     * 过滤类
+     * @param fullPath 类的全路径
+     * @return Stream
+     * @throws IOException IOException
+     */
+    private static Stream filterPath(String fullPath) throws IOException {
+        return Files.walk(Paths.get(fullPath))
+                .filter(Objects::nonNull)
+                .filter(Files::isRegularFile)
+                .filter(path -> {
+                    String fileName = path.getFileName().toString();
+                    if(fileName == null){
+                        return false;
+                    }
+                    return fileName.endsWith(".class");
+                });
+    }
+
 
     /**
      * 扫描jar包中的类。