英文:
Spring AOP with Quartz jobs
问题
I am trying to use Spring AOP with Quartz job spring beans. The jobs are autowired into spring container using the following approach:
a. Create AutowiringSpringBeanJobFactory extending SpringBeanJobFactory implementing ApplicationContextAware
b. override createJobInstance and use the AutowiringCapableBeanFactory to autowire the job beans.
Spring boot Application Configuration:
@Configuration
public class MyApplicationConfig {
@Bean
@Primary
public SchedulerFactoryBean schedulerFactoryBean() throws Exception {
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(ApplicationContextProvider.getContext());
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
factoryBean.setDataSource(datasource());
factoryBean.setConfigLocation(new ClassPathResource("quartz.properties"));
factoryBean.setFactory(jobFactory);
}
}
Autowiring of Jobs done as:
public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext() {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}
Using this setup, I have created an Aspect:
@Aspect
@Configuration
public class MyAspect {
@Around("execution(public void com.myapp.jobs.*.execute(..))")
public Object process(ProceedingJoinPoint pjp) throws Throwable {
// do something with pjp
}
}
This is my sample job:
@Service
public class Myjob implements Job {
@Autowired
IAuditService auditService;
public void execute(JobExecutionContext jctx) throws JobExecutionException {
//do something
}
}
However, when the above job executes, spring aop does not invoke MyAspect.process().
I am already autowiring my job beans and I am able to autowire other beans into my jobs but only the aspect does not get invoked. What's missing here?
英文:
I am trying to use Spring AOP with Quartz job spring beans. The jobs are autowired into spring container using the following approach:
a. Create AutowiringSpringBeanJobFactory extending SpriongBeanJobFactory implementing ApplicationContextAware
b. override createJobInstance and use the AutowiringCapableBeanFactory to autowire the job beans.
See solution
Spring boot Application Configuration:
@Configuration
public class MyApplicationConfig {
@Bean
@Primary
public SchedulerFactoryBean schedulerFactoryBean() throws Exception {
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(ApplicationContextProvider.getContext());
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
factoryBean.setDataSource(datasource());
factoryBean.setConfigLocation(new ClassPathResource("quartz.properties"));
factoryBean.setFactory(jobFactory);
}
}
Autowiring of Jobs done as:
public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext() {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}
Using this setup, I have created an Aspect:
@Aspect
@Configuration
public class MyAspect {
@Around("execution(public void com.myapp.jobs.*.execute(..))")
public Object process(ProceedingJoinPoint pjp) throws Throwable {
// do something with pjp
}
}
This is my sample job:
@Service
public class Myjob implements Job {
@Autowired
IAuditService auditService;
public void execute(JobExecutionContext jctx) throws JobExecutionException {
//do something
}
}
However, when the above job executes, spring aop does not invoke MyAspect.process().
I am already autowring my job beans and I am able to autowire other beans into my jobs but only the aspect does not get invoked. Whats missing here?
答案1
得分: 0
Sure, here's the translated content:
首先,你可以使用 @Component
替代 @Configuration
作为你的切面的注解,这样它会像这样:
@Aspect
@Component
public class MyAspect {
@Around("execution(public void com.myapp.jobs.*.execute(..))")
public Object process(ProceedingJoinPoint pjp) throws Throwable {
// 对 pjp 做一些操作
}
}
其次,确保切点表达式是正确的,你是否引用了正确的包/类/方法。
最后,如果你没有使用 Spring Boot,你应该将 @EnableAspectJAutoProxy
添加到你的配置类中,否则在 Spring Boot 中不需要,因为它是自动配置的!
英文:
First of all you can use @Component
instead of @Configuration
as annotation of your aspect, thus it will look like this:
@Aspect
@Component
public class MyAspect {
@Around("execution(public void com.myapp.jobs.*.execute(..))")
public Object process(ProceedingJoinPoint pjp) throws Throwable {
// do something with pjp
}
}
Secondly make sure that the pointcut expression is correct, whether you are referring to the right package/classe/method.
Lastly, if you are not using spring boot you should add @EnableAspectJAutoProxy
to your configuration class otherwise no need for that with spring boot as it's auto configured !
答案2
得分: 0
为了在我的作业中启用AOP,我不得不增强“AutowiringSpringBeanJobFactory”,以手动为作业编织方面的内容,如下所示:
public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private AutowireCapableBeanFactory beanFactory;
private Object jobAspect;
public void setJobAspect(Object aspect) {
this.jobAspect = aspect;
}
@Override
public void setApplicationContext() {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
AspectJProxyFactory pFactory = new AspectJProxyFactory(job);
pFactory.addAspect(this.jobAspect);
return pFactory.getProxy();
}
}
然而,如果您的作业在其方法上使用了注解,还有其他问题。不过,这是另一个时间要讨论的事情。
英文:
To enable AOP for my jobs, i had to enhance "AutowiringSpringBeanJobFactory " to manually weave aspects in for the jobs as follows:
public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private AutowireCapableBeanFactory beanFactory;
private Object jobAspect;
public void setJobAspect(Object aspect) {
this.jobAspect = aspect;
}
@Override
public void setApplicationContext() {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
AspectJProxyFactory pFactory = new AspectJProxyFactory(job);
pFactory.addAspect(this.jobAspect);
return pFactory.getProxy();
}
}
However, there are additional issues with this if your job uses annotations on its method(s). That's for another time though.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论