Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

autowired entries are null when using @Scheduled annotation?

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
  }
}
like image 626
user871199 Avatar asked Jan 28 '16 22:01

user871199


People also ask

Why Autowired is getting 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.

What is @scheduled annotation in 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.

How does @scheduled work in Spring?

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.

Why is @autowired not working?

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.


1 Answers

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!).

like image 68
Raman Avatar answered Sep 18 '22 12:09

Raman