我需要在下面的Runnable Thread中访问Spring bean(featureService
和uxService
),但null
的值为applicationContext
因此我无法获取Spring bean Runnable接口。我想知道是否可以访问runnable中的spring bean?如果没有,请建议我另一种方法。
我正在使用Spring 4.0.6
和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;
}
}
我正在调用runnable,如下所示
ExecutorService es = Executors.newCachedThreadPool();
es.execute(new UserMenuUpdateTask(activeUsers));
答案 0 :(得分:1)
Spring使用ThreadLocal来存储applicationContext
,但ExecutorService创建了一个不同的Thread,其中没有bean被管理和/或beanContext找不到任何bean。
请改为使用此instructions。
答案 1 :(得分:1)
ApplicationContextAware
是Spring用来将其上下文设置为Spring自身管理(知道)的bean的接口。由于您自己创建了UserMenuUpdateTask
,因此Spring甚至不知道该实例,也无法设置该字段。
如果你不需要每个调用/每个线程的runnable的新实例(即如果UserMenuUpdateTask
是无状态或线程安全的),你可以让Spring管理它(通过注释或XML配置)并使用ExecutorService.execute()
中的Spring实例化实例。
如果每次都需要UserMenuUpdateTask
的新实例,则需要改为调用类ApplicationContextAware
(假设它的实例由Spring管理),并将指针设置为application UserMenuUpdateTask
中的上下文,然后将其提供给ExecutorService
。
答案 2 :(得分:0)
ApplicationContextAware接口仅在Spring内部实例化对象时起作用。当您执行 new UserMenuUpdateTask(activeUsers)时,spring对此对象一无所知,因此它不会设置applicationContext。
编写没有参数的构造函数,将范围设置为prototype并从spring获取此对象,在下一行设置activeUsers,它应该可以工作。或者在创建对象后手动设置应用程序。
我也建议你改变这一行
for (User user : userNamesList) {
featureService = (FeatureService) applicationContext.getBean("featureService");
uxService = (UxService) applicationContext.getBean("uxService");
//.........
}
到
featureService = (FeatureService) applicationContext.getBean("featureService");
uxService = (UxService) applicationContext.getBean("uxService");
for (User user : userNamesList) {
//.........
}