I need to access Spring beans(featureService
and uxService
) in my Runnable Thread below but am getting null
value for applicationContext
hence I couldnt get Spring beans inside the Runnable. I am wondering if its possible to access spring beans inside a runnable or not? if not please suggest me an alternative approach.
I am using Spring 4.0.6
and Java 8
@Component
public class UserMenuUpdateTask implements Runnable, Serializable, ApplicationContextAware {
private static final long serialVersionUID = 3336518785505658027L;
List<User> userNamesList;
FeatureService featureService;
UXService uxService;
private ApplicationContext applicationContext;
public UserMegaMenuUpdateTask() {}
public UserMegaMenuUpdateTask(List<User> userNamesList) {
this.userNamesList = userNamesList;
}
@Override
public void run() {
try {
for (User user : userNamesList) {
featureService = (FeatureService) applicationContext.getBean("featureService");
uxService = (UxService) applicationContext.getBean("uxService");
//.........
}
} catch (BaseApplicationException ex) {
throw new BaseApplicationException(ex);
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
I am calling the runnable as below
ExecutorService es = Executors.newCachedThreadPool();
es.execute(new UserMenuUpdateTask(activeUsers));
ApplicationContextAware
is an interface used by Spring to set its context into beans that Spring itself manages (knows about). Since you create the UserMenuUpdateTask
yourself, Spring does not even know about the instance and cannot set the field.
If you don't need a new instance of your runnable for every call / every thread (i.e. if the UserMenuUpdateTask
is stateless or thread-safe), you can let Spring manage it (through annotations or XML configuration) and use the Spring-instantiated instance in ExecutorService.execute()
.
If a new instance of UserMenuUpdateTask
is needed every time, you'll need to instead make the calling class ApplicationContextAware
(assuming instance of it is managed by Spring), and set the pointer to application context in the UserMenuUpdateTask
before giving it to the ExecutorService
.
Spring uses ThreadLocal to store the applicationContext
but ExecutorService creates a different Thread where no beans are managed and/or the beanContext does not find any beans.
Follow this instructions instead.
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