Spring version 4.2.0.RELEASE
Given following class, config member becomes null when cleanDocumentMirror method is executed by spring. My code is essentially similar to spring example. Its not just this field, but all other autowired fields are null.
I have afterPropertiesSet method, and that method is referring to config member and it does not fail or in otherwords members are auto wired correctly. Application does start correctly and does work correctly as all dependencies are injected correctly. Only when this method is called, I see all autowired entries as null.
The class has some methods with @JmsListener annotation and when spring invokes those methods, members look correct. Only when scheduled method is called, I face the problem. So likely I need to enable some settings.
@Component
@Scope("singleton")
@Transactional(value = "somevalue")
@EnableTransactionManagement()
public class DownloadResponseListener implements InitializingBean {
@Autowired
AggregatorConfig config;
@JmsListener(destination = "response_queue", containerFactory = "mqConnectionContainerFactory")
public void process(final ObjectMessage message) {
config.getConfigrationValue(); // works correctly here.
}
@Scheduled(fixedRate = 5 * 1000)
void cleanDocumentMirror() {
config.getConfigrationValue(); // causes NPE here as config is null
}
}
If the application starts and your field appears to be null it is generally due to one of the following issues: Using @Autowired on a static field. Omitted @Autowired on a field. Instance of bean not visible to Spring.
The @EnableScheduling annotation is used to enable the scheduler for your application. This annotation should be added into the main Spring Boot application class file. @SpringBootApplication @EnableScheduling public class DemoApplication { public static void main(String[] args) { SpringApplication.
In addition to the TaskExecutor abstraction, Spring 3.0 introduces a TaskScheduler with a variety of methods for scheduling tasks to run at some point in the future. The simplest method is the one named 'schedule' that takes a Runnable and Date only. That will cause the task to run once after the specified time.
When @Autowired doesn't work. There are several reasons @Autowired might not work. When a new instance is created not by Spring but by for example manually calling a constructor, the instance of the class will not be registered in the Spring context and thus not available for dependency injection.
I had the same issue. I found that after adding the @Scheduled
annotation, Spring actually created the bean twice -- once correctly, and once without any of the dependencies, which was being executed by the task scheduler.
In my case, it was because the method annotated with @Scheduled
was final and I guess this was causing issues with Spring's automagic proxying mechanism.
In Kotlin, all classes are final by default, therefore this is a common problem. When using Spring with Kotlin, consider use of the kotlin-spring plugin to automatically compile Spring-annotated classes and methods as open
.
Try and find similar reasons in your code that Spring may not be able to proxy the object properly (it would be nice if it raised an error or even a warning in this situation!).
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