Issue
JobController.java
(POST/testjob)-> to start quartz Scheduler
(POST/testjob => start Scheduler => QuartzJob.java
=> run execute => HelloJob do runJob())
BUT When userRepository.printData()
, I got error NullPointerException
from
@Autowired
private JdbcTemplate jdbcTemplate;
JobController :
@RestController
public class JobController {
public static SchedulerFactory sf;
public static Scheduler sched;
public static CronTrigger trigger;
public static JobDetail jobDetail;
@RequestMapping(path = "/testjob", method = RequestMethod.POST)
public String testjob() {
Class c;
try {
c = Class.forName("com.demo.jobs.HelloJob");
sf = new org.quartz.impl.StdSchedulerFactory();
sched = sf.getScheduler();
jobDetail = JobBuilder.newJob(c).withIdentity("myJob", "group1").build();
trigger = (CronTrigger) TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0/5 0-59 0-23 * * ?"))
.build();
sched.scheduleJob(jobDetail, trigger);
sched.start();
} catch (Exception e) {
e.printStackTrace();
}
return "testjob!";
}
}
QuartzJob.java
@DisallowConcurrentExecution
public abstract class QuartzJob implements Job {
public abstract void runJob() throws Exception;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
try {
runJob();
} catch (Exception e) {
e.printStackTrace();
}
}
}
HelloJob.java:
public class HelloJob extends QuartzJob {
@Autowired
private UserRepository userRepository;
@Override
public void runJob() throws Exception{
try {
userRepository.printData();
} catch (Exception e) {
e.printStackTrace();
}
}
}
UserImpl.java:
@Repository
public class UserImpl implements UserRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void printData() {
List<User> result = jdbcTemplate.query(" SELECT * FROM USER ",
new BeanPropertyRowMapper<User>(User.class), new Object[] {});
for (User u : result) {
System.out.println("name: " + u.getName() + " ~ " + "phone: " + u.getPhone());
}
}
}
Does anybody have some experience with it? How to do it better? THANKS~
github_demo:https://github.com/qxgnbryoo81014/demo
Solution
The HelloJob is not manage by spring.you can use util acquire UserRepository obj like this:
private UserRepository userRepository;
public HelloJob() {
this.userRepository = SpringBeanUtils.getBean(UserRepository.class);
}
The SpringBeanUtils :
@Component
public class SpringBeanUtils implements ApplicationContextAware {
private static ApplicationContext context;
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
public static ApplicationContext getApplicationContext() {
Assert.notNull(context, "applicationContext must be not null");
return context;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringBeanUtils.context = applicationContext;
}
}
Answered By - DingHao
Answer Checked By - Katrina (JavaFixing Volunteer)