1. 程式人生 > >spring quartzy的spring注入問題(dao層和service層)

spring quartzy的spring注入問題(dao層和service層)

許久沒有寫博文了,今天來寫寫,畢業設計中遇到的某個小問題,及解決方法。
畢業設計中涉及到spring的定時器quartzy的使用,
遇到的問題是:quartzy中不能使用spring注入的方式注入dao層和service層,原因是spring在載入的時候先載入quarzy,後加載bean。查看了一下原始碼:org.springframework.scheduling.quartz.JobDetailFactoryBean。
這個類我們只看他的實現:
![JobDetailFactoryBean類的實現](https://img-blog.csdn.net/20170416232235638?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWFpeWlrYWk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

實現了ApplicationContextAware,這個類是我當時在實現rpc服務的時候瞭解過的一個類,適用於非同步載入的,可以理解為分開執行,所以我的的bean並不能被注入到quartzy中。
不過利用了一個晚上的時間查找了一些資料,終於皇天不負有心人,找到了一篇:原文地址
接下來我們看程式碼:
先重寫一下AdaptableJobFactory類中的createJobInstance(TriggerFiredBundle bundle)方法:

public class JobFactory extends AdaptableJobFactory{
    //這個物件Spring會幫我們自動注入進來,也屬於Spring技術範疇.
@Autowired private AutowireCapableBeanFactory capableBeanFactory; @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { //呼叫父類的方法 Object jobInstance = super.createJobInstance(bundle); //AutowireCapableBeanFactory這個介面一般在applicationContext的內部是較少使用的,
//它的功能主要是為了裝配applicationContext管理之外的Bean。 capableBeanFactory.autowireBean(jobInstance); return jobInstance; } }

spring配置檔案中的配置:

<!-- quartz定時器,定時器的類--自己用的類 -->
    <bean id="jobDetailFactoryBean" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.myk.oe.utils.QuartzTask"></property>
    </bean>
    <!-- 配置執行時間和規則 -->
    <bean id="quartzTask" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="jobDetailFactoryBean"></property>
        <!-- 5秒一次 -->       
        <property name="cronExpression" value="0/5 * * * * ?"></property>
    </bean>
    <!-- 將bean注入到定時器的類 -->
    <bean id="jobFactory" class="com.myk.oe.quartz.util.JobFactory"></bean>

    <!-- 總管理類 如果將lazy-init='false'那麼容器啟動就會執行排程程式 --> 
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
        <property name="triggers">
            <list>
                <ref bean="quartzTask" /><!-- 任務 -->
            </list>
        </property>
        <property name="jobFactory" ref="jobFactory"></property>
        <property name="autoStartup" value="true"/><!-- 自動開始 -->
    </bean>

配置完成之後,看定時器的執行類:

@DisallowConcurrentExecution
public class QuartzTask extends QuartzJobBean{

    @Resource(name="appointmentServiceImpl")
    private AppointmentService appointmentService;//這是服務類

    @Override
    protected void executeInternal(JobExecutionContext context)
            throws JobExecutionException {

    List<Appointment> appointments = appointmentService.getAppointments();//獲取資料
        System.err.println(appointments);
    }
}

然後執行結果:

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5436b941] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@24e6e99e] will not be managed by Spring
==>  Preparing: SELECT * FROM onlineexamination.appointment where app_date >=date_sub(now(),interval 2 day) and app_date < now() 
==> Parameters: 
<==    Columns: app_id, jiasy_id, kemu_type_id, app_price, app_date
<==        Row: 1000004, 1000005, k001, 200.00, 2017-04-15
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5436b941]
[Appointment [app_id=1000004, jiasy_id=1000005, kemu_type_id=k001, app_price=200.0, app_date=2017-04-15, jsyxxb=null, tmlxb=Tmlxb [kemu_type_id=k001, kemu_price=0.0, kemu_name_string=null]]]

看到這個結果的,還是比較欣慰的,感謝那個大牛。