spring boot加载第三方jar包的配置文件

来源:互联网 发布:javascript入门视频 编辑:程序博客网 时间:2024/06/04 18:28

前言

今天收到一封邮件,大概内容如下:spring boot鼓励去配置化,那么怎么将第三方jar包中的xml去配置化了?

其实,这个问题,在前面的博客中也有提到,http://blog.csdn.net/liuchuanhong1/article/details/60873295

下面,我们就以Quartz定时任务为例,单独对这个问题来进行说明,如何实现去配置化。

如果不使用spring boot,我们配置一个简单的定时任务时,需要引入以下配置文件:

<!-- 配置需要定时执行的任务类以及方法 --><bean id="doJob"class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"><!-- 指定任务类 --><property name="targetObject" ref="schedulerTask" /><!-- 指定任务执行的方法 --><property name="targetMethod" value="doTask" /><property name="concurrent" value="false"></property></bean><!-- 配置触发器 --><bean id="jobTrigger"class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"><property name="jobDetail" ref="doJob" /><!-- 每5秒运行一次 --><property name="cronExpression" value="0/5 * * * * ?" /></bean><!-- 触发定时任务 --><bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="triggers"><list><ref bean="jobTrigger" /><!-- 此处可以配置多个触发器 --></list></property><property name="applicationContextSchedulerContextKey" value="applicationContextKey" /><property name="waitForJobsToCompleteOnShutdown" value="true"></property></bean>
接下来的任务,就是如何将上面的xml配置文件,去配置化。

从上面的配置文件中,可以得出,我们需要配置3个实例,分别是JobDetail,JobTrigger和Scheduler。

1、首先抽取出需要在application.properties配置文件中配置的属性项,从上面的配置文件中,可以得出如下需要配置的属性项,对应的VO如下:

package com.chhliu.springboot.quartz.config;import org.springframework.boot.context.properties.ConfigurationProperties;@ConfigurationProperties(prefix="quartz.config")public class QuartzConfigProperties {private String targetObject;private String targetMethod;private boolean concurrent;private String cronExpression;private String applicationContextSchedulerContextKey;private boolean waitForJobsToCompleteOnShutdown;                ……省略getter、setter方法……}
2、在application.properties配置文件中,加入如下配置

quartz.config.targetObject=taskJob ## 待执行对象的名字quartz.config.targetMethod=doJob ## 待执行的方法的名字quartz.config.concurrent=false ## 是否并发,如果上一个定时任务还没有执行完,又被触发了,如果配置为false,则需等待上个任务执行完,才触发quartz.config.cronExpression=0/5 * * * * ? ## 任务触发表达式quartz.config.applicationContextSchedulerContextKey=applicationContextKey ## 通过该key可以获取spring上下文quartz.config.waitForJobsToCompleteOnShutdown=true ## 是否等待任务完全执行完后,再销毁线程池
3、分别实例化JobDetail,JobTrigger和Scheduler

