i've got Spring Boot with annotation based configuration running, but I#m pretty new to spring. I really could not find a solution to my problem elsewhere. I've got Task objects with the following inheritance structure:
Now I want to autowire some Repository to the SystemTask. Also I want to autowire the Repository and some Service to the UserTask (and all of its children).
How do I do this? With the following code I get a Null Pointer Exception.
the parent:
public abstract class ParentTask implements Runnable {
// some fields
protected ParentTask(/*fields*/) {
//this.fields = fields;
}
@Override
public abstract void run();
}
the first child:
public class SystemTask extends ParentTask {
@Autowired
protected SomeService someService;
protected SystemTask(/*fields*/) {
super(fields);
//set some other fields
}
@Override
public void run() {
someService.doSomething(); // <-- nullPointerException
}
}
the second child:
public abstract class UserTask extends ParentTask {
@Autowired
protected SomeService someService;
@Autowired
protected SomeRepository someRepository;
protected UserTask(/*fields*/) {
super(fields);
}
@Override
public abstract void run();
}
child of UserTask (shall have the autowired ressources of UserTask)
public class SpecificUserTask extends UserTask{
private SpecificUserTask (/*fields*/) {
super(fields);
//set some other fields
}
@Override
public void run() {
// do something
}
}
My Repository is a standard mongo repository imlpementation and should not have any errors. My "someService" looks something like this:
@Service
public class SomeService{
// some fields
@Autowired
private someOtherRepository someOtherRepository;
// some methods
public void doSomething() {
//...
}
}
So again my questions:
Thank you all in advance.
EDIT: this is how I create a new Task whenever needed:
@Service
public class TaskAdministration {
private final TaskAdministrationRepository taskAdministrationRepository;
public void commissionSystemTask(fields) {
SystemTask task = new SystemTask(fields);
taskScheduler.schedule(task, taskTrigger);
// persist task to restore if necessary
taskAdministrationRepository.save(task);
}
}
You need to put annotation on your SpecificUserTask
class like @Component
. And then when you @Autowired
your SpecificUserTask
spring will inject everything for it and it's super classes.
Spring doesn't know anything about your SpecificUserTask
object if you're not annotating it with spring's specific annotation.
Autowiring happens by placing an instance of one bean into the field in an instance of another bean. Both classes should be beans and should "live" in application context.
"living" in the application context means that the context instantiates the objects, not you, you should never make new MyClass()
. The container finds each injection point and sets an instance there.
So when you're annotating bean with annotation like @Service
or @Component
spring finds them and instantiates.
I resolved my Problem, which was actually needing an autowired service/repository in a non-spring managed class. I used manual dependency injection like described here:
How do I manually autowire a bean with Spring?
This way I can have multiple instances of a class and also use services managed by spring. This is my code now:
@Service
public class TaskAdministration {
@Autowired
private ApplicationContext appContext;
private final TaskAdministrationRepository taskAdministrationRepository;
public void commissionSystemTask(fields) {
SystemTask task = new SystemTask(trigger);
AutowireCapableBeanFactory factory = appContext.getAutowireCapableBeanFactory();
factory.autowireBean( task );
factory.initializeBean( task, "SystemTask" );
taskScheduler.schedule(task, task.trigger);
// persist task to restore if necessary
taskAdministrationRepository.save(task);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.