Spring 具有 Quartz 作业的 AOP

Spring AOP with Quartz jobs

我正在尝试将 Spring AOP 与 Quartz 作业 spring beans 一起使用。使用以下方法将作业自动连接到 spring 容器中: 一种。创建 AutowiringSpringBeanJobFactory 扩展 SpriongBeanJobFactory 实现 ApplicationContextAware b.覆盖 createJobInstance 并使用 AutowiringCapableBeanFactory 自动装配作业 bean。

solution

Spring 引导应用程序配置:

@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);
  }
}

作业的自动装配完成为:

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;

    }
}

使用此设置,我创建了一个方面:

@Aspect
@Configuration
public class MyAspect {
    @Around("execution(public void com.myapp.jobs.*.execute(..))")
    public Object process(ProceedingJoinPoint pjp) throws Throwable {
       // do something with pjp
    }
}

这是我的示例作业:

@Service
public class Myjob implements Job {
  @Autowired
  IAuditService auditService;

  public void execute(JobExecutionContext jctx) throws JobExecutionException {
    //do something
  }
}

但是,当上述作业执行时,spring aop 不会调用 MyAspect.process()。

我已经在自动装配我的作业 Bean,并且我能够将其他 Bean 自动装配到我的作业中,但只有方面没有被调用。这里缺少什么?

首先你可以使用@Component而不是@Configuration作为你的方面的注释,因此它看起来像这样:

@Aspect
@Component
public class MyAspect {
    @Around("execution(public void com.myapp.jobs.*.execute(..))")
    public Object process(ProceedingJoinPoint pjp) throws Throwable {
       // do something with pjp
    }
}

其次确定切入点表达式是否正确,是否指的是对的package/classe/method.

最后,如果你没有使用 spring 引导你应该添加 @EnableAspectJAutoProxy 到你的配置 class 否则不需要那个spring 自动配置启动!

要为我的作业启用 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();
    }
}

但是,如果您的作业在其方法上使用注释,则还有其他问题。不过那是另一次了。