Spring Batch 鏋勫徐浼佷笟绾ф壒澶勭悊搴旂敤

Spring Batch 鏋勫缓浼佷笟绾ф壒澶勭悊搴旂敤

浣跨敤 Spring Batch 鏋勫缓浼佷笟绾ф壒澶勭悊搴旂敤: 绗?1 閮ㄥ垎

Spring Batch 鏄竴娆惧熀浜?Spring 鐨勬壒澶勭悊妗嗘灦锛岄€氳繃瀹冨彲浠ヨ交鏄撴瀯寤哄嚭楂樺唴鑱氥€佷綆鑰﹀悎鐨勪紒涓氭壒澶勭悊搴旂敤銆傞€氳繃鏈枃鎮ㄥ彲浠ヤ竴姝ユ浜嗚В濡備綍寮€鍙戝熀浜?Spring Batch 鐨勬壒澶勭悊绋嬪簭銆傚悓鏃讹紝鏈枃杩樹粙缁嶄簡 Spring Batch 鐨勭浉鍏虫牳蹇冩蹇点€?/p>

鍒?鍏夌憺, 杞欢鏋舵瀯甯? 鍥涜揪杞欢

2012 骞?2 鏈?16 鏃?/p>

  • Spring Batch 鏋勫徐浼佷笟绾ф壒澶勭悊搴旂敤鍐呭

寮曡█

鎬昏堪

鏈郴鍒楁枃绔犳棬鍦ㄩ€氳繃绀轰緥鎼缓浠ュ強鐗规€т粙缁嶏紝璇︾粏璁茶堪濡備綍鍒╃敤 Spring Batch 寮€鍙戜紒涓氭壒澶勭悊搴旂敤銆傛湰绯诲垪鏂囩珷鍏卞垎涓轰笁閮ㄥ垎锛岀涓€閮ㄥ垎鍒濇浠嬬粛浜嗘壒澶勭悊浠ュ強 Spring Batch 鐨勭浉鍏虫蹇碉紝鍚屾椂鎼缓浜嗕竴涓畝鍗曠殑鍩轰簬 Spring Batch 鐨勬壒澶勭悊搴旂敤銆傜浜岄儴鍒嗕粙缁嶄簡 Step Flow 浠ュ強骞跺彂鏀寔銆傜涓夐儴鍒嗗垯涓昏浠嬬粛浜?Spring Batch 瀵逛换鍔$洃鎺х殑鏀寔銆備笅闈㈣鎴戜滑杩涘叆绗竴閮ㄥ垎鍐呭銆?/p>

浠€涔堟槸鎵瑰鐞?/h3>

鍦ㄧ幇浠d紒涓氬簲鐢ㄥ綋涓紝闈㈠澶嶆潅鐨勪笟鍔′互鍙婃捣閲忕殑鏁版嵁锛岄櫎浜嗛€氳繃搴炴潅鐨勪汉鏈轰氦浜掔晫闈㈣繘琛屽悇绉嶅鐞嗗锛岃繕鏈変竴绫诲伐浣滐紝涓嶉渶瑕佷汉宸ュ共棰勶紝鍙渶瑕佸畾鏈熻鍏ュぇ鎵归噺鏁版嵁锛岀劧鍚庡畬鎴愮浉搴斾笟鍔″鐞嗗苟杩涜褰掓。銆傝繖绫诲伐浣滃嵆涓衡€滄壒澶勭悊鈥濄€?/p>

浠庝笂闈㈢殑鎻忚堪鍙互鐪嬪嚭锛屾壒澶勭悊搴旂敤鏈夊涓嬪嚑涓壒鐐癸細

  • 鏁版嵁閲忓ぇ锛屽皯鍒欑櫨涓囷紝澶氬垯涓婁嚎鐨勬暟閲忕骇銆?/li>
  • 涓嶉渶瑕佷汉宸ュ共棰勶紝鐢辩郴缁熸牴鎹厤缃嚜鍔ㄥ畬鎴愩€?/li>
  • 涓庢椂闂寸浉鍏筹紝濡傛瘡澶╂墽琛屼竴娆℃垨姣忔湀鎵ц涓€娆°€?/li>

鍚屾椂锛屾壒澶勭悊搴旂敤鍙堟槑鏄惧垎涓轰笁涓幆鑺傦細

  • 璇绘暟鎹紝鏁版嵁鍙兘鏉ヨ嚜鏂囦欢銆佹暟鎹簱鎴栨秷鎭槦鍒楃瓑
  • 鏁版嵁澶勭悊锛屽鐢典俊鏀拺绯荤粺鐨勮璐瑰鐞?/li>
  • 鍐欐暟鎹紝灏嗚緭鍑虹粨鏋滃啓鍏ユ枃浠躲€佹暟鎹簱鎴栨秷鎭槦鍒楃瓑

鍥犳锛屼粠绯荤粺鏋舵瀯涓婏紝搴旈噸鐐硅€冭檻鎵瑰鐞嗗簲鐢ㄧ殑浜嬪姟绮掑害銆佹棩蹇楃洃鎺с€佹墽琛屻€佽祫婧愮鐞嗭紙灏ゅ叾瀛樺湪骞跺彂鐨勬儏鍐典笅锛夈€備粠绯荤粺璁捐涓婏紝搴旈噸鐐硅€冭檻鏁版嵁璇诲啓涓庝笟鍔″鐞嗙殑瑙h€︼紝鎻愰珮澶嶇敤鎬т互鍙婂彲娴嬭瘯鎬с€?/p>

浠€涔堟槸 Spring Batch

Spring Batch 浣滀负 Spring 鐨勫瓙椤圭洰锛屾槸涓€娆惧熀浜?Spring 鐨勪紒涓氭壒澶勭悊妗嗘灦銆傞€氳繃瀹冨彲浠ユ瀯寤哄嚭鍋ュ.鐨勪紒涓氭壒澶勭悊搴旂敤銆係pring Batch 涓嶄粎鎻愪緵浜嗙粺涓€鐨勮鍐欐帴鍙c€佷赴瀵岀殑浠诲姟澶勭悊鏂瑰紡銆佺伒娲荤殑浜嬪姟绠$悊鍙婂苟鍙戝鐞嗭紝鍚屾椂杩樻敮鎸佹棩蹇椼€佺洃鎺с€佷换鍔¢噸鍚笌璺宠繃绛夌壒鎬э紝澶уぇ绠€鍖栦簡鎵瑰鐞嗗簲鐢ㄥ紑鍙戯紝灏嗗紑鍙戜汉鍛樹粠澶嶆潅鐨勪换鍔¢厤缃鐞嗚繃绋嬩腑瑙f斁鍑烘潵锛屼娇浠栦滑鍙互鏇村鍦板幓鍏虫敞鏍稿績鐨勪笟鍔″鐞嗚繃绋嬨€?/p>

鍙﹀鎴戜滑杩橀渶瑕佺煡閬擄紝Spring Batch 鏄竴娆炬壒澶勭悊搴旂敤妗嗘灦锛屼笉鏄皟搴︽鏋躲€傚畠鍙叧娉ㄦ壒澶勭悊浠诲姟鐩稿叧鐨勯棶棰橈紝濡備簨鍔°€佸苟鍙戙€佺洃鎺с€佹墽琛岀瓑锛屽苟涓嶆彁渚涚浉搴旂殑璋冨害鍔熻兘銆傚洜姝わ紝濡傛灉鎴戜滑甯屾湜鎵瑰鐞嗕换鍔″畾鏈熸墽琛岋紝鍙粨鍚?Quartz 绛夋垚鐔熺殑璋冨害妗嗘灦瀹炵幇銆?/p>

涓嬮潰灏嗛€氳繃涓€涓ず渚嬭缁嗕粙缁嶅浣曚娇鐢?Spring Batch 鎼缓鎵瑰鐞嗗簲鐢ㄣ€傝繖涓ず渚嬫瘮杈冪畝鍗曪紝瀵圭郴缁熶腑鎵€鏈夌敤鎴峰彂閫佷竴灏佺即璐规彁閱掗€氱煡銆傛澶勶紝鎴戜滑绠€鍗曞湴灏嗙即璐规彁閱掕緭鍑哄埌鎺у埗鍙般€傚綋鐒讹紝闅忕潃浠嬬粛鐨勬繁鍏ワ紝鎴戝皢閫愭笎涓板瘜璇ュ姛鑳斤紝浣垮叾鏈€缁堝畬鏁村睍绀?Spring Batch 鐨勫悇绉嶇壒鎬с€?/p>

鐜鎼缓

棣栧厛锛屼粠 Spring 瀹樻柟缃戠珯涓嬭浇 Spring Batch 鍙戝竷鍖咃紙瑙伮?a style="margin: 0px; padding: 0px; border: 0px; font-size: inherit; vertical-align: baseline; color: #745285;" href="http://www.ibm.com/developerworks/cn/java/j-lo-springbatch1/#resources">鍙傝€冭祫婧?/a>锛夈€傛湰鏂囧熀浜?Spring Batch 2.1.6锛堝綋鍓嶆渶鏂扮増鏈负 2.1.8锛変互鍙?Spring 2.5.6 鐗堟湰鏋勫缓銆傛垜浠彲浠ョ湅鍒?Spring Batch 鍏卞寘鍚?spring-batch-core 鍜?spring-batch-infrastructure 涓や釜鍖呫€俿pring-batch-core 涓昏鍖呭惈鎵瑰鐞嗛鍩熺浉鍏崇被锛岃€?spring-batch-infrastructure 鎻愪緵浜嗕竴涓熀纭€璁块棶澶勭悊妗嗘灦銆?/p>

鎺ヤ笅鏉ワ紝璁╂垜浠柊寤轰竴涓?Eclipse 宸ョ▼锛屽苟灏?Spring Batch 浠ュ強 Spring 鐩稿叧鍖呮坊鍔犲埌渚濊禆鐜锛屽 鍥?1 鎵€绀?/p>

鍥?1. 渚濊禆鐜
Spring Batch 鏋勫徐浼佷笟绾ф壒澶勭悊搴旂敤

鐜鎼缓瀹屾垚鍚庯紝璁╂垜浠湅涓€涓嬪浣曚竴姝ユ鏋勫缓涓€涓壒澶勭悊搴旂敤銆?/p>

鏋勫缓搴旂敤

