springboot項(xiàng)目利用反射修改自動(dòng)配置類

最近的一個(gè)springboot項(xiàng)目有一個(gè)在項(xiàng)目啟動(dòng)時(shí),切換使用數(shù)據(jù)庫存儲(chǔ)還是區(qū)塊鏈存儲(chǔ)的需求。使用區(qū)塊鏈存儲(chǔ)時(shí),需要屏蔽掉jpa自動(dòng)進(jìn)行數(shù)據(jù)庫連接的操作。

這里通過在項(xiàng)目啟動(dòng)時(shí)給主類傳參來判斷選擇的存儲(chǔ)方式,確定是區(qū)塊鏈時(shí),在主類中通過反射來修改springboot開啟自動(dòng)配置的注解的屬性值,去除掉數(shù)據(jù)庫相關(guān)的自動(dòng)配置類,起到不連接數(shù)據(jù)庫的作用。

具體方法如下:

//正常的springboot項(xiàng)目啟動(dòng)類
@SpringBootApplication
public class TestReflectionStopJpaConnectionDbApplication {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
     SpringApplication.run(
TestReflectionStopJpaConnectionDbApplication.class, args);
    }

}

將上面的主類的 @SpringBootApplication 注解修改為下面的注解(下面的注解是@SpringBootApplication的具體實(shí)現(xiàn),這里提出來方便使用反射修改),同時(shí)啟動(dòng)springboot項(xiàng)目時(shí)帶有參數(shù),java -jar target/test_reflection_stop_jpa_connection_db-0.0.1-SNAPSHOT.jar blockchain 改為下面的代碼

@SpringBootConfiguration
@ComponentScan(
        excludeFilters = {@ComponentScan.Filter(
                type = FilterType.CUSTOM,
                classes = {TypeExcludeFilter.class}
        ), @ComponentScan.Filter(
                type = FilterType.CUSTOM,
                classes = {AutoConfigurationExcludeFilter.class}
        )}
)
@EnableAutoConfiguration
public class TestReflectionStopJpaConnectionDbApplication {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        
        if ("blockchain".equals(args[0])){
            log.info("-========================");
            //獲取自動(dòng)配置注解
            EnableAutoConfiguration autoConfiguration = TestReflectionStopJpaConnectionDbApplication.class.getAnnotation(EnableAutoConfiguration.class);
            InvocationHandler invocationHandler = Proxy.getInvocationHandler(autoConfiguration);

            Field values = invocationHandler.getClass().getDeclaredField("memberValues");
            values.setAccessible(true);
            Map<String,Object> memberValues = (Map<String, Object>) values.get(invocationHandler);
            Class[] classes = (Class[]) memberValues.get("exclude");
            log.info("改變前, size = {}", classes.length);

            //將數(shù)據(jù)庫相關(guān)配置類賦值給該注解的exclude屬性
            classes = new Class[]{DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class};
            memberValues.put("exclude", classes);
        }

        SpringApplication.run(TestReflectionStopJpaConnectionDbApplication.class, args);
    }

}

這樣在項(xiàng)目啟動(dòng)時(shí)就不會(huì)進(jìn)行數(shù)據(jù)庫連接了。

note:
這里注意反射獲取注解修改其屬性的用法。
參考

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容