To run a Job in a TaskExecutor
I need to instantiate new Jobs implementing the Runnable
Interface. To solve this, i will create a new Spring Prototype Bean named Job "on Demand".
But in my application a Job
has two fields LocationChanger
and QueryTyper
. These two should share the same WebDriver
instance created by a WebDriverFactory
.
Now the question is how to design this with Spring?
This is the related code:
@Component
@Scope("prototype")
public class Job implements Runnable {
@Autowired
LocationChanger locationChanger;
@Autowired
QueryTyper queryTyper;
@Override
public void run() {
// at this point the locationChanger and
// queryTyper should share the same instance
}
}
@Component
@Scope("prototype")
public class LocationChanger {
@Autowired
@Qualifier(...) // For every new Job Created, the same WebDriver instance should be injected.
WebDriver webDriver
}
@Component
@Scope("prototype")
public class QueryTyper {
@Autowired
@Qualifier(...) // For every new Job Created, the same WebDriver instance should be injected.
WebDriver webDriver
}
public class WebDriverFactoryBean implements FactoryBean<WebDriver> {
@Override
public WebDriver getObject() throws Exception {
return // createdAndPrepare...
}
@Override
public boolean isSingleton() {
return false;
}
}
Thanks a lot!
Update 1:
A possible solution could be to autowire the WebDriver
in the Job only and then in a @PostConstruct
inject this WebDriver to the LocationChanger
and QueryTyper
. But then i wire by hand.
@Component
@Scope("prototype")
public class Job implements Runnable {
@Autowired
LocationChanger locationChanger;
@Autowired
QueryTyper queryTyper;
@Autowired
WebDriver webDriver;
@PostConstruct
public void autowireByHand() {
locationChanger.setWebDriver(this.webDriver);
queryTyper.setWebDriver(this.webDriver);
}
}
// + remove all @Autowired WebDriver's from LocationChanger and QueryTyper
If I understand your requirement, you need WebDriver
to be shared between a Job
and LocationChanger
. So it's not prototype
scope, and it's not singleton
scope. To solve this, I think you either have to do it by hand, as you suggest, or you could try to implement your own scope, as described in the Spring reference documentation
Edit
I don't think you "handwired" solution looks that bad BTW.