濡傗€滃紩瑷€鈥濅腑鎵€杩?Spring Batch 鎸夌収鍏虫敞鐐圭殑涓嶅悓锛屽皢鏁翠釜鎵瑰鐞嗚繃绋嬪垎涓轰笁閮ㄥ垎锛氳銆佸鐞嗐€佸啓锛屼粠鑰屽皢鎵瑰鐞嗗簲鐢ㄨ繘琛屽悎鐞嗚В鑰︺€傚悓鏃讹紝Spring Batch 杩橀拡瀵硅銆佸啓鎿嶄綔鎻愪緵浜嗗绉嶅疄鐜帮紝濡傛秷鎭€佹枃浠躲€佹暟鎹簱銆傚浜庢暟鎹簱锛岃繕鎻愪緵浜?Hibernate銆乮Batis銆丣PA 绛夊父瑙?ORM 妗嗘灦鐨勮銆佸啓鎺ュ彛鏀寔銆?/p>

瀵硅薄瀹氫箟

棣栧厛鎴戜滑闇€瑕佺紪鍐欑敤鎴蜂互鍙婃秷鎭被锛屾瘮杈冪畝鍗曪紝濡傛竻鍗?1 鍜?娓呭崟 2 鎵€绀猴細

娓呭崟 1. User 绫?/h5>
package org.springframework.batch.sample;

public class User {
	private String name;
	private Integer age;
	public String getName() {return name;}
	public void setName(String name) {this.name = name;}
	public Integer getAge() {return age;}
	public void setAge(Integer age) {this.age = age;}
}
娓呭崟 2. Message 绫?/h5>
package org.springframework.batch.sample;

public class Message {
	private String content;
	public String getContent() {return content;}
	public void setContent(String content) {this.content = content;}
}

璇诲啓鍙婂鐞嗘帴鍙?/h3>

棣栧厛锛屾墍鏈?Spring Batch 鐨勮鎿嶄綔鍧囬渶瑕佸疄鐜?ItemReader 鎺ュ彛锛岃€屼笖 Spring Batch 涓烘垜浠彁渚涗簡澶氱榛樿瀹炵幇锛屽挨鍏舵槸鍩轰簬 ORM 妗嗘灦鐨勮鎺ュ彛锛屽悓鏃舵敮鎸佸熀浜庢父鏍囧拰鍒嗛〉涓ょ被鎿嶄綔銆傚洜姝わ紝澶氭暟鎯呭喌涓嬫垜浠苟涓嶉渶瑕佹墜鍔ㄧ紪鍐?ItemReader 绫伙紝鑰屾槸鐩存帴浣跨敤鐩稿簲瀹炵幇绫诲嵆鍙€?/p>

鍦ㄨ绀轰緥涓紝鎴戜滑浣跨敤 org.springframework.batch.item.file.FlatFileItemReader 绫讳粠鏂囦欢涓繘琛屼俊鎭鍏ワ紝鐢ㄦ埛淇℃伅鏍煎紡瀹氫箟濡?娓呭崟 3 鎵€绀恒€?/p>

娓呭崟 3. 鐢ㄦ埛淇℃伅
 User1,20 
 User2,21 
 User3,22 
 User4,23 
 User5,24 
 User6,25 
 User7,26 
 User8,27 
 User9,28 
 User10,29

璇ョ被灏佽浜嗘枃浠惰鎿嶄綔锛屼粎浠呴渶瑕佹垜浠墜鍔ㄨ缃?LineMapper 涓庤闂枃浠惰矾寰勫嵆鍙€係pring Batch 閫氳繃 LineMapper 鍙互灏嗘枃浠朵腑鐨勪竴琛屾槧灏勪负涓€涓璞°€傛垜浠笉闅惧彂鐜帮紝Spring Batch 灏嗘枃浠舵搷浣滃皝瑁呬负绫讳技 Spring JDBC 椋庢牸鐨勬帴鍙o紝杩欎篃涓?Spring 涓€璐€″鐨勬帴鍙g粺涓€鏄竴鑷寸殑銆傛澶勬垜浠娇鐢?org.springframework.batch.item.file.mapping.DefaultLineMapper 杩涜琛屾槧灏勩€傝鎿嶄綔鐨勯厤缃俊鎭 娓呭崟 4 鎵€绀猴細

娓呭崟 4. message_job.xml
<beans:bean id="messageReader" 
      class="org.springframework.batch.item.file.FlatFileItemReader">
	<beans:property name="lineMapper" ref="lineMapper">
	</beans:property>
	<beans:property name="resource" 
	value="classpath:/users.txt"></beans:property>
</beans:bean>
<beans:bean id="lineMapper"
	class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
	<beans:property name="lineTokenizer">
		<beans:bean 
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
        </beans:bean>
	</beans:property>
	<beans:property name="fieldSetMapper">
		<beans:bean class="org.springframework.batch.sample.UserMapper">
        </beans:bean>
	</beans:property>
</beans:bean>

浠庢竻鍗曟垜浠彲浠ョ煡閬擄紝DefaultLineMapper 闇€瑕佽缃?lineTokenizer 鍜?fieldSetMapper 涓や釜灞炴€э紝棣栧厛閫氳繃 lineTokenizer 瀹屾垚鏂囦欢琛屾媶鍒嗭紝骞跺皝瑁呬负涓€涓睘鎬х粨鏋滈泦锛屽洜涓烘垜浠娇鐢ㄢ€?鈥濆垎闅旂敤鎴峰睘鎬э紝鎵€浠ラ渶瑕佸皢 lineTokenizer 璁剧疆涓?DelimitedLineTokenizer銆傛渶鍚庨€氳繃 fieldSetMapper 瀹屾垚灏嗙粨鏋滈泦灏佽涓轰竴涓?POJO 瀵硅薄銆傚叿浣撳疄鐜板 娓呭崟 5 鎵€绀猴細

娓呭崟 5. UserMapper 绫?/h5>
 package org.springframework.batch.sample;

import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.validation.BindException;

public class UserMapper implements FieldSetMapper<User> {
	public User mapFieldSet(FieldSet fs) throws BindException {
		User u = new User();
		u.setName(fs.readString(0));
		u.setAge(fs.readInt(1));
		return u;
	}
}

璇ユ帴鍙g殑瀹炵幇鏂瑰紡涓?Spring JDBC 鐨?RowMapper 鏋佸叾鐩镐技銆?/p>

鎺ヤ笅鏉ワ紝鍐嶈鎴戜滑鐪嬩竴涓嬪浣曞疄鐜板啓鎿嶄綔銆係pring Batch 鎵€鏈夊啓鎿嶄綔鍧囬渶瑕佸疄鐜?ItemWriter 鎺ュ彛銆傝鎺ュ彛鍙湁涓€涓柟娉?void write(List<? extends T> items)锛屽弬鏁版槸杈撳嚭缁撴灉鐨勫垪琛ㄣ€備箣鎵€浠ュ姝ゅ畾涔夛紝鏄负浜嗕究浜庢垜浠繘琛屾壒閲忔搷浣滐紝浠ユ彁楂樻€ц兘銆傛瘡娆′紶鍏ョ殑鍒楄〃鐢变簨鍔℃彁浜ょ矑搴︾‘瀹氾紝涔熷氨鏄 Spring Batch 姣忔灏嗘彁浜ょ殑缁撴灉闆嗕紶鍏ュ啓鎿嶄綔鎺ュ彛銆傚洜涓烘垜浠鍋氱殑浠呬粎鏄皢缂磋垂閫氱煡杈撳嚭鍒版帶鍒跺彴锛屾墍浠ワ紝鍐欐搷浣滃疄鐜板 娓呭崟 6 鎵€绀猴細

娓呭崟 6. MessagesItemWriter 绫?/h5>
package org.springframework.batch.sample;

import java.util.List;
import org.springframework.batch.item.ItemWriter;

public class MessagesItemWriter implements ItemWriter<Message>{
	public void write(List<? extends Message> messages) throws Exception {
		System.out.println("write results");
		for (Message m : messages) {
			System.out.println(m.getContent());
		}
	}
}

鍚?ItemReader 涓€鏍凤紝Spring Batch 涔熶负鎴戜滑鎻愪緵浜嗗鏍风殑鍐欐搷浣滄敮鎸侊紝鍏蜂綋鍙槄璇?Spring Batch 鍙傝€冩墜鍐岋紝姝ゅ涓嶅啀璧樿堪銆?/p>

鏈€鍚庯紝鍐嶇湅涓€涓嬪浣曞疄鐜颁笟鍔″鐞嗐€係pring Batch 鎻愪緵浜?ItemProcessor 鎺ュ彛鐢ㄤ簬瀹屾垚鐩稿簲涓氬姟澶勭悊銆傚湪鏈ず渚嬩腑锛屽嵆涓烘牴鎹敤鎴蜂俊鎭敓鎴愪竴鏉$即璐归€氱煡淇℃伅锛屽 娓呭崟 7 鎵€绀猴細

娓呭崟 7. MessagesItemProcessor 绫?/h5>
package org.springframework.batch.sample;

import org.springframework.batch.item.ItemProcessor;

public class MessagesItemProcessor implements ItemProcessor<User, Message> {

	public Message process(User user) throws Exception {
		Message m = new Message();
		m.setContent("Hello " + user.getName()
				+ ",please pay promptly at the end of this month.");
		return m;
	}

}

浠诲姟瀹氫箟

閫氳繃涓婇潰涓€鑺傦紝鎴戜滑宸茬粡瀹屾垚浜嗘壒澶勭悊浠诲姟鐨勮鏁版嵁銆佸鐞嗚繃绋嬨€佸啓鏁版嵁涓変釜杩囩▼銆傞偅涔堬紝鎴戜滑濡備綍灏嗚繖涓夐儴鍒嗙粨鍚堝湪涓€璧峰畬鎴愭壒澶勭悊浠诲姟鍛紵

Spring Batch 灏嗘壒澶勭悊浠诲姟绉颁负涓€涓?Job锛屽悓鏃讹紝Job 涓嬪垎涓哄涓?Step銆係tep 鏄竴涓嫭绔嬬殑銆侀『搴忕殑澶勭悊姝ラ锛屽寘鍚姝ラ鎵瑰鐞嗕腑闇€瑕佺殑鎵€鏈変俊鎭€傚涓壒澶勭悊 Step 鎸夌収涓€瀹氱殑娴佺▼缁勬垚涓€涓?Job銆傞€氳繃杩欐牱鐨勮璁℃柟寮忥紝鎴戜滑鍙互鐏垫椿閰嶇疆 Job 鐨勫鐞嗚繃绋嬨€?/p>

