最近的一个springboot项目有一个在项目启动时,切换使用数据库存储还是区块链存储的需求。使用区块链存储时,需要屏蔽掉jpa自动进行数据库连接的操作。
这里通过在项目启动时给主类传参来判断选择的存储方式,确定是区块链时,在主类中通过反射来修改springboot开启自动配置的注解的属性值,去除掉数据库相关的自动配置类,起到不连接数据库的作用。
具体方法如下:
//正常的springboot项目启动类
@SpringBootApplication
public class TestReflectionStopJpaConnectionDbApplication {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
SpringApplication.run(
TestReflectionStopJpaConnectionDbApplication.class, args);
}
}
将上面的主类的 @SpringBootApplication 注解修改为下面的注解(下面的注解是@SpringBootApplication的具体实现,这里提出来方便使用反射修改),同时启动springboot项目时带有参数,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("-========================");
//获取自动配置注解
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);
//将数据库相关配置类赋值给该注解的exclude属性
classes = new Class[]{DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class};
memberValues.put("exclude", classes);
}
SpringApplication.run(TestReflectionStopJpaConnectionDbApplication.class, args);
}
}
这样在项目启动时就不会进行数据库连接了。
note:
这里注意反射获取注解修改其属性的用法。
参考