Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

exclusive Spring profiled beans and DependsOn annotation

The code that works for me:
part of configuration of the database looks like this:

@Profile("!dbClean")
@Bean(initMethod = "migrate")
public Flyway flywayNotADestroyer() {
    Flyway flyway = new Flyway();
    flyway.setDataSource(dataSource());
    flyway.setInitOnMigrate(true);
    return flyway;
}

@Profile("dbClean")
@Bean(initMethod = "migrate")
public Flyway flywayTheDestroyer() {
    Flyway flyway = new Flyway();
    flyway.setDataSource(dataSource());
    flyway.setInitOnMigrate(true);
    flyway.clean();
    return flyway;
}

the configuration represents two exclusive beans. One is being created when "dbClean" profile is present and another is created when it is not present. Bear with me and forget about code duplication.

Another configuration governs the Quartz configuration:

@Autowired
private Flyway flyway;

@Bean
public SchedulerFactoryBean quartzScheduler(Flyway flyway) throws SchedulerException {
    SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean();

    quartzScheduler.setDataSource(dataSource);
    quartzScheduler.setTransactionManager(transactionManager);
    quartzScheduler.setOverwriteExistingJobs(true);
    quartzScheduler.setSchedulerName("mysuperduperthegratest-quartz-scheduler");

    AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
    jobFactory.setApplicationContext(applicationContext);
    quartzScheduler.setJobFactory(jobFactory);
    quartzScheduler.setQuartzProperties(schedulingProperties);

    return quartzScheduler;
}

The above works like a charm. The problem is Quartz configuration is not using the Flyway autowired bean. It only needs that this bean is created earlier than the Quartz scheduler.

So the ideal configuration would be:

the db part:

@Profile("!dbClean")
@Bean(name = "flyway", initMethod = "migrate")
public Flyway flywayNotADestroyer() {
    Flyway flyway = new Flyway();
    flyway.setDataSource(dataSource());
    flyway.setInitOnMigrate(true);
    return flyway;
}

@Profile("dbClean")
@Bean(name = "flyway", initMethod = "migrate")
public Flyway flywayTheDestroyer() {
    Flyway flyway = new Flyway();
    flyway.setDataSource(dataSource());
    flyway.setInitOnMigrate(true);
    flyway.clean();
    return flyway;
}

The Quartz part:

@Bean
@DependsOn({"flyway"})
public SchedulerFactoryBean quartzScheduler() throws SchedulerException {
    SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean();

    quartzScheduler.setDataSource(dataSource);
    quartzScheduler.setTransactionManager(transactionManager);
    quartzScheduler.setOverwriteExistingJobs(true);
    quartzScheduler.setSchedulerName("mysuperduperthegratest-quartz-scheduler");

    AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
    jobFactory.setApplicationContext(applicationContext);
    quartzScheduler.setJobFactory(jobFactory);
    quartzScheduler.setQuartzProperties(schedulingProperties);

    return quartzScheduler;
}

The problem is that the last configuration wont work. Neither of the flyway beans is ever created. And I have no idea why. Back than when I was using xml configuration I remember that it was possible to have two beans with the same name in different profiles. And it worked. Am I doing something wrong here or this may be some bug in Spring itself? Normally I debug Spring myself but the part of Spring with @Configuration logic is a green filed for me on which I can't waste time on at the moment.

like image 850
goroncy Avatar asked Mar 27 '15 08:03

goroncy


1 Answers

I know this question was asked ages ago but I ran into an issue use Quartz and Flyway in a Spring Boot project.

Quartz would try and start up before flyway created tables. The following worked for me:

@DependsOn("flywayInitializer")
public SchedulerFactoryBean quartzScheduler() { ...
like image 73
dvanrensburg Avatar answered Oct 29 '22 18:10

dvanrensburg