My application.properties
file defines the default profile as spring.profiles.active=test
and I have a method that I schedule like so:
@Scheduled(initialDelay = 2500, fixedRate = 60 * 1000 * minutesRecheckRate)
@Profile("loop")
public void processingLoop() {
System.out.println(Arrays.toString(env.getActiveProfiles()));
//.. the rest is omitted for brevity.
To my understanding, under these circumstances I should never see this get called while running my unit-tests because I do not change the default profile. This turns out not to be the case, as this is still getting scheduled and I see the output
[test]
in my console despite my best efforts to prevent it. What is happening? Why is this still running even with a different active profile?
UPDATE: I can't give much more due to the fact this is a work-relevant application, but I'll give what I can.
The class is configured like so:
@Configuration
@EnableScheduling
public class BatchConfiguration {
The unit tests are all annotated like this:
@SpringApplicationConfiguration(classes = SpringBatchJsontestApplication.class)
public class SpringBatchJsontestApplicationTests extends AbstractTestNGSpringContextTests {
The main application class is this:
@SpringBootApplication
public class SpringBatchJsontestApplication {
None of them change anything else. There is no context.xml
file, this is a SpringBoot application so everything is annotations only.
This is the end result that works very well for me
@Profile("test")
@Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public ScheduledAnnotationBeanPostProcessor scheduleBeanProcessorOverride() {
logger.info("Test Profile is active, overriding ScheduledAnnotationBeanPostProcessor to prevent annotations from running during tests.");
return new ScheduledAnnotationBeanPostProcessor() {
@Override
protected void processScheduled(Scheduled scheduled, Method method, Object bean) {
logger.info(String.format("Preventing scheduling for %s, %s, %s", scheduled, method, bean.getClass().getCanonicalName()));
}
};
}
Here is the POM configuration to trigger the testing profile, so I no longer have to do so explicitly in my application.properties
.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<systemPropertyVariables>
<spring.profiles.active>test</spring.profiles.active>
</systemPropertyVariables>
</configuration>
</plugin>
The @Profile
annotation doesn't do anything for a regular method, nor a method annotated with @Scheduled
. The javadoc states
The @Profile annotation may be used in any of the following ways:
- as a type-level annotation on any class directly or indirectly annotated with
@Component
, including@Configuration
classes- as a meta-annotation, for the purpose of composing custom stereotype annotations
- as a method-level annotation on any
@Bean
method
The last case, in bold, is the only use of @Profile
on a method.
If you want to enable the @Scheduled
behavior under a specific profile, annotate the bean (definition) that contains it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With