鎺ヤ笅鏉ワ紝璁╂垜浠湅涓€涓嬪浣曢厤缃即璐归€氱煡鐨?Job锛屽 娓呭崟 8 鎵€绀猴細

娓呭崟 8. message_job.xml
<job id="messageJob">
  <step id="messageStep">
	<tasklet>
	   <chunk reader="messageReader" processor="messageProcessor" 
	       writer="messageWriter" commit-interval="5" 
	       chunk-completion-policy="">
		</chunk>
	</tasklet>
   </step>
</job>

濡備笂锛屾垜浠畾涔変簡涓€涓悕涓衡€渕essageJob鈥濈殑 Job锛岃 Job 浠呭寘鍚竴涓?Step銆傚湪閰嶇疆 Step 鐨勮繃绋嬩腑锛屾垜浠笉浠呰鎸囧畾璇绘暟鎹€佸鐞嗐€佸啓鏁版嵁鐩稿叧鐨?bean锛岃繕瑕佹寚瀹?commit-interval 鍜?chunk-completion-policy 灞炴€с€傚墠鑰呮寚瀹氫簡璇?Step 涓簨鍔℃彁浜ょ殑绮掑害锛屽彇鍊间负 5 鍗宠〃鏄庢瘡褰撳鐞嗗畬姣曡鍏ョ殑 5 鏉℃暟鎹椂锛屾彁浜や竴娆′簨鍔°€傚悗鑰呮寚瀹氫簡 Step 鐨勫畬鎴愮瓥鐣ワ紝鍗冲綋浠€涔堟儏鍐靛彂鐢熸椂琛ㄦ槑璇?Step 宸茬粡瀹屾垚锛屽彲浠ヨ浆鍏ュ悗缁鐞嗐€傜敱浜庢病鏈夋槑纭寚瀹氱浉搴旂殑绫伙紝Spring Batch 浣跨敤榛樿绛栫暐锛屽嵆褰撹鍏ユ暟鎹负绌烘椂璁や负 Step 缁撴潫銆?/p>

鏈€鍚庯紝鎴戜滑杩橀渶瑕侀厤缃竴涓?JobRepository 骞朵负鍏舵寚瀹氫竴涓簨鍔$鐞嗗櫒锛岃绫荤敤浜庡 Job 杩涜绠$悊锛屽 娓呭崟 9 鎵€绀猴細

娓呭崟 9. message_job.xml
<beans:bean id="jobRepository"
class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
		<beans:property name="transactionManager" ref="transactionManager" />
</beans:bean>

<beans:bean id="transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>

鍥犱负鎴戜滑鏁翠釜绀轰緥涓嶉渶瑕佹暟鎹簱鎿嶄綔锛屾墍浠ラ€夋嫨浜嗕娇鐢?MapJobRepositoryFactoryBean 鍜?ResourcelessTransactionManager銆?/p>

鎵€鏈夐厤缃畬鎴愪互鍚庯紝杩涘叆鏈€鍚庝竴姝モ€斺€斾换鍔℃墽琛屻€?/p>

浠诲姟鎵ц

閭d箞濡備綍杩愯涓€涓?Job 鍛紵 Spring Batch 鎻愪緵浜?JobLauncher 鎺ュ彛鐢ㄤ簬杩愯 Job锛屽苟鎻愪緵浜嗕竴涓粯璁ゅ疄鐜?SimpleJobLauncher銆傚厛璁╂垜浠湅涓€涓嬪叿浣撴墽琛屼唬鐮侊紝濡?娓呭崟 10 鎵€绀猴細

娓呭崟 10. Main 绫?/h5>
 public class Main {
	public static void main(String[] args) {
        ClassPathXmlApplicationContext c = 
                 new ClassPathXmlApplicationContext("message_job.xml");
        SimpleJobLauncher launcher = new SimpleJobLauncher();
        launcher.setJobRepository((JobRepository) c.getBean("jobRepository"));
        launcher.setTaskExecutor(new SimpleAsyncTaskExecutor());
        try {
             launcher.run((Job) c.getBean("messageJob"), new JobParameters());
        } catch (Exception e) {
        e.printStackTrace();
        }
	}
}

棣栧厛锛屾垜浠渶瑕佷负 JobLauncher 鎸囧畾涓€涓?JobRepository锛岃绫昏礋璐e垱寤轰竴涓?JobExecution 瀵硅薄鏉ユ墽琛?Job锛屾澶勭洿鎺ヤ粠涓婁笅鏂囪幏鍙栧嵆鍙€傚叾娆★紝闇€瑕佹寚瀹氫竴涓换鍔℃墽琛屽櫒锛屾垜浠娇鐢?Spring Batch 鎻愪緵鐨?SimpleAsyncTaskExecutor銆傛渶鍚庯紝閫氳繃 run 鏂规硶鏉ユ墽琛屾寚瀹氱殑 Job锛岃鏂规硶鍖呭惈涓や釜鍙傛暟锛岄渶瑕佹墽琛岀殑 Job 浠ュ強鎵ц鍙傛暟銆傛偍鍙互閫氳繃杩愯绀轰緥宸ョ▼鏌ョ湅杩愯缁撴灉銆傜敱浜?MessageItemWriter 鍦ㄦ瘡娆¤緭鍑虹粨鏋滃墠锛屽厛鎵撳嵃浜嗕竴琛屾彁绀猴紝鍥犳鎮ㄥ彲浠ユ槑鏄剧湅鍑鸿緭鍑哄垎 2 缁勮繘琛屾墦鍗帮紝鍗充簨鍔¤鎻愪氦浜?2 娆★紙鍥犱负鎴戜滑璁剧疆鐨勪簨鍔$矑搴︿负 5銆傦級銆?/p>

浠庝笟鍔″姛鑳戒笂鑰冭檻锛屽悓涓€浠诲姟搴旇灏介噺閬垮厤閲嶅鎵ц锛堝嵆鐩稿悓鏉′欢涓嬬殑浠诲姟鍙兘鎴愬姛杩愯涓€娆★級锛岃瘯鎯冲鏋滄湰绀轰緥涓彂閫佺即璐归€氱煡杩囧鍙兘瀵艰嚧鐢ㄦ埛涓嶆弧锛岄偅涔堢數淇¤璐规壒澶勭悊浠诲姟閲嶅鎵ц鍒欏皢瀵艰嚧閲嶅璁¤垂锛屼粠鑰屼娇鐢ㄦ埛閬彈鎹熷け銆傚垢杩愮殑鏄紝Spring Batch 宸茬粡涓烘垜浠€冭檻濂戒簡杩欎簺銆?/p>

瀵逛簬 Spring Batch 鏉ヨ锛孞obParameters 鐩稿悓鐨勪换鍔″彧鑳芥垚鍔熻繍琛屼竴娆°€傛偍濡傛灉鍦ㄧず渚?Main 绫讳腑杩炵画杩愯鍚屼竴 Job锛屽皢浼氬緱鍒板涓嬪紓甯革紙瑙?娓呭崟 11 锛夛細

娓呭崟 11. 寮傚父淇℃伅
org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: 
A job instance already exists and is complete for parameters={}.  
If you want to run this job again, change the parameters.

鍥犳锛屽鏋滄垜浠笇鏈涜浠诲姟鏄懆鏈熸墽琛岀殑锛堝姣忔湀鎵ц涓€娆★級锛岄偅涔堝繀椤讳繚璇佸懆鏈熷唴鍙傛暟鏄敮涓€銆傚亣濡傝瀹㈡埛瑕佹眰鎴戜滑姣忔湀涓虹敤鎴峰彂閫佷竴娆$即璐归€氱煡銆傛垜浠殑浠诲姟鎵ц鍙互濡?娓呭崟 12 鎵€绀猴細

娓呭崟 12. Main 绫?/h5>
Map<String,JobParameter> parameters = new HashMap<String,JobParameter>();
parameters.put(RUN_MONTH_KEY,new JobParameter("2011-10"));
launcher.run((Job) c.getBean("messageJob"),new JobParameters(parameters));
parameters.put(RUN_MONTH_KEY,new JobParameter("2011-11"));
launcher.run((Job) c.getBean("messageJob"),new JobParameters(parameters));

鍦ㄧず渚嬩腑锛屾垜灏嗘墽琛屾湀浠戒綔涓?Job 鐨勫弬鏁颁紶鍏ワ紝鍒嗗埆鎵ц浜?10銆?1 鏈堜袱涓湀鐨勪换鍔°€?/p>

浠诲姟閲嶈瘯

鏃㈢劧鐩稿悓鍙傛暟鐨勪换鍔″彧鑳芥垚鍔熸墽琛屼竴娆★紝閭d箞锛屽鏋滀换鍔″け璐ヨ濡備綍澶勭悊锛熸鏃讹紝闇€瑕佽€冭檻鐨勬槸锛屾棦鐒朵换鍔℃楠ゆ湁浜嬪姟鎻愪氦绮掑害锛岄偅涔堝彲鑳戒换鍔″凡缁忔彁浜や簡閮ㄥ垎澶勭悊缁撴灉锛岃繖閮ㄥ垎涓嶅簲璇ヨ閲嶅澶勭悊銆備篃灏辨槸璇达紝姝ゆ椂搴旇鏈夐噸璇曟搷浣溿€?/p>

鍦?Spring Batch 涓紝閫氳繃閰嶇疆鍙互瀹炵幇姝ラ Step 鐨勯噸璇曪紝濡?娓呭崟 13 鎵€绀猴細

娓呭崟 13. message_job.xml
 <job id="messageJob" restartable="true">
	<step id="messageStep">
		<tasklet>
			<chunk reader="messageReader" processor="messageProcessor" 
			                                       writer="messageWriter"
                commit-interval="5" chunk-completion-policy="" retry-limit="2">
				<retryable-exception-classes>
					<include class="java.lang.RuntimeException" />
				</retryable-exception-classes>
			</chunk>
		</tasklet>
	</step>
</job>

鎴戜滑鍙互鐪嬪埌锛屼富瑕佸垎涓ら儴鍒嗭細棣栧厛锛岄渶瑕佽缃噸璇曟鏁帮紝鍏舵鏄綋鎵ц杩囩▼涓崟鑾峰埌鍝簺寮傚父鏃堕渶瑕侀噸璇曘€傚鏋滃湪鎵ц杩囩▼涓崟鑾峰埌閲嶈瘯寮傚父鍒楄〃涓殑寮傚父淇℃伅锛屽垯杩涜閲嶈瘯鎿嶄綔銆傚鏋滈噸璇曟搷浣滆揪鍒版渶澶ф鏁颁粛鎻愮ず寮傚父锛屽垯璁や负浠诲姟鎵ц澶辫触銆傚浜庡紓甯镐俊鎭殑閰嶇疆锛岄櫎浜嗛€氳繃 include 閰嶇疆鍖呭惈鍒楄〃澶栵紝涔熷彲浠ラ€氳繃 exclude 閰嶇疆鎺掗櫎鍒楄〃銆?/p>

