When I run TaskJob I am getting null pointer exception because Spring doesn't autowiring serviceJob service. Is new thread causing this problem because Spring autowired mysqlService without any problem?
public class TaskJob implements Runnable {
@Autowired
private ServiceJob serviceJob;
String name;
String source;
public TaskJob(String name, String source) {
this.name = name;
this.source = source;
}
public void run() {
serviceJob.run();
}
}
@Service
public class ServiceJob extends BaseJob{
@Autowired
private MysqlService mysqlService;
public void run(){
....
}
}
@Service
public class MysqlService {
...
}
My applicationContext.xml;
<context:component-scan base-package="cm.*" />
And my classes are;
cm.tasks.jobs.TaskJob
cm.jobs.ServiceJob
cm.services.MysqlService;
EDIT: TaskJob instanciated with;
TaskJob taskJob = new TaskJob(name, source);
Thread taskThread = new Thread(taskJob);
taskThread.start();
The answer for your question is YES. You can use autowired in thread class.
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.
Need to call the service method executeAsynchronously() to start the flow. You may auto-wire AsynchronousService to the ThreadAppRunner as follows and call service. executeAsynchronously() .
Since Spring is the most popular DI and IOC container for Java application, @Autowired is more common and @Inject is lesser-known, but from a portability point of view, it's better to use @Inject. Spring 3.0 supports JSR-330 annotation, so if you are using Spring 3.0 or higher release, prefer @Inject over @Autowired.
Spring only autowires components it creates. You are calling new TaskJob(), Spring doesn't know about this object so no autowiring will take place.
As a workaround you can call the application context directly. Firstly get a handle on the application context. This can be done by adding @Autowire for the application context itself.
@Autowired
private ApplicationContext applicationContext;
When you create TaskJob, ask the app context to do your auto-wiring.
TaskJob taskJob = new TaskJob(name, source);
applicationContext.getAutowireCapableBeanFactory().autowireBean(taskJob);
Additionally if you have any @PostConstruct
annotated methods you need triggering you can call initializeBean()
applicationContext.getAutowireCapableBeanFactory().initializeBean(taskJob, null);
Your TaskJob is instantiated wihh "new" operator which means the object created is not a spring bean. So you will have to write code to create object for the property (ServiceJob) with the new operator.
While using Spring spring framework Service objects are not created like this. Kindly use getBean method of Applicationcontext. Please see here
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