package com.chhliu.springboot.quartz.entity;import org.quartz.Trigger;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.quartz.CronTriggerFactoryBean;import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;import org.springframework.scheduling.quartz.SchedulerFactoryBean;import com.chhliu.springboot.quartz.config.QuartzConfigProperties;/** * 描述:将quartz的xml配置文件去配置化 * @author chhliu * 创建时间:2017年4月11日 下午7:41:21 * @version 1.2.0 */@Configurationpublic class QuartzConfig {        @Autowired    private QuartzConfigProperties properties; // 注入属性配置文件对应的类实例        /**     * attention:     * Details:初始化JobDetail     * @author chhliu     * 创建时间:2017年4月11日 下午6:17:06     * @param task     * @return     * MethodInvokingJobDetailFactoryBean     * @throws ClassNotFoundException      * @throws IllegalAccessException      * @throws InstantiationException      */    @Bean(name = "jobDetail")    public MethodInvokingJobDetailFactoryBean detailFactoryBean() throws ClassNotFoundException, InstantiationException, IllegalAccessException {// ScheduleTask为需要执行的任务        MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();        /*         *  是否并发执行         *  例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了,         *  如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行         */        jobDetail.setConcurrent(properties.isConcurrent());                /*         * 为需要执行的实体类对应的对象         */        String targetObject = properties.getTargetObject();        jobDetail.setTargetBeanName(targetObject);                /*         * 通过这几个配置,告诉JobDetailFactoryBean我们需要定时执行targetObject类中的properties.getTargetMethod()方法         */        jobDetail.setTargetMethod(properties.getTargetMethod());        return jobDetail;    }        /**     * attention:     * Details:实例化JobTrigger     * @author chhliu     * 创建时间:2017年4月11日 下午7:39:14     * @param jobDetail     * @return     * CronTriggerFactoryBean     */    @Bean(name = "jobTrigger")    public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) {        CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();        tigger.setJobDetail(jobDetail.getObject());        tigger.setCronExpression(properties.getCronExpression());        return tigger;    }        /**     * attention:     * Details:实例化Scheduler     * @author chhliu     * 创建时间:2017年4月11日 下午7:39:35     * @param cronJobTrigger     * @return     * SchedulerFactoryBean     */    @Bean(name = "scheduler")    public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) {        SchedulerFactoryBean bean = new SchedulerFactoryBean();        // 注册触发器        bean.setTriggers(cronJobTrigger);        // 通过applicationContextSchedulerContextKey属性配置获取spring上下文        bean.setApplicationContextSchedulerContextKey(properties.getApplicationContextSchedulerContextKey());        // 关闭任务的时候,是否等待任务执行完毕        bean.setWaitForJobsToCompleteOnShutdown(properties.isWaitForJobsToCompleteOnShutdown());        return bean;    }}
4、编写需要执行的方法

package com.chhliu.springboot.quartz.job;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;@Service("taskJob")public class TaskJob {private static final Logger LOGGER =  LoggerFactory.getLogger(TaskJob.class);public void doJob(){LOGGER.info("hello spring boot, i'm the king of the world!!!");}}
5、测试

package com.chhliu.springboot.quartz;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.context.properties.EnableConfigurationProperties;import com.chhliu.springboot.quartz.config.QuartzConfigProperties;@SpringBootApplication@EnableConfigurationProperties({QuartzConfigProperties.class} ) // 开启配置属性支持public class SpringbootQuartzApplication {public static void main(String[] args) {SpringApplication.run(SpringbootQuartzApplication.class, args);}}
6、测试结果如下
2017-04-11 19:09:35.017  INFO 7500 --- [eduler_Worker-1] c.chhliu.springboot.quartz.job.TaskJob   : hello spring boot, i'm the king of the world!!!2017-04-11 19:09:40.004  INFO 7500 --- [eduler_Worker-2] c.chhliu.springboot.quartz.job.TaskJob   : hello spring boot, i'm the king of the world!!!2017-04-11 19:09:45.004  INFO 7500 --- [eduler_Worker-3] c.chhliu.springboot.quartz.job.TaskJob   : hello spring boot, i'm the king of the world!!!2017-04-11 19:09:50.004  INFO 7500 --- [eduler_Worker-4] c.chhliu.springboot.quartz.job.TaskJob   : hello spring boot, i'm the king of the world!!!2017-04-11 19:09:55.001  INFO 7500 --- [eduler_Worker-5] c.chhliu.springboot.quartz.job.TaskJob   : hello spring boot, i'm the king of the world!!!2017-04-11 19:10:00.002  INFO 7500 --- [eduler_Worker-6] c.chhliu.springboot.quartz.job.TaskJob   : hello spring boot, i'm the king of the world!!!2017-04-11 19:10:05.001  INFO 7500 --- [eduler_Worker-7] c.chhliu.springboot.quartz.job.TaskJob   : hello spring boot, i'm the king of the world!!!
从上面的测试结果可以看出,任务被触发了,也得到了正确的结果。

上面的这个示例,只是一个简单的例子,但是生产上复杂的需求,原理也是类似的。

2 0