鐢变簬閫氳繃閰嶇疆杩涜鐨?Step 閲嶈瘯鏄嚜鍔ㄧ殑锛屽洜姝よ緝闅炬帶鍒讹紙澶氱敤浜庣綉缁滆闂紓甯哥瓑涓嶉渶瑕佷汉宸ュ共棰勭殑鎯呭喌锛夈€傚彲浠ヨ€冭檻涓€涓嬫湰绀轰緥锛屽鏋滄湁涓€涓敤鎴风殑淇℃伅鏈夐棶棰橈紝鍚嶅瓧涓虹┖锛屼笉鑳藉彂閫佺即璐归€氱煡锛屾楠ら噸璇曚究涓嶅悎閫備簡锛屾鏃舵垜浠彲浠ュ Job 杩涜閲嶈瘯鎿嶄綔銆?/p>

Spring Batch 鍏佽閲嶅鎵ц鏈垚鍔熺殑 Job锛岃€屾瘡娆℃墽琛屽嵆涓轰竴娆¢噸璇曟搷浣溿€傜ず渚嬩唬鐮佸 娓呭崟 14 鎵€绀猴細

娓呭崟 14. Main 绫?/h5>
 Map<String,JobParameter> parameters = new HashMap<String,JobParameter>(); 
 parameters.put(RUN_MONTH_KEY,new JobParameter("2011-10")); 
 launcher.run((Job) c.getBean("messageJob"),new JobParameters(parameters)); 
 Thread.sleep(10000); 
 launcher.run((Job) c.getBean("messageJob"),new JobParameters(parameters));

鎮ㄥ彲浠ラ€氳繃濡備笅姝ラ鏌ョ湅杩愯缁撴灉锛氶鍏堬紝灏?users.txt 鏂囦欢涓殑绗?7 琛岋紙涔嬫墍浠ユ寚瀹氳琛岋紝渚夸簬楠岃瘉浜嬪姟鎻愪氦浠ュ強閲嶅鎵ц鐨勮捣濮嬩綅缃級鐨勭敤鎴峰悕淇敼涓虹┖銆傚叾娆★紝杩愯绀轰緥銆傛渶鍚庯紝鍦ㄧ▼搴忓嚭鐜板紓甯告彁绀烘椂锛屾洿鏂扮 7 琛岀殑鐢ㄦ埛鍚嶏紙涓轰簡渚夸簬婕旂ず锛岀▼搴忓湪涓ゆ浠诲姟鎵ц杩囩▼涓瓑寰?10 绉掗挓锛夈€?/p>

鎮ㄥ彲浠ュ湪鎺у埗鍙颁腑寰堟槑鏄剧殑鐪嬪埌锛屼换鍔″厛鎵撳嵃浜?5 鏉¤褰曪紙绗竴娆′簨鍔℃彁浜わ級锛岀劧鍚庡嚭鐜板紓甯镐俊鎭紝寰呮垜浠皢閿欒鏇存鍚庯紝鍙堟墦鍗颁簡 5 鏉¤褰曪紝浠诲姟鏈€缁堟垚鍔熷畬鎴愩€?/p>

浠庤緭鍑虹粨鏋滐紝鎴戜滑鍙互鐭ラ亾 Spring Batch 鏄粠鍑洪敊鐨勪簨鍔¤竟鐣屽唴绗竴鏉¤褰曢噸澶嶆墽琛岀殑锛岃繖鏍蜂究纭繚浜嗘暟鎹畬鏁存€э紝鑰屼笖鎵€鏈夎繖涓€鍒囧浜庣敤鎴峰潎鏄€忔槑鐨勩€?/p>

閭d箞 Spring Batch 鏄浣曞仛鍒拌繖涓€姝ョ殑鍛紵杩欎笌 Spring Batch 鐨勮繍琛屾椂绠$悊鏄垎涓嶅紑鐨勩€?/p>

杩愯鏃剁鐞?/h2>

Spring Batch 鎻愪緵浜嗗 琛?1 鎵€绀虹殑绫荤敤浜庤褰曟瘡涓?Job 鐨勮繍琛屼俊鎭細

琛?1. 杩愯鏃剁被淇℃伅
绫诲悕 鎻忚堪
JobInstance 璇ョ被璁板綍浜?Job 鐨勮繍琛屽疄渚嬨€備妇渚嬶細10 鏈堝拰 11 鏈堝垎鍒墽琛屽悓涓€ Job锛屽皢鐢熸垚涓や釜 JobInstance銆備富瑕佷俊鎭湁锛氭爣璇嗐€佺増鏈€丣ob 鍚嶇О銆丣ob 鍙傛暟
JobExecution 璇ョ被璁板綍浜?Job 鐨勮繍琛岃褰曘€傚涓婇潰鐨勭ず渚嬶紝Job 绗竴娆¤繍琛屽け璐ワ紝绗簩娆¤繍琛屾垚鍔燂紝閭d箞灏嗗舰鎴愪袱鏉¤繍琛岃褰曪紝浣嗘槸瀵瑰簲鐨勬槸鍚屼竴涓繍琛屽疄渚嬨€備富瑕佷俊鎭湁锛欽ob 鐨勮繍琛屾椂闂淬€佽繍琛岀姸鎬佺瓑銆?/td>
JobParameters 璇ョ被璁板綍浜?Job 鐨勮繍琛屽弬鏁?/td>
ExecutionContext 璇ョ被涓昏鐢ㄤ簬寮€鍙戜汉鍛樺瓨鍌ㄤ换鍔¤繍琛岃繃绋嬩腑鐨勭浉鍏充俊鎭紙浠ラ敭鍊煎褰㈠紡锛夛紝涓昏鍒嗕负 Job 鍜?Step 涓や釜鑼冨洿
StepExecution 璇ョ被涓?JobExecution 绫讳技锛屼富瑕佽褰曚簡 Step 鐨勮繍琛岃褰曘€傚寘鎷娆¤繍琛岃鍙栬褰曟潯鏁般€佽緭鍑鸿褰曟潯鏁般€佹彁浜ゆ鏁般€佸洖婊氭鏁般€佽璺宠繃鏉℃暟銆佸鐞嗚烦杩囨潯鏁般€佸啓璺宠繃鏉℃暟绛変俊鎭?/td>

Spring Batch 閫氳繃 JobRepository 鎺ュ彛缁存姢鎵€鏈?Job 鐨勮繍琛屼俊鎭紝姝ゅ JobLauncher 鐨?run 鏂规硶涔熻繑鍥炰竴涓?JobExecution 瀵硅薄锛岄€氳繃璇ュ璞″彲浠ユ柟渚跨殑鑾峰緱 Job 鍏朵粬鐨勮繍琛屼俊鎭紝浠g爜濡?娓呭崟 15 鎵€绀猴細

娓呭崟 15. Main 绫?/h5>
 Map<String,JobParameter> parameters = new HashMap<String,JobParameter>(); 
 parameters.put(RUN_MONTH_KEY,new JobParameter("2011-10")); 
 JobExecution je = 
        launcher.run((Job) c.getBean("messageJob"),new JobParameters(parameters)); 
 System.out.println(je); 
 System.out.println(je.getJobInstance()); 
 System.out.println(je.getStepExecutions());

杈撳嚭淇℃伅濡?娓呭崟 16 鎵€绀猴細

娓呭崟 16. 杈撳嚭缁撴灉
JobExecution: id=0, version=2, startTime=Tue Nov 15 21:00:09 CST 2011, 
endTime=Tue Nov 15 21:00:09 CST 2011, lastUpdated=Tue Nov 15 21:00:09 CST 2011, 
status=COMPLETED, exitStatus=exitCode=COMPLETED;exitDescription=, 
job=[JobInstance: id=0, version=0, JobParameters=[{run.month=2011-10}], Job=[messageJob]]

 JobInstance: id=0, version=0, JobParameters=[{run.month=2011-10}], Job=[messageJob] 

 [StepExecution: id=1, version=5, name=messageStep, status=COMPLETED, 
 exitStatus=COMPLETED, readCount=10, filterCount=0, writeCount=10 readSkipCount=0,
  writeSkipCount=0, processSkipCount=0, commitCount=3 , rollbackCount=0, 
  exitDescription=]

浠庢棩蹇楁偍鍙互鍙戠幇浜嬪姟涓€鍏辨彁浜や簡 3 娆★紝杩欎笌鍓嶉潰鐨勮鏄庢槸涓嶄竴鑷寸殑銆備箣鎵€浠ヤ細濡傛鏄洜涓哄綋浜嬪姟鎻愪氦绮掑害鎭板ソ鍙互琚褰曟暟鏁撮櫎鏃讹紝浜嬪姟浼氭湁涓€娆$┖鎻愪氦銆?/p>

鍏充簬 Spring Batch 杩愯鏃朵俊鎭鐞嗭紝灏嗗湪璁茶В Job 鐩戞帶鏃跺啀璇︾粏浠嬬粛锛屾澶勪笉鍐嶈禈杩帮紝浣犱篃鍙互鏌ョ湅 Spring Batch 鍙傝€冭祫鏂欎簡瑙g浉鍏充俊鎭€?/p>

鎬荤粨

鏈枃閫氳繃涓€涓畝鍗曠ず渚嬫紨绀轰簡濡備綍鏋勫缓 Spring Batch 搴旂敤锛屽悓鏃朵粙缁嶄簡 Spring Batch 鐨勭浉鍏虫牳蹇冩蹇点€傚笇鏈涙偍閫氳繃鏈枃鍙互鎺屾彙 Spring Batch 鐨勫熀鏈姛鑳姐€傚湪鎺ヤ笅鏉ョ殑鏂囩珷涓紝鎴戝皢缁х画浠嬬粛 Spring Batch 鐨勪袱涓噸瑕佺壒鎬э細Job 娴佸拰骞跺彂銆?/p>

浣跨敤 Spring Batch 鏋勫缓浼佷笟绾ф壒澶勭悊搴旂敤: 绗?2 閮ㄥ垎

