前幾天,同事問了我一個問題,我告訴他用spring的定時任務解決,並給他配置了spring的定時任務。當時隨便找了一個bean寫了一段代碼,驗證定時任務正確執行后,就沒再管,昨天下午,同事寫代碼的時候,把這段代碼移到了自己特定的bean中。問題就來了,定時任務不執行了。我給他把代碼的位置又換回之前的那個bean中。又可以執行。。
弄了老半天,終於解決了。原來是spring延遲加載的問題。
spring 定時任務的配置:
spring3.0后,引入了注解,因此配置顯得很方便。只要配置好配置文件的命名空間,然后直接在代碼中使用注解即可!
首先,配置文件的schema要加上 這兩句:
- http://www.springframework.org/schema/task
- http://www.springframework.org/schema/task/spring-task-3.1.xsd
然后,配置namespace的別名:
- xmlns:task="http://www.springframework.org/schema/task"
配置文件的頭部,就配置好了。
然后是,打開定時器的開關:
- <task:annotation-driven/>
這樣。spring就可以根據注解掃描這些bean,然后檢查注解代碼了。
執行定時的代碼:
- @Scheduled(cron="0/5 * * * * ? ")
- public void schetest(){
- System.out.println("scheduled invoke!");
- }
每隔五秒執行一次。
正常的配置應該如上。但是昨天卻出了問題。把這個代碼寫到某個類中就沒問題,寫到這個包下面的同樣別的bean中就不執行了。 后來去網上搜了一下,一篇文章說道:要順利執行定時任務,執行這段代碼的bean,不能使延遲加載而來的。 即 不能是default-lazy-init="true"。我看了一下,配置文件,發現這個文件beans 節點中,赫然寫着default-lazy-init="true" 於是問題找到了。 這樣寫的目的是,加快啟動時間,啟動的時候,對bean的加載延遲。但是有錯誤卻無法即使顯現了。 因為配置文件是搭環境時配置好的。因此不便改動。因此采用別的辦法,手動 配置這個bean不再延遲加載,即在這個bean上 加上:
- @Lazy(false)
這樣,這個類就不再是延遲加載了。定時任務寫在他里面,也正常執行了。
問題解決了。但我還有一個疑問:為什么,我在同一個包下面,把代碼寫到某些類中,他可以執行,寫到某些類中卻不可以執行呢? 仔細看了一遍那邊配置文件,發現有一段代碼:
- <bean id="methodCachePointCut"
- class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
- <property name="advice">
- <ref local="methodCacheInterceptor" />
- </property>
- <property name="patterns">
- <list>
- <!--
- <value>com.xajob.service.AdvertisService.getAll</value>
- <value>com.xajob.service.LinksService.getAll</value>
- <value>com.xajob.service.CompanyService.getFamousCompanies</value>
- <value>execution(com.xajob.service.JobService.getByIndustr*(..))</value>
- <value>execution(com.xajob.service.CompanyService.getByIndustr*(..))</value>
- <value>execution(com.xajob.service.CompanyService.getGraduate*(..))</value>
- <value>execution(com.xajob.service.JobService.getGraduate*(..))</value>
- <value>execution(com.xajob.service.JobService.countByIndustr*(..))</value>
- <value>execution(com.xajob.service.PersonService.getNew*(..))</value>
- <value>execution(com.xajob.service.JobService.getNew*(..))</value>
- <value>execution(com.xajob.service.CompanyService.getNew*(..))</value>
- <value>execution(com.xajob.service.ArticleService.get*(..))</value>
- <value>execution(com.xajob.service.ArticleService.page*(..))</value>
- <value>execution(com.xajob.service.ArticleService.group*(..))</value>
- <value>com.xajob.service.JobService.pageHighLevelJob</value>
- <value>execution(com.xajob.service.JobService.getTop*(..))</value>
- <value>execution(com.xajob.service.SpecialCompanyService.get*(..))</value>
- -->
- <value>com.xajob.service.LinksService.getAll</value>
- <value>com.xajob.service.AdvertisService.getAll</value>
- <value>.*getFamousCompanies</value>
- <value>.*getNewPerson</value>
- <value>.*getNew5Job</value>
- <value>.*getNew5Urgent</value>
- <value>.*getNewCompany</value>
- <value>.*getTop20HighLevelJob</value>
- <value>com.xajob.service.SpecialCompanyService.*</value>
- <value>com.xajob.service.ArticleService.getByType</value>
- <value>com.xajob.service.ArticleService.pageByType</value>
- <value>com.xajob.service.ArticleService.getTopTen</value>
- <value>com.xajob.service.ArticleService.getNewEight</value>
- <value>com.xajob.service.ArticleService.getImgNews</value>
- <value>com.xajob.service.ArticleService.groupByType</value>
- </list>
- </property>
- </bean>
- <bean id="cacheAdvertisService"
- class="com.xajob.service.AdvertisService">
- </bean>
- <bean id="cacheLinksService"
- class="com.xajob.service.LinksService">
- </bean>
- <bean id="cacheArticleService"
- class="com.xajob.service.ArticleService">
- </bean>
- <bean id="cacheCompanyService"
- class="com.xajob.service.CompanyService">
- </bean>
- <bean id="cacheJobService"
- class="com.xajob.service.JobService">
- </bean>
- <bean id="cacheSpecialCompanyService"
- class="com.xajob.service.SpecialCompanyService">
- </bean>
- <bean id="cachePersonService"
- class="com.xajob.service.PersonService">
- </bean>
- <bean id="cacheAdvertisInterceptor" class="org.springframework.aop.framework.ProxyFactoryBean">
- <property name="target">
- <list>
- <ref local="cacheAdvertisService"/>
- <ref local="cacheLinksService"/>
- <ref local="cacheArticleService"/>
- <ref local="cacheCompanyService"/>
- <ref local="cacheJobService"/>
- <ref local="cacheSpecialCompanyService"/>
- <ref local="cachePersonService"/>
- </list>
- </property>
- <property name="interceptorNames">
- <list>
- <value>methodCachePointCut</value>
- </list>
- </property>
- </bean>
看bean的名稱,ProxyFactoryBean. 猜測應該和代理有關。百度了一下,的確如此。 考慮了一下,這段代碼大體意思是,org.springframework.aop.support.RegexpMethodPointcutAdvisor 對其ref指向的下面的攔截的bean中的某些方法進行切面。攔截的方法就是pattern中定義的。
而org.springframework.aop.framework.ProxyFactoryBean 這個類,就是使用了代理,重新生成了幾個對象,而使這幾個bean避免了延遲加載,因此定時代碼寫在他里面會執行!
- 頂
- 0
- 踩