最近的一個(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:
這里注意反射獲取注解修改其屬性的用法。
參考