鍦ㄦ湰绯诲垪鏂囩珷鐨劼?a style="margin: 15px 0px 0px; padding: 0px; border: 0px; font-size: 1em; vertical-align: baseline; color: #745285; font-family: Arial, sans-serif; display: inline; text-decoration: underline;" href="http://www.ibm.com/developerworks/cn/java/j-lo-springbatch1/">绗?1 閮ㄥ垎聽涓紝涓昏璁茶В浜嗗浣曚竴姝ユ鎼缓 Spring Batch 鎵瑰鐞嗗簲鐢紝鏈枃浣滀负绗?2 閮ㄥ垎锛屼富瑕佷粙缁嶄簡 Spring Batch 鐨?Step Flow 浠ュ強骞跺彂澶勭悊涓ら」閲嶈鐗规€с€?/p>

鍒?鍏夌憺, 杞欢鏋舵瀯甯? 鍥涜揪杞欢

2012 骞?8 鏈?02 鏃?/p>

  • Spring Batch 鏋勫徐浼佷笟绾ф壒澶勭悊搴旂敤鍐呭

鍓嶈█

鍦ㄦ湰绯诲垪鏂囩珷鐨勭 1 閮ㄥ垎锛屾垜浠惌寤轰簡涓€涓敤鎴风即璐归€氱煡鐨勬壒澶勭悊浠诲姟銆傚敖绠¤繖涓畝鍗曠殑搴旂敤灞曠幇浜?Spring Batch 鐨勫熀鏈姛鑳斤紝浣嗘槸瀹冧笌鐪熷疄鐨勫簲鐢ㄧ浉鍘荤敋杩溿€傚湪瀹為檯搴旂敤涓紝鎴戜滑鐨?Job 鍙兘蹇呴』瑕佸寘鍚涓?Step锛屼负浜嗘彁楂樻€ц兘锛屾垜浠彲鑳介渶瑕佽€冭檻 Job 鐨勫苟鍙戦棶棰樸€係pring Batch 鍦ㄨ繖浜涙柟闈㈠張鎻愪緵浜嗗摢浜涘ソ鐨勭壒鎬у憿锛熻鎴戜滑缁х画銆?/p>

Step Flow

閫氳繃鍓嶆枃鎴戜滑宸茬粡鐭ラ亾锛孲tep 鏄竴涓嫭绔嬬殑銆侀『搴忕殑澶勭悊姝ラ锛屽寘鍚畬鏁寸殑杈撳叆銆佸鐞嗕互鍙婅緭鍑恒€備絾鏄湪浼佷笟搴旂敤涓紝鎴戜滑闈㈠鐨勬洿澶氭儏鍐垫槸澶氫釜姝ラ鎸夌収涓€瀹氱殑椤哄簭杩涜澶勭悊銆傚洜姝ゅ浣曠淮鎶ゆ楠や箣闂寸殑鎵ц椤哄簭鏄垜浠渶瑕佽€冭檻鐨勩€係pring Batch 鎻愪緵浜?Step Flow 鏉ヨВ鍐宠繖涓棶棰樸€?/p>

绀轰緥鏀硅繘

璁╂垜浠洖鍒扮敤鎴风即璐归€氱煡鐨?Job銆傚鎴锋彁鍑轰簡杩涗竴姝ョ殑闇€姹傦細璁¤垂銆佹墸璐广€佺即璐归€氱煡瑕佺‘淇濋『搴忔墽琛屻€傞鍏堬紝涓烘瘡涓敤鎴风敓鎴愯处鍗曪紝鐒跺悗浠庣敤鎴蜂綑棰濅笂杩涜鎵i櫎锛屽浜庝綑棰濅笉瓒崇殑鐢ㄦ埛锛屽彂閫佺即璐归€氱煡銆備笅闈㈢湅涓€涓嬪浣曚娇鐢?Step Flow 瀹炵幇璇ラ渶姹傘€?/p>

鍦ㄨ瑙?Step Flow 涔嬪墠锛屾垜浠厛瀵圭 1 閮ㄥ垎鐨勭ず渚嬭繘琛屾敼杩涳紝灏嗗叾鐢辨枃浠舵搷浣滆縼绉诲埌鏁版嵁搴撲笂锛岃繖鏍蜂究浜庢垜浠悗缁殑璁茶В銆傛暟鎹簱鍒濆鍖栬剼鏈 init_db_mysql.sql锛堜綅浜庣ず渚嬩唬鐮佸寘 batch_sample 鏍圭洰褰曚笅锛夛紝鍏蜂綋閰嶇疆濡傛竻鍗?1 鎵€绀猴細

娓呭崟 1. billing_job.xml
<beans:bean id="jobRepository"
   class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
   <beans:property name="dataSource" ref="dataSource" />
   <beans:property name="transactionManager" ref="transactionManager" />
</beans:bean>
<beans:bean id="userDbReader"
	class="org.springframework.batch.item.database.JdbcPagingItemReader">
	<beans:property name="dataSource" ref="dataSource" />
	<beans:property name="rowMapper" ref="userDbMapper" />
	<beans:property name="queryProvider" ref="userQueryProvider" />
</beans:bean>
<beans:bean id="userDbMapper"
	class="org.springframework.batch.sample.UserDbMapper" />
<beans:bean id="userQueryProvider"
	class="org.springframework.batch.item.database.support.MySqlPagingQueryProvider">
	<beans:property name="selectClause" value="u.id,u.name,u.age,u.balance" />
	<beans:property name="fromClause" value="users u" />
	<beans:property name="sortKey" value="u.id" />
</beans:bean>
<beans:bean id="messageDbWriter"
	class="org.springframework.batch.item.database.JdbcBatchItemWriter">
	<beans:property name="dataSource" ref="dataSource" />
	<beans:property name="sql"
    value="insert into messages(id,user_id,content) values(:id,:user.id,:content)" />
	<beans:property name="itemSqlParameterSourceProvider"
		ref="itemSqlParameterSourceProvider" />
</beans:bean>
<beans:bean id="itemSqlParameterSourceProvider"
class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider"
 />

鎴戜滑鍒嗗埆浣跨敤 Spring Batch 鎻愪緵鐨?JdbcPagingItemReader 鍜?JdbcBatchItemWriter 杩涜璇诲啓銆傚悓鏃讹紝鎴戝皢 jobRepository 淇敼涓?JobRepositoryFactoryBean锛屽洜姝わ紝杩愯绀轰緥鍓嶏紝鎮ㄨ繕闇€瑕佹墽琛?Spring Batch 鎻愪緵鐨?schema-mysql.sql锛堜綅浜?core 鍖?org\springframework\batch\core 鐩綍涓嬶級銆傜浉鍏冲唴瀹瑰皢鍦ㄧ 3 閮ㄥ垎璇︾粏璁茶В锛屾澶勪笉鍐嶈禈杩般€?/p>

绗竴涓祦绋?/h3>

鍦ㄩ厤缃?Step 鏃讹紝鎴戜滑鍙互鎸囧畾鍏?next 灞炴€э紝璇ュ睘鎬ф寚鍚戝彟涓€涓?Step銆傞€氳繃閰嶇疆 Step 鐨?next 灞炴€э紝鎴戜滑渚垮彲浠ヨ交鏄撳疄鐜颁笂杩版祦绋嬨€傚叿浣撳娓呭崟 2 鎵€绀?/p>

娓呭崟 2. billing_job.xml
<job id="billingJob" restartable="true">
	<step id="billingStep" next="payStep">
		<tasklet>
			<chunk reader="userDbReader" processor="billingProcessor"
             writer="billDbWriter" commit-interval="5" chunk-completion-policy="">
			</chunk>
		</tasklet>
	</step>
	<step id="payStep" next="messageStep">
		<tasklet>
          <chunk reader="billDbReader" processor="payProcessor" writer="payDbWriter" 
			commit-interval="5" chunk-completion-policy=""  skip-limit="100" >
<skippable-exception-classes>
      <include class="org.springframework.batch.sample.MoneyNotEnoughException" />
				</skippable-exception-classes>
			</chunk>
		</tasklet>
	</step>
	<step id="messageStep">
		<tasklet>
			<chunk reader="billArrearsDbReader" processor="messageProcessor"
					writer="messageDbWriter" commit-interval="5"
					chunk-completion-policy="">
			</chunk>
		</tasklet>
	</step>
</job>

鎴戜滑灏?billStep 鐨?next 璁剧疆涓?payStep锛屽皢 payStep 鐨?next 璁剧疆涓?messageStep锛屽悓鏃跺垎鍒寚瀹氫簡璇汇€佸鐞嗐€佸啓鎺ュ彛銆係pring Batch 鍦ㄨ繍琛?billingJob 鏃讹紝棣栧厛鎵ц billingStep锛屾煡鎵剧敤鎴蜂俊鎭敓鎴愯处鍗曡垂鐢紝鐒跺悗鎵ц payStep锛屾煡鎵捐处鍗曚俊鎭敓鎴愭墸璐硅褰曪紝濡傛灉鐢ㄦ埛浣欓涓嶈冻鍒欒烦杩囥€傛渶鍚庯紝鏌ユ壘娆犺垂璐﹀崟锛岀敓鎴愮即璐归€氱煡銆傚彧鏈夊綋涓婁竴姝ユ墽琛屾垚鍔熷悗锛屾墠浼氭墽琛屼笅涓€姝ャ€?/p>

billStep 鍜?payStep 鐨?ItemProcessor 瀹炵幇鍒嗗埆濡傛竻鍗?3 鍜屾竻鍗?4 鎵€绀猴細

娓呭崟 3.BillingItemProcessor 绫?/h5>
public class BillingItemProcessor implements ItemProcessor#<User, Bill> {

	public Bill process(User item) throws Exception {
		Bill b = new Bill();
		b.setUser(item);
		b.setFees(70.00);
		b.setPaidFees(0.0);
		b.setUnpaidFees(70.00);
		b.setPayStatus(0);/*unpaid*/
		return b;
	}

}
娓呭崟 4.PaymentItemProcessor 绫?/h5>
 public class PaymentItemProcessor implements ItemProcessor<Bill, PayRecord> { 
 public PayRecord process(Bill item) throws Exception {
		if (item.getUser().getBalance() <= 0) {
			return null;
		}
		if (item.getUser().getBalance() >= item.getUnpaidFees()) {
			// create payrecord
			PayRecord pr = new PayRecord();
			pr.setBill(item);
			pr.setPaidFees(item.getUnpaidFees());
			// update balance
			item.getUser().setBalance(item.getUser().getBalance() - 
			     item.getUnpaidFees());
			// update bill
			item.setPaidFees(item.getUnpaidFees());
			item.setUnpaidFees(0.0);
			item.setPayStatus(1);/* paid */
			return pr;
		} else {
			throw new MoneyNotEnoughException();
		}
	}
}

