[SprintBoot]Flyway与Shiro加载冲突解决探讨

本文解决SprintBoot项目中Shiro与Flyway的整合问题,避免因数据库表不存在导致的初始化错误,通过禁用自动配置、手动配置Flyway及调整依赖顺序实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

         先说说背景,由于在SprintBoot项目里引入了Shiro,并希望引入Flyway来管理数据库迁移,会有加载先后顺序问题,最终导致Shiro初始化Configuration时,需要查询数据库,需要MybatisPlus Mapper加载而报表不存在的错误,如果表已存在则不存在此问题:

bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: ERROR: relation "d_resource" does not exist
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:635)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338)
	

网上多是说,通过三步来达到目的:

  1) 禁用Flyway自动配置加载:

        在注解@SpringBootApplication中排除掉FlywayAutoConfiguration的加载:

@SpringBootApplication(exclude = {FlywayAutoConfiguration.class})
public class ExampleApplication {

2) 手动配置FlywayConfig(依据网上出处):

@Configuration
@Slf4j
public class FlywayConfig {
 
    @Autowired
    private DataSource dataSource; 
 
    @PostConstruct
    public void migrate() {
        Flyway flyway = Flyway.configure()
                .dataSource(dataSource)
                .baselineOnMigrate(true)
                .load();
 
        try {
            flyway.migrate();
        } catch (FlywayException e) {
            flyway.repair();
            log.error("Flyway配置出错",e);
        }
    }
}

3)依赖加持

    在Shiro或Mybatis 的Config中加入@DependsOn("flywayConfig"),这样可控制优先级,比如ShiroConfig,可加在类上:

@Configuration
@DependsOn("flywayConfig")
public class ShiroConfig {

   因为,这里ShiroConfig会优先加载,通过Service读取数据库数据时,表还不存在而报错。   

  或者设置了分页插件的MybatisPlusConfig:

@Configuration
@DependsOn("flywayConfig")
public class MybatisPlusConfig {

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        // 设置sql的limit为无限制,默认是500
        return new PaginationInterceptor().setLimit(-1);
    }
}

   网上有说,可将@DependsOn注解加到部分@Bean注解一起,貌似加类上也是可以达到目的,经过测试发现也是可以的,所以就不用每个@Bean方法上都加,除非需要细粒度控制加载顺序。

 

最后,但是

  经过测试,发现,自定义的FlywayConfig,无法正确读取application.yml里的配置,比如:

spring
  flyway:
    enabled: true
    baseline-on-migrate: true
    locations: classpath:db/migration,classpath:db/mock

locations的值,始终是默认的db/migration,甚至enabled设置为false,Flyway仍旧会执行。

由于没有花大量时间去研究,相信应该有更优解,暂采用了比较笨的办法解决:

@Slf4j
@Configuration
public class FlywayConfig {

    @Autowired
    private DataSource dataSource;
    // @Autowired
    // private FlywayProperties properties; //FIXME 貌似无法注入

    @Value("${spring.flyway.locations}")
    private List<String> locations = new ArrayList(Collections.singletonList("classpath:db/migration"));

    @Value("${spring.flyway.baseline-on-migrate}")
    private boolean baselineOnMigrate;

    @PostConstruct
    public void migrate() {
        Flyway flyway = Flyway.configure()
                .dataSource(dataSource)
                .locations(locations.toArray(new String[0]))
                .baselineOnMigrate(baselineOnMigrate)
                .load();
        // try {
        flyway.migrate();
        // } catch (FlywayException e) {
        //     flyway.repair();
        //     log.error(e.getMessage(), e);
        // }
    }}

   即显式的读取yml中的参数配置,并设置到Flyway引擎中,最终方可达到与yml设置一致的执行效果。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值