1. 程式人生 > 實用技巧 >PageHelper:在系統中發現了多個分頁外掛,請檢查系統配置

PageHelper:在系統中發現了多個分頁外掛,請檢查系統配置

專案執行環境:Spring Boot + Mybatis/Mybatis-plus + PageHelper

專案前提:本專案引入了一個由其它Spring Boot專案打包成的JAR包(這個很關鍵

問題描述

在IDEA中除錯程式,分頁正常;但通過WAR包部署時報錯:“在系統中發現了多個分頁外掛,請檢查系統配置”,具體報錯資訊如下:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.RuntimeException: 在系統中發現了多個分頁外掛,請檢查系統配置!
### Cause: java.lang.RuntimeException: 在系統中發現了多個分頁外掛,請檢查系統配置!

錯誤的解決方法

根據網上的方法嘗試設定@SpringBootApplication(exclude = PageHelperAutoConfiguration.class),之後獨立WAR包部署的專案可以正常執行,但是在IDEA中分頁功能卻失效了。

解決方法

上面的解決方法雖然沒能最終解決問題,但是提供了一個思路,提示可能是自動配置的過程中出了問題

在上面的解決方法中設定@SpringBootApplication(exclude = PageHelperAutoConfiguration.class)之後獨立WAR包部署的專案可以正常執行,但是在IDEA中分頁功能卻失效了。說明確實是自動配置的問題,自動配置是需要的,但是如果配置兩次的話就會報出“多個分頁外掛”的錯誤!

問題分析

  1. 不管是在IDEA中除錯還是獨立WAR包部署,測試環境和生產環境基本一致,唯一不同是本地測試用的是Spring Boot的內建Tomcat啟動的,而生產環境是執行在獨立Tomcat中的。
    而用內建Tomcat啟動類啟動沒有問題,但是WAR包部署到獨立Tomcat就會出現這個報錯,所以要看看有什麼區別。

  2. 在將Spring Boot專案打包成WAR包時需要配置Application啟動類繼承SpringBootServletInitializer,並重寫configure方法,而configure方法的作用就是要指定啟動資源。

  3. 根據前面的分析可以猜測,是PageHelper相關的資源被指定了兩次,所以啟動的時候載入了兩次這個資源,兩次都自動配置了PageHelper外掛,從而導致報錯。所以可以根據這個思路去尋找專案中有哪些地方繼承了SpringBootServletInitializer,並重寫了configure方法。

  4. 很簡單地,可以猜到可能是自己引入的那個由其它Spring Boot專案打包成的JAR包出的問題。
    正常來說,將一個Spring Boot專案打包成JAR包時要刪除其Application啟動類,但是在某次打包時由於疏忽忘記了這個步驟,所以導致之後生成的WAR包中有兩個繼承了SpringBootServletInitializer的類,所以導致PageHelper外掛被配置了兩次。

  1. 修改將被打包成JAR包的Spring Boot專案,去掉多餘的Application,即可解決問題。

說明

本人追溯到的原因只是一種情況,但是可以按照這個思路去找問題。


拓展部分

PageHelper的自動配置類原始碼分析:PageHelperAutoConfiguration

@Configuration
@ConditionalOnBean(SqlSessionFactory.class)
@EnableConfigurationProperties(PageHelperProperties.class)
@AutoConfigureAfter(MybatisAutoConfiguration.class)
public class PageHelperAutoConfiguration {
 
    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;
 
    @Autowired
    private PageHelperProperties properties;
 
    /**
     * 接受分頁外掛額外的屬性
     *
     * @return
     */
    @Bean
    @ConfigurationProperties(prefix = PageHelperProperties.PAGEHELPER_PREFIX)
    public Properties pageHelperProperties() {
        return new Properties();
    }
 
    @PostConstruct
    public void addPageInterceptor() {
        PageInterceptor interceptor = new PageInterceptor();
        Properties properties = new Properties();
        //先把一般方式配置的屬性放進去
        properties.putAll(pageHelperProperties());
        //在把特殊配置放進去,由於close-conn 利用上面方式時,屬性名就是 close-conn 而不是 closeConn,所以需要額外的一步
        properties.putAll(this.properties.getProperties());
        interceptor.setProperties(properties);
        for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
            sqlSessionFactory.getConfiguration().addInterceptor(interceptor);
        }
    }
}
  1. 從原始碼也可以看出兩次自動配置會加入了兩個攔截器PageInterceptor,所以才會提示“多個外掛”;
  2. 加上exclude=PageHelperAutoConfiguration.class之後,相當於排除了PageHelperAutoConfiguration.class,即不讓PageHelper自動配置,所以取消自動配置後又出現分頁失效的問題。

參考

https://blog.csdn.net/ejiao1233/article/details/83995511