鍦ㄦ竻鍗?3 涓紝鎴戜滑涓烘瘡涓敤鎴风敓鎴愪竴鏉?70 鍏冪殑璐﹀崟锛屽凡缂磋垂鐢ㄤ负 0锛屾湭缂磋垂鐢ㄤ负 70銆傚湪娓呭崟 4 涓紝灏嗚处鍗曢噾棰濅粠鐢ㄦ埛浣欓涓墸闄わ紝骞舵洿鏂拌处鍗曞凡缂村拰鏈即璐圭敤锛屽鏋滀綑棰濅笉瓒筹紝鎻愮ず寮傚父锛堥€氳繃娓呭崟 2 鍙煡锛屾垜浠浜庢绫诲紓甯歌繘琛屼簡璺宠繃澶勭悊锛夈€?/p>

姝ゅ锛屾垜浠幇鍦ㄧ殑缂磋垂閫氱煡闇€瑕佸熀浜庢瑺璐硅处鍗曠敓鎴愶紝鍥犳锛屾垜浠渶瑕佹柊鎻愪緵涓€涓即璐归€氱煡鐨?ItemProcessor锛屽叿浣撳娓呭崟 5 鎵€绀猴細

娓呭崟 5.ArrearsMessagesItemProcessor 绫?/h5>
public class ArrearsMessagesItemProcessor implements
		ItemProcessor<Bill, Message> {

	public Message process(Bill item) throws Exception {
		if (item.getPayStatus() == 0) {/*unpaid*/
			Message m = new Message();
			m.setUser(item.getUser());
			m.setContent("Hello " + item.getUser().getName()
					+ ",please pay promptly at end of this month.");
			return m;
		}
		return null;
	}

}

姣忎釜 Step 鐨勮鍐欐帴鍙e彲鍙傜収 billing_job.xml锛屽潎浣跨敤 Spring Batch 鎻愪緵鐨勫疄鐜扮被锛屾澶勪笉鍐嶈禈杩帮紙姝ゅ闇€瑕佺壒鍒敞鎰?payDbWriter锛岀敱浜庢墸璐规椂锛屾垜浠渶瑕佸悓鏃剁敓鎴愭墸璐硅褰曪紝骞舵洿鏂扮敤鎴峰拰璐﹀崟锛屽洜姝ゆ垜浠娇鐢ㄤ簡 CompositeItemWriter锛夈€傝嚦姝わ紝鎴戜滑宸茬粡瀹屾垚浜嗙涓€姝ワ紝瀹炵幇浜嗗熀鏈殑澶氭楠ら『搴忓鐞嗭紝鎮ㄥ彲浠ヨ繍琛?Main2锛屽苟閫氳繃鏁版嵁搴撴煡鐪嬭繍琛岀粨鏋滐紙bills銆乸ayrecords銆乵essages锛夈€?/p>

鏉′欢娴佺▼鍜屾祦绋嬪喅绛?/h3>

閫氳繃涓婇潰鐨?Step Flow锛屾垜浠凡缁忔弧瓒充簡瀹㈡埛鐨勫垵姝ラ渶姹傦紝浣嗘槸瀹㈡埛鍙堟彁鍑鸿繘涓€姝ヨ姹傦細鑳藉惁褰撴墍鏈夌敤鎴疯垂鐢ㄥ潎瓒冲鐨勬儏鍐典笅锛屼笉鍐嶆墽琛岀即璐归€氱煡澶勭悊銆傚洜涓烘煡璇竴閬嶆瑺璐硅处鍗曞湪涓€瀹氱▼搴︿笂杩樻槸闄嶄綆浜嗗鐞嗘€ц兘銆係pring Batch 鎻愪緵浜嗘潯浠舵祦绋嬪拰娴佺▼鍐崇瓥鏉ユ敮鎸佺被浼煎簲鐢ㄥ満鏅€?/p>

棣栧厛锛岃鎴戜滑鐪嬩竴涓嬪浣曚娇鐢ㄦ潯浠舵祦绋嬫潵瀹炵幇璇ラ渶姹傘€係tep 閫氳繃鍦?next 鍏冪礌涓婅缃?on 灞炴€ф潵鏀寔鏉′欢娴佺▼锛宱n 灞炴€у彇鍊间负 Step 鐨勭粨鏉熺姸鎬侊紝濡?COMPLETED銆丗AILED 绛夛紝鍚屾椂杩樻敮鎸?* 浠ュ強 ? 閫氶厤绗︼紝鍏蜂綋鍙槄璇宦?a style="margin: 0px; padding: 0px; border: 0px; font-size: inherit; vertical-align: baseline; color: #745285;" href="http://www.ibm.com/developerworks/cn/java/j-lo-springbatch2/#resources">鍙傝€冩墜鍐?/a>銆?/p>

鐢变簬鎴戜滑甯屾湜褰撳瓨鍦ㄤ綑棰濅笉瓒崇殑鎯呭喌鏃讹紝涔熷氨鏄?payStep 鐨勮烦杩囨潯鏁板ぇ浜?0 鏃讹紝鍐嶆墽琛岀即璐归€氱煡 Step锛屽洜姝わ紝鎴戜滑闇€瑕佺壒娈婃寚瀹氫竴绉嶇粨鏉熺姸鎬併€傛澶勶紝鎴戜滑鍙互涓?Step 娣诲姞涓€涓洃鍚櫒锛屼互杩斿洖鎸囧畾鐨勭粨鏉熺姸鎬併€?/p>

淇敼鍚庣殑 payStep 濡傛竻鍗?6 鎵€绀猴紝鐩戝惉鍣ㄥ疄鐜板娓呭崟 7 鎵€绀猴細

娓呭崟 6. billing_job.xml
<step id="payStep">
	<tasklet>
		<chunk reader="billDbReader" processor="payProcessor" writer="payDbWriter"
			commit-interval="5" chunk-completion-policy="" skip-limit="100">
			<skippable-exception-classes>
				<include
        class="org.springframework.batch.sample.MoneyNotEnoughException" />
			</skippable-exception-classes>
		</chunk>
	</tasklet>
<next on="COMPLETED WITH SKIPS" to="messageStep"/>
	<listeners>
		<listener ref="payStepCheckingListener"></listener>
	</listeners>
</step>
娓呭崟 7. PayStepCheckingListener 绫?/h5>
public class PayStepCheckingListener extends StepExecutionListenerSupport {

	@Override
	public ExitStatus afterStep(StepExecution stepExecution) {
		String exitCode = stepExecution.getExitStatus().getExitCode();
		if (!exitCode.equals(ExitStatus.FAILED.getExitCode())
				&& stepExecution.getSkipCount() > 0) {
			return new ExitStatus("COMPLETED WITH SKIPS");
		} else {
			return null;
		}
	}

}

鎺ヤ笅鏉ワ紝鍐嶈鎴戜滑鐪嬩竴涓嬪浣曚娇鐢ㄦ祦绋嬪喅绛栨潵瀹炵幇璇ュ姛鑳姐€傚鏁版儏鍐典笅锛孲tep 鐨勭粨鏉熺姸鎬佸苟涓嶈兘澶熸弧瓒宠緝涓哄鏉傜殑鏉′欢娴佺▼锛屾鏃朵究鐢ㄥ埌浜嗘祦绋嬪喅绛栧櫒銆傞€氳繃瀹冿紝鎴戜滑鍙互鏍规嵁 Job 鍜?Step 鐨勫悇绉嶆墽琛屾儏鍐佃繑鍥炵浉搴旂殑鎵ц鐘舵€佹潵鎺у埗娴佺▼銆?/p>

棣栧厛锛屾垜浠渶瑕佸畾涔変竴涓祦绋嬪喅绛栧櫒锛屼唬鐮佸娓呭崟 8 鎵€绀猴細

娓呭崟 8. MessagesDecider 绫?/h5>
public class MessagesDecider implements JobExecutionDecider {

	public FlowExecutionStatus decide(JobExecution jobExecution,
			StepExecution stepExecution) {
		String exitCode = stepExecution.getExitStatus().getExitCode();
		if (!exitCode.equals(ExitStatus.FAILED.getExitCode())
				&& stepExecution.getSkipCount() > 0) {
			return new FlowExecutionStatus("COMPLETED WITH SKIPS");
		} else {
			return FlowExecutionStatus.COMPLETED;
		}
	}

}

涓?StepExecutionListener 涓嶅悓锛岃绫荤殑 decide 鏂规硶杩斿洖涓€涓?FlowExecutionStatus 瀵硅薄銆備笌涔嬪搴旓紝Job 閰嶇疆淇敼涓哄娓呭崟 9 鎵€绀猴細

娓呭崟 9. billing_job2.xml
<job id="billingJob" restartable="true">
	<step id="billingStep" next="payStep">
	</step>
	<step id="payStep" next="decider">
	</step>
	<decision id="decider" decider="messagesDecider">
		<next on="COMPLETED WITH SKIPS" to="messageStep" />
		<end on="COMPLETED" />
	</decision>
	<step id="messageStep">
	</step>
</job>

鍙互鐪嬪埌 payStep 鐨?next 鍙樻垚浜?decider锛屽湪 decider 涓牴鎹繑鍥炵粨鏋滅‘瀹氭墽琛岃矾寰勶細濡傛灉瀛樺湪璺宠繃鐨勬儏鍐碉紝鎵ц messageStep锛屽惁鍒欑洿鎺ョ粨鏉?Job锛堟敞鎰忥細姝ゅ鎴戜滑鐢ㄥ埌浜?end 鍏冪礌锛夈€?/p>

閫氳繃涓婇潰鐨勮杩帮紝鎴戜滑澶т綋浜嗚В浜?Spring Batch 瀵逛簬鏉′欢娴佺▼鐨勬敮鎸侊紙姝ゅ锛屾垜浠彲浠ラ€氳繃璁剧疆 Step 鐨?next 灞炴€т负鍏堝墠鎵ц鐨?Step锛屼粠鑰屽疄鐜版敮鎸佸惊鐜殑 Job锛屼絾鏄瑪鑰呭苟涓嶈涓鸿繖鏄疄鐜板惊鐜换鍔$殑涓€涓ソ鏂规锛屾晠鍦ㄦ澶勪笉鍋氳缁嗚瑙o級锛屾帴涓嬫潵鍐嶈鎴戜滑鐪嬩竴涓嬫壒澶勭悊涓彟涓€椤归噸瑕佺壒寰佲€斺€斿苟鍙戙€?/p>

