Spring Boot 1.5
Quartz 2.2
我在运行时使用Quartz配置为jdbc-job-store动态创建和调度Quartz作业。这些工作需要在应用程序执行之间保持不变。 在作业执行期间,我需要访问完整的Spring上下文(Spring管理的bean和JPA事务)。
然而,如果我尝试将任何东西自动装入我的工作中,那么我会收到类似的错误。 "通过字段myAutowiredField"
表示的不满意的依赖性我无法解决这个问题。我发现很多人都展示了如何让自动装配工作在Quartz工作中,但几乎所有这些工作都只有一个静态的,硬编码的工作。不是在运行时动态创建的作业。
以下网址的示例最接近。它可动态创建作业,并且自动装配功能非常出色。但是,它是一家公羊店。一旦我切换到jdbc,我就回到原点。
我也看过这些..
Spring + Hibernate + Quartz: Dynamic Job
inject bean reference into a Quartz job in Spring?
......等等。
但同样,他们的解决方案似乎都缺少了一些东西。例如,他们依赖于静态工作,触发器,或者只是简单地工作等等。
任何人都有关于最新资源的提示或链接?
谢谢!
修改1
当工作被解雇时,弹簧上下文会发生一些事情。这里有一些代码可以说明。
在第一次autowireBean()调用中(这是在Spring Boot配置期间完成的),它不会抛出错误。注意:在这一点上,没有用处,我只是表明它确实工作了#39;这里。
在第二次autowireBean()调用中(这是触发作业的时候),它失败了。这是真实的'调用
public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory
{
private transient AutowireCapableBeanFactory beanFactory;
public AutowiringSpringBeanJobFactory(ApplicationContext context)
{
super();
this.beanFactory = context.getAutowireCapableBeanFactory();
MyJobClass job = new MyJobClass();
beanFactory.autowireBean(new MyJobClass()); /** no problem **/
beanFactory.initializeBean(job, "job");
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception
{
final Object job = super.createJobInstance(bundle); /* job is an instance MyJobClass.. same as above */
beanFactory.autowireBean(job); /** "Unsatisfied dependency" exception **/
beanFactory.initializeBean(job, "job");
return job;
}
}
修改2
好吧,我似乎已经开始工作,但是,我不知道是否会有后果。 这是org.springframework.scheduling.quartz.AdaptableJobFactory
的罪魁祸首protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
return bundle.getJobDetail().getJobClass().newInstance();
}
似乎bundle.getJobDetail()。getJobClass()返回了一些' proxy'我的工作类的类型。但基本上它'说'它返回了我正确的Job课程,但情况有所不同。它有相同的名称,但我无法施展它。例如......
Object job = bundle.getJobDetail().getJobClass().newInstance();
MyJobClass myJob = (MyJobClass) job;
引发错误,说我无法将com.company.MyJobClass转换为com.company.MyJobClass。
所以这里是我的修复' ...
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception
{
String className = bundle.getJobDetail().getJobClass().getName();
Object job = Class.forName(className).newInstance();
beanFactory.autowireBean(job);
job = beanFactory.applyBeanPostProcessorsAfterInitialization(job, "job"); // Without this, @Transactional in my job bean doesn't work
beanFactory.initializeBean(job, "job");
return job;
}
由于我不再调用super(),我失去了SpringBeanJobFactory的一个方便功能,但我暂时还不错。 我想底线是需要在这个sucker包装在事务代理中之前调用autowireBean()。
答案 0 :(得分:0)
当你提到"不是在运行时动态创建的作业。"我会假设你在某些时候做了类似的事情:MyJob job = new MyJob()
;
如果您想使用Spring
' @Autowire
在MyJob中注入依赖项,我想到的一种方法是:
@Configurable(dependencyCheck = true)
java -javaagent:<path to spring-agent-${spring.version}.jar> ...