首页 > 技术文章 > [AOP拦截 ]SpringBoot+Quartz Aop拦截Job类中的方法

hujunhui 2019-07-05 11:09 原文

​ 最近在工作使用boot+quartz整合,开发定时调度平台,遇到需要对Quartz的Job进行异常后将异常记录到日志表的操作,第一反应就想到了使用Spring的AOP,利用AfterThrowing来完成这个操作。

话不多说,直接上代码:

 

1 <!--整合Quartz-->
2 <dependency>
3       <groupId>org.springframework.boot</groupId>
4       <artifactId>spring-boot-starter-quartz</artifactId>
5 </dependency>

1.正常的一个job类:

2. 创建JobBeanFactory类,重写 SpringBeanJobFactory 的方法。

 1 import org.quartz.SchedulerContext;
 2 import org.quartz.spi.TriggerFiredBundle;
 3 import org.springframework.beans.BeanWrapper;
 4 import org.springframework.beans.MutablePropertyValues;
 5 import org.springframework.beans.PropertyAccessorFactory;
 6 import org.springframework.beans.factory.BeanFactory;
 7 import org.springframework.lang.Nullable;
 8 import org.springframework.scheduling.quartz.SpringBeanJobFactory;
 9 
10 /**
11  * @Author: Hujh
12  * @Date: 2019/7/5 9:38
13  * @Description:  配置job工厂
14  */
15 public class JobBeanFactory extends SpringBeanJobFactory{
16 
17     @Nullable
18     private String[] ignoredUnknownProperties;
19 
20     @Nullable
21     private SchedulerContext schedulerContext;
22 
23 
24     private final BeanFactory beanFactory;
25 
26 
27     JobBeanFactory(BeanFactory beanFactory){
28         this.beanFactory = beanFactory;
29     }
30 
31 
32     public void setIgnoredUnknownProperties(String... ignoredUnknownProperties) {
33         this.ignoredUnknownProperties = ignoredUnknownProperties;
34     }
35 
36     @Override
37     public void setSchedulerContext(SchedulerContext schedulerContext) {
38         this.schedulerContext = schedulerContext;
39     }
40 
41 
42     /**
43      * @Title: createJobInstance
44      * @Author : Hujh
45      * @Date: 2019/7/5 10:19
46      * @Description : 创建调度工作接口
47      * @param : bundle
48      * @Return : java.lang.Object
49      */
50     @Override
51     protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
52         Class<?> jobClass = bundle.getJobDetail().getJobClass();
53         Object job = beanFactory.getBean(jobClass);
54         if (isEligibleForPropertyPopulation(job)) {
55             BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(job);
56             MutablePropertyValues pvs = new MutablePropertyValues();
57             if (this.schedulerContext != null) {
58                 pvs.addPropertyValues(this.schedulerContext);
59             }
60             pvs.addPropertyValues(bundle.getJobDetail().getJobDataMap());
61             pvs.addPropertyValues(bundle.getTrigger().getJobDataMap());
62             if (this.ignoredUnknownProperties != null) {
63                 for (String propName : this.ignoredUnknownProperties) {
64                     if (pvs.contains(propName) && !bw.isWritableProperty(propName)) {
65                         pvs.removePropertyValue(propName);
66                     }
67                 }
68                 bw.setPropertyValues(pvs);
69             }
70             else {
71                 bw.setPropertyValues(pvs, true);
72             }
73         }
74         return job;
75     }
76 }

3.创建 QuartzConfig类,交给spring容器进行管理

 1 import org.springframework.beans.BeansException;
 2 import org.springframework.boot.autoconfigure.quartz.SchedulerFactoryBeanCustomizer;
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.ApplicationContextAware;
 5 import org.springframework.context.annotation.Bean;
 6 import org.springframework.context.annotation.Configuration;
 7 
 8 /**
 9  * @Author: Hujh
10  * @Date: 2019/7/5 9:39
11  * @Description: Quartz相关配置类
12  */
13 @Configuration
14 public class QuartzConfig implements ApplicationContextAware {
15 
16     private ApplicationContext applicationContext;
17 
18     @Bean
19     public SchedulerFactoryBeanCustomizer schedulerFactoryBeanCustomizer() {
20         // Spring 项目整合 Quartz  主要依靠添加 SchedulerFactoryBean 这个 FactoryBean
21         return schedulerFactoryBean -> schedulerFactoryBean.setJobFactory(new JobBeanFactory(applicationContext));
22     }
23 
24     /**
25      * 初始化加载applicationContext
26      */
27     @Override
28     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
29         this.applicationContext = applicationContext;
30     }
31 }

4. 创建AOP拦截:JobLogAop

1  <!-- aop依赖 -->
2  <dependency>
3       <groupId>org.springframework.boot</groupId>
4       <artifactId>spring-boot-starter-aop</artifactId>
5  </dependency>

 

 1  2 
 3 import org.aspectj.lang.annotation.*;
 4 import org.slf4j.Logger;
 5 import org.slf4j.LoggerFactory;
 6 import org.springframework.stereotype.Component;
 7 
 8 /**
 9  * @Author: Hujh
10  * @Date: 2019/7/4 17:12
11  * @Description: 工作调度任务拦截 (日志记录)
12  */
13 @Component
14 @Aspect
15 public class JobLogAop {
16 
17     private Logger logger = LoggerFactory.getLogger(JobLogAop.class);
18 
19     /**
20      * 只对于execute切入
21      */
22     @Pointcut("execution(public void com.ylsp.jobs..*.execute(..))")
23     public void pointJobLog(){}
24 
25     /**
26      * 切点通知(方法执行后)
27      */
28     @AfterReturning("pointJobLog()")
29     public void handlerControllerMethod() {
30         logger.info("execute方法执行后..---->> 开始写入日志");
31     }
32 
33 
34 }

 

  注:直接创建一个Job,可以看到Aop已经生效。

 

推荐阅读