骞跺彂澶勭悊

濡傛灉鎴戜滑鐨勬壒澶勭悊浠诲姟瓒冲绠€鍗曪紝纭欢閰嶇疆鍙婄綉缁滅幆澧冧篃瓒冲濂斤紝閭d箞鎴戜滑瀹屽叏鍙互灏嗘壒澶勭悊浠诲姟璁捐涓哄崟绾跨▼锛屼絾鐜板疄鏄紒涓氬簲鐢ㄥ浜庣‖浠剁殑瑕佹眰瑕佹瘮纭欢鑷韩鍙戝睍蹇殑澶氾紝鏇翠綍鍐佃繕鏈夐偅涔堝鐨勪紒涓氳鍦ㄨ緝宸殑纭欢鐜涓繍琛岃嚜宸辩殑浼佷笟搴旂敤骞跺笇鏈涙嫢鏈変竴涓彲浠ユ帴鍙楃殑鎬ц兘銆傚洜姝ゅ湪浼佷笟搴旂敤涓紝灏ゅ叾鏄秹鍙婂埌澶ф壒閲忔暟鎹鐞嗭紝骞跺彂鏄笉鍙伩鍏嶇殑銆傞偅涔堬紝Spring Batch 鍦ㄥ苟鍙戞柟闈㈠張鎻愪緵浜嗗摢浜涘姛鑳芥敮鎸佸憿锛?/p>

棣栧厛锛孲pring Batch 鎻愪緵浜?Step 鍐呯殑骞跺彂锛岃繖涔熸槸鏈€绠€鍗曠殑涓€绉嶅苟鍙戝鐞嗘敮鎸併€傞€氳繃涓?Step 璁剧疆 task-executor 灞炴€э紝鎴戜滑渚垮彲浠ヤ娇褰撳墠 Step 浠ュ苟鍙戞柟寮忔墽琛屻€傚悓鏃讹紝杩樺彲浠ラ€氳繃 throttle-limit 璁剧疆骞跺彂绾跨▼鏁帮紙榛樿涓?4锛夈€備篃灏辨槸璇存偍涓嶅繀淇敼浠讳綍涓氬姟澶勭悊閫昏緫锛屼粎浠呴€氳繃淇敼閰嶇疆鍗冲彲浠ュ疄鐜板悓姝ュ埌寮傛鐨勫垏鎹€?/p>

濡傛灉鎴戜滑甯屾湜绀轰緥涓殑 billingStep 浠ュ苟鍙戞柟寮忔墽琛岋紝涓斿苟鍙戜换鍔℃暟涓?5锛岄偅涔堝彧闇€瑕佸仛濡備笅閰嶇疆鍗冲彲锛岃娓呭崟 10锛?/p>

娓呭崟 10. billing_job3.xml
<step id="billingStep" next="payStep">
	<tasklet task-executor="taskExecutor" throttle-limit="5">
		<chunk reader="userDbReader" processor="billingProcessor"
		writer="billDbWriter" commit-interval="5" chunk-completion-policy="">
		</chunk>
	</tasklet>
</step>
<beans:bean id="taskExecutor"
	class="org.springframework.core.task.SimpleAsyncTaskExecutor">
</beans:bean>

浠庢竻鍗曞彲浠ョ湅鍑猴紝鎴戜滑涓?billingStep 鎸囧畾浜嗕竴涓紓姝ヤ换鍔℃墽琛屽櫒 SimpleAsyncTaskExecutor锛岃鎵ц鍣ㄥ皢浼氭寜鐓ч厤缃垱寤烘寚瀹氭暟鐩殑绾跨▼鏉ヨ繘琛屾暟鎹鐞嗐€傞€氳繃杩欑鏂瑰紡锛岄伩鍏嶄簡鎴戜滑鎵嬪姩鍒涘缓骞剁鐞嗙嚎绋嬬殑宸ヤ綔锛屼娇鎴戜滑鍙渶瑕佸叧娉ㄤ笟鍔″鐞嗘湰韬€?/p>

闇€瑕佽ˉ鍏呰鏄庣殑鏄紝Spring Core 涓烘垜浠彁渚涗簡澶氱鎵ц鍣ㄥ疄鐜帮紙鍖呮嫭澶氱寮傛鎵ц鍣級锛屾垜浠彲浠ユ牴鎹疄闄呮儏鍐电伒娲婚€夋嫨浣跨敤銆傚綋鐒讹紝鍍忔垜浠澶勯渶瑕佸苟鍙戝鐞嗘椂锛屽繀椤讳娇鐢ㄥ紓姝ユ墽琛屽櫒銆傚嚑绉嶄富瑕佸疄鐜板琛?1 鎵€绀猴細

琛?1. 浠诲姟鎵ц鍣ㄥ垪琛?/h5>
绫诲悕 鎻忚堪 鏄惁寮傛
SyncTaskExecutor 绠€鍗曞悓姝ユ墽琛屽櫒 鍚?/td>
ThrottledTaskExecutor 璇ユ墽琛屽櫒涓哄叾浠栦换鎰忔墽琛屽櫒鐨勮楗扮被锛屽苟瀹屾垚鎻愪緵鎵ц娆℃暟闄愬埗鐨勫姛鑳?/td> 瑙嗚瑁呴グ鐨勬墽琛屽櫒鑰屽畾
SimpleAsyncTaskExecutor 绠€鍗曞紓姝ユ墽琛屽櫒锛屾彁渚涗簡涓€绉嶆渶鍩烘湰鐨勫紓姝ユ墽琛屽疄鐜?/td> 鏄?/td>
WorkManagerTaskExecutor 璇ョ被浣滀负閫氳繃 JCA 瑙勮寖杩涜浠诲姟鎵ц鐨勫疄鐜帮紝鍏跺寘鍚?JBossWorkManagerTaskExecutor 鍜?GlassFishWorkManagerTaskExecutor 涓や釜瀛愮被 鏄?/td>
ThreadPoolTaskExecutor 绾跨▼姹犱换鍔℃墽琛屽櫒 鏄?/td>

鍏舵锛孲pring Batch 杩樻敮鎸?Step 闂寸殑骞跺彂锛岃繖鏄€氳繃 Split Flow 瀹炵幇鐨勩€傝鎴戜滑鐪嬬湅 Split Flow 鏄浣曚娇鐢ㄧ殑銆傚湪姝や箣鍓嶏紝璁╂垜浠鎯充竴涓嬶紝鍋囧瀹㈡埛鍩轰簬涓婇潰鐨勭ず渚嬫彁鍑鸿繘涓€姝ラ渶姹傦細姣忔湀涓虹敤鎴风敓鎴愭墸璐归€氱煡锛屽苟鐢熸垚璐﹀崟銆佹墸璐广€佺即璐归€氱煡锛堝浜庤垂鐢ㄤ笉瓒崇殑鎯呭喌锛夈€?/p>

褰撶劧锛岃瀹炵幇涓婅堪闇€姹傛湁寰堝绉嶆柟寮忥紝姣斿锛屾寜鐓х敓鎴愯处鍗曘€佹墸璐归€氱煡銆佹墸璐广€佺即璐归€氱煡鐨勯『搴忎覆琛屾墽琛岋紝鐒惰€岋紝姝ょ澶勭悊鏂瑰紡鍔垮繀浼氶檷浣庢€ц兘锛屽嵆浣挎垜浠彲浠ヤ娇鐢?Step 澶氱嚎绋嬪鐞嗘潵鎻愰珮鎬ц兘锛屽彲浠嶄笉鏄渶浼樻柟寮忋€傞偅涔堟垜浠濡備綍鏀硅繘鍛紵鏄剧劧锛屾垜浠彲浠ュ皢鐢熸垚鎵h垂閫氱煡鍜屾墸璐瑰苟琛屾墽琛岋紝鍥犱负杩欎袱姝ユ槸瀹屽叏鐙珛鐨勩€備慨鏀瑰悗鐨?billing_job 濡傛竻鍗?11 鎵€绀猴細

娓呭崟 11. billing_job3.xml
 <job id="billingJob" restartable="true">
	<step id="billingStep" next="splitStep">
		<tasklet task-executor="taskExecutor" throttle-limit="5">
			<chunk reader="userDbReader" processor="billingProcessor"
        writer="billDbWriter" commit-interval="5" chunk-completion-policy="">
			</chunk>
		</tasklet>
	</step>
	<split id="splitStep" task-executor="taskExecutor"  next="decider">
		<flow>
			<step id="billingMessageStep">
				<tasklet>
                  <chunk reader="billDbReader" processor="billMessageItemProcessor"
					writer="messageDbWriter" commit-interval="5"
							chunk-completion-policy="">
					</chunk>
				</tasklet>
			</step>
		</flow>
		<flow>
			<step id="payStep">
				<tasklet>
                   <chunk reader="billDbReader" processor="payProcessor"
                   writer="payDbWriter" commit-interval="5" chunk-completion-policy=""
                   skip-limit="100">
                    <skippable-exception-classes>
                      <include 
                  class="org.springframework.batch.sample.MoneyNotEnoughException" />
                      </skippable-exception-classes>
					</chunk>
				</tasklet>
			</step>
		</flow>
	</split>
	<decision id="decider" decider="messagesDecider">
		<next on="COMPLETED WITH SKIPS" to="paymentMessageStep" />
		<end on="COMPLETED" />
	</decision>
	<step id="paymentMessageStep">
		<tasklet>
			<chunk reader="billArrearsDbReader" processor="messageProcessor"
					writer="messageDbWriter" commit-interval="5"
					chunk-completion-policy="">
			</chunk>
		</tasklet>
	</step>
</job>

浠庢竻鍗?10 鍙互鐪嬪嚭锛宐illingStep 鐨勪笅涓€姝ュ彉鎴愪簡涓€涓?split 鍏冪礌锛岃鍏冪礌涓嬪寘鍚袱涓?flow銆傗€渇low鈥濋【鍚嶆€濅箟鍖呭惈涓€绯诲垪鍙墽琛岀殑 step锛岀ず渚嬩腑涓や釜 flow 鍒嗗埆鍖呭惈 billingMessageStep锛堢敓鎴愭墸璐归€氱煡锛夊拰 payStep 涓や釜 step銆係pring Batch 鎵ц split 鏃讹紝灏嗕細骞惰鎵ц鍏朵笅鎵€鏈?flow锛岃€屼笖鍙湁褰撴墍鏈?step 鍧囨墽琛屽畬姣曚箣鍚庯紝鎵嶄細鎵ц split 鍏冪礌鐨勪笅涓€姝ワ紝褰撶劧锛屽墠鎻愭槸鎮ㄤ负 split 鍏冪礌鎸囧畾鐨?task-executor"涓?SimpleAsyncTaskExecutor锛岃灞炴€ч粯璁や负 SyncTaskExecutor锛屽嵆涓茶鎵ц銆?/p>

