将无状态 bean 注入到 ScheduledExecutorService 的可运行对象中
Inject stateless bean into runnable for ScheduledExecutorService
我想 运行 在部署 Glassfish 之后进行一些处理。进程将 运行 每小时进行一次,它包含通过无状态 bean CarService 和下面的 findAll() 从数据库 table 获取数据:
@PersistenceContext
private EntityManager em;
public List<Cars> findAll() {
javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(Cars.class));
return em.createQuery(cq).getResultList();
}
然后我在部署后使用 ScheduledExecutorService 启动进程。
@ManagedBean(eager=true)
@ApplicationScoped
public class ApplicationStateChange {
private ScheduledExecutorService scheduler;
@PostConstruct
public void init() {
System.out.println("ejb init method called");
scheduler = Executors.newScheduledThreadPool(2);
scheduler.scheduleAtFixedRate(new ScheduleTask();, 15, 30, TimeUnit.SECONDS);
}
@PreDestroy
public void destroy() {
/* Shutdown stuff here */
System.out.println("ejb destroy method called");
scheduler.shutdownNow();
}
上面的 ScheduleTask() 包含包含业务逻辑的流程,例如:
public class ScheduleTask implements Runnable {
@Inject
CarService carService;
private volatile ScheduledExecutorService scheduler = null;
@Override
public void run() {
System.out.println("scheduletask is called");
List<Car> carList = new ArrayList<>();
carList = carService.findAll();
if (carList != null) {
for (Car car : carList) {
System.out.println(car);
}
}
}
我无法通过注入上述 运行nable class 来获取 findALL() 方法。调度程序工作正常但是当它到达 carList = carService.findAll();
时它失败了事实上它在 javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
失败了
我怀疑持久性上下文在调用时没有正确加载。
我已关注以下问题Spawning threads in a JSF managed bean for scheduled tasks using a timer
scheduledExecutorService, timerService and Stateless EJB on scheduled jobs
正如您所链接的第一个问题的答案中明确指出的那样,只需将 @Schedule
用于 @Singleton
用 @Startup
注释的 SessionBean,以确保它在服务器运行时运行启动或部署应用程序。
正如您正确提到的,EntityManager 和 PersistenceContext 不能注入到非容器管理的 class(并且 Singleton SessionBean 是托管的 class)。
链接答案:
Spawning threads in a JSF managed bean for scheduled tasks using a timer
我想 运行 在部署 Glassfish 之后进行一些处理。进程将 运行 每小时进行一次,它包含通过无状态 bean CarService 和下面的 findAll() 从数据库 table 获取数据:
@PersistenceContext
private EntityManager em;
public List<Cars> findAll() {
javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(Cars.class));
return em.createQuery(cq).getResultList();
}
然后我在部署后使用 ScheduledExecutorService 启动进程。
@ManagedBean(eager=true)
@ApplicationScoped
public class ApplicationStateChange {
private ScheduledExecutorService scheduler;
@PostConstruct
public void init() {
System.out.println("ejb init method called");
scheduler = Executors.newScheduledThreadPool(2);
scheduler.scheduleAtFixedRate(new ScheduleTask();, 15, 30, TimeUnit.SECONDS);
}
@PreDestroy
public void destroy() {
/* Shutdown stuff here */
System.out.println("ejb destroy method called");
scheduler.shutdownNow();
}
上面的 ScheduleTask() 包含包含业务逻辑的流程,例如:
public class ScheduleTask implements Runnable {
@Inject
CarService carService;
private volatile ScheduledExecutorService scheduler = null;
@Override
public void run() {
System.out.println("scheduletask is called");
List<Car> carList = new ArrayList<>();
carList = carService.findAll();
if (carList != null) {
for (Car car : carList) {
System.out.println(car);
}
}
}
我无法通过注入上述 运行nable class 来获取 findALL() 方法。调度程序工作正常但是当它到达 carList = carService.findAll();
时它失败了事实上它在 javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
我怀疑持久性上下文在调用时没有正确加载。
我已关注以下问题Spawning threads in a JSF managed bean for scheduled tasks using a timer
scheduledExecutorService, timerService and Stateless EJB on scheduled jobs
正如您所链接的第一个问题的答案中明确指出的那样,只需将 @Schedule
用于 @Singleton
用 @Startup
注释的 SessionBean,以确保它在服务器运行时运行启动或部署应用程序。
正如您正确提到的,EntityManager 和 PersistenceContext 不能注入到非容器管理的 class(并且 Singleton SessionBean 是托管的 class)。
链接答案:
Spawning threads in a JSF managed bean for scheduled tasks using a timer