閫氳繃涓婅堪涓ょ鏂瑰紡锛屾垜浠彲浠ュ疄鐜?Job 鐨勫苟鍙戝鐞嗭紝浣嗘樉鐒惰鏂瑰紡鏈夊叾灞€闄愭€э紝鍗充粎闄愪簬鍗曟満銆?/p>

璁╂垜浠鎯充竴涓嬪涓嬪満鏅細鍦ㄤ笂杩扮即璐逛换鍔′腑锛岀敤鎴风敓鎴愯处鍗曢潪甯告參锛堜篃璁告槸鍥犱负涓氬姟澶勭悊杩囦簬澶嶆潅锛屼篃璁稿洜涓虹敓鎴愯处鍗曠殑杩囩▼涓悓鏃跺鐞嗕簡濂藉鍏宠仈淇℃伅锛夈€傝繖绉嶅満鏅垜浠鎬庝箞浼樺寲鍛紵鏄剧劧锛屽嵆渚挎垜浠皢璇ユ楠ら厤缃负骞惰锛岄偅涔堝畠鐨勪紭鍖栫┖闂翠篃鏄湁闄愮殑锛屽洜涓虹嚎绋嬪苟鍙戝埌涓€瀹氭暟閲忎箣鍚庡繀瀹氬彈闄愪簬绯荤粺纭欢閰嶇疆銆傝繖涓椂鍊欙紝鎴戜滑鑷劧浼氭兂鍒颁慨鏀归儴缃叉柟寮忥紝灏嗚€楁椂鎿嶄綔鍒嗛厤鍒板涓満鍣ㄤ笂骞惰鎵ц銆傞偅涔堝熀浜?Spring Batch 鎴戜滑璇ュ浣曞疄鐜板憿锛熸澶勪究鐢ㄥ埌浜?PartitionStep銆傝鎴戜滑鐪嬩竴涓嬪畠鏄浣曟墽琛岀殑锛屽叾鏃跺簭鍥惧鍥?1 鎵€绀猴細

鍥?1. PartitionStep 搴忓垪鍥?/h5> Spring Batch 鏋勫徐浼佷笟绾ф壒澶勭悊搴旂敤

浠庡浘涓垜浠彲浠ョ湅鍒帮紝PartitionStep 骞朵笉璐熻矗璇汇€佸啓鏁版嵁锛屽畠鍙槸鏍规嵁閰嶇疆鐨勭瓥鐣ワ紙PartitionHandler锛夊皢 StepExecution 杩涜鍒嗚В锛屽苟濮旀淳鍒版寚瀹氱殑 Step 涓婂苟琛屾墽琛岋紙璇?Step 鍙兘鏄湰鍦帮紝涔熷彲鑳芥槸杩滅▼锛夛紝鎵ц瀹屾瘯鍚庯紝灏嗘墍鏈夋墽琛岀粨鏋滆繘琛屽悎骞讹紙鐢?StepExecutionAggregator 瀹屾垚锛変綔涓鸿嚜韬殑鎵ц缁撴灉銆傚埄鐢?PartitionStep锛屽湪濮旀淳 Step 涓鸿繙绋嬭皟鐢ㄧ殑鎯呭喌涓嬶紝鎴戜滑鍙互寰堝鏄撻€氳繃澧炲姞浠庢満鏁扮洰鐨勬柟寮忔潵鎻愰珮浠诲姟杩愯鏁堢巼锛屽ぇ澶ф彁楂樹簡绯荤粺鐨勫彲浼哥缉鎬с€傝€屼笖姝ょ鏂瑰紡骞朵笉浼氬奖鍝?PartitionStep 鎵€鍦?Job 鐨勬墽琛岄『搴忥紝鍥犱负 PartitionStep 鍙湁褰撴墍鏈夊娲?Step 瀹屾垚涔嬪悗锛屾墠浼氱户缁線涓嬫墽琛屻€?/p>

涓嶈繃浣跨敤 PartitionStep 闇€瑕佹敞鎰忎互涓嬪嚑鐐癸細

  • 鐢变簬鏁版嵁鐨勮鍐欎互鍙婂鐞嗗潎鍦ㄤ粠鏈轰笂杩涜锛屽洜姝ら渶瑕佺‘淇濆苟鍙戠殑浠庢満涔嬮棿涓嶄細閲嶅璇诲彇鏁版嵁锛堝綋鐒讹紝杩欎釜闂鏄墍鏈夋壒澶勭悊搴旂敤閲囩敤涓讳粠鍜岄泦缇ゆ灦鏋勬椂鎵€蹇呴』鑰冭檻鐨勯棶棰橈紝鑰屽苟闈炲彧鏈?Spring Batch 鎵嶄細鏈夛級銆?/li>
  • 纭繚鍒嗚В鍒板悇涓粠鏈轰笂鐨?StepExecution 鏄笉鍚岀殑銆傚湪 StepExecutionSplitter 鐨勯粯璁ゅ疄鐜?SimpleStepExecutionSplitter 涓紝棣栧厛閫氳繃涓€涓?Partitioner 寰楀埌鍒嗚В鍚庣殑 ExecutionContext锛岀劧鍚庨拡瀵规瘡涓?ExecutionContext锛屽垱寤?StepExecution锛堝綋鐒讹紝濡傛灉 Step 涓洪噸澶嶆墽琛岋紝閭d箞灏嗕細寰楀埌涓婃杩愯鐨?ExecutionContext 鍜?StepExecution锛岃€岄潪閲嶆柊鍒涘缓锛夈€?/li>

浠庣浜岀偣鍙互鐪嬪嚭锛岄€氳繃鍦?ExecutionContext 璁剧疆鍞竴鐨勪俊鎭紝鎴戜滑渚垮彲浠ヤ繚璇佹瘡涓粠鏈鸿鍙栫殑鏁版嵁鏄笉鍚岀殑銆?/p>

涓讳粠鏂瑰紡鐨勫叿浣撻厤缃娓呭崟 12 鎵€绀猴細

娓呭崟 12. partition.xml
 <beans:bean name="step"
	class="org.springframework.batch.core.partition.support.PartitionStep">
	<beans:property name="partitionHandler">
		<beans:bean
class="org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler">
			<beans:property name="step" ref="remoteStep" />
			<beans:property name="gridSize" value="10" />
			<beans:property name="taskExecutor" ref="taskExecutor" />
		</beans:bean>
	</beans:property>
	<beans:property name="stepExecutionSplitter">
      <beans:bean 
class="org.springframework.batch.core.partition.support.SimpleStepExecutionSplitter">
			<beans:constructor-arg ref="jobRepository" />
			<beans:constructor-arg ref="messageStep" />
			<beans:constructor-arg ref="simplePartitioner" />
		</beans:bean>
	</beans:property>
	<beans:property name="jobRepository" ref="jobRepository" />
</beans:bean>

<step id="messageStep">
	<tasklet task-executor="taskExecutor">
		<chunk reader="messageReader" processor="messageProcessor"
		writer="messageWriter" commit-interval="5" chunk-completion-policy=""
				retry-limit="2">
			<retryable-exception-classes>
				<include class="java.lang.RuntimeException" />
			</retryable-exception-classes>
		</chunk>
	</tasklet>
</step>
<beans:bean id="remoteStep"
	class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
	<beans:property name="serviceInterface" 
	    value="org.springframework.batch.core.Step" />
	<beans:property name="serviceUrl" 
	     value="${batch.remote.base.url}/steps/messageStep" />
</beans:bean>

姝ゅ鍙噰鐢?Spring Batch 鐨勯粯璁ゅ疄鐜帮紝灏?Step 鍙戦€佸埌涓€鍙颁粠鏈轰笂鎵ц锛屽綋鐒讹紝鎮ㄥ畬鍏ㄥ彲浠ュ熀浜?Spring Batch 褰撳墠鎺ュ彛锛岃交鏄撴墿灞曞嚭鍒嗗彂鍒?N 鍙颁粠鏈轰笂鎵ц鐨勫疄鐜般€?/p>

姝ゅ锛屽湪鑰楁椂鐨?Step 姣旇緝鐙珛鐨勬儏鍐典笅锛堝鍙戦€佹墸璐归€氱煡鐨?Step锛屽悗缁?Step 涓嶄細渚濊禆鎵h垂閫氱煡 Step 鐨勪换浣曡緭鍑虹粨鏋滐級锛屾垜浠繕鍙互閲囩敤鍙︿竴绉嶄富浠庢灦鏋勩€傚湪涓绘満涓婇厤缃竴涓爣鍑嗙殑 Step锛屽叾 ItemWriter 璐熻矗灏嗚鍙栫殑璁板綍浠?Message 鐨勫舰寮忓彂閫佺粰娑堟伅涓棿浠讹紙褰撶劧锛岃鏂规骞舵湭鍏呭垎鍒╃敤 Spring Batch 鐨勭壒鎬э紝鑰屾槸鐢辨秷鎭腑闂翠欢瀹屾垚骞跺彂澶勭悊锛夈€?/p>

鎬荤粨

閫氳繃鏈枃鐨勮瑙o紝鎮ㄥ凡缁忓熀鏈簡瑙d簡 Spring Batch 涓娴佺▼銆佹潯浠朵互鍙婂苟鍙戠殑鏀寔銆傚埄鐢?Spring Batch 鎻愪緵鐨勮繖浜涚壒鎬э紝鎴戜滑瀹屽叏鍙互鏋勫缓鍑洪珮鎬ц兘銆侀珮鍙墿灞曟€у拰鍙淮鎶ゆ€х殑鎵瑰鐞嗗簲鐢ㄣ€傚湪鏈郴鍒楁枃绔犵殑鏈€鍚庝竴閮ㄥ垎锛屾垜灏嗙户缁粰鎮ㄤ粙缁?Spring Batch 鍏充簬鎵瑰鐞嗙洃鎺ф柟闈㈢殑鍐呭銆?/p>