or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

auto-configuration.mdconfiguration-properties.mdcustomization.mdindex.mdjob-execution.md

customization.mddocs/

0

# Customization and Qualification

1

2

Spring Boot Batch Starter provides extensive customization capabilities through qualifier annotations, customization interfaces, and database initialization components for advanced configuration scenarios.

3

4

## Capabilities

5

6

### Qualifier Annotations

7

8

Qualifier annotations enable precise dependency injection when multiple beans of the same type exist, particularly useful in multi-tenant or complex enterprise environments.

9

10

#### @BatchDataSource

11

12

Qualifier annotation for specifying a dedicated DataSource for batch metadata storage, separate from the application's primary DataSource.

13

14

```java { .api }

15

/**

16

* Qualifier annotation for a DataSource to be injected into Batch auto-configuration.

17

* Can be used on a secondary data source, if there is another one marked as @Primary.

18

*/

19

@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE })

20

@Retention(RetentionPolicy.RUNTIME)

21

@Documented

22

@Qualifier

23

public @interface BatchDataSource {

24

}

25

```

26

27

**Usage Examples:**

28

29

```java

30

@Configuration

31

public class MultiDataSourceConfiguration {

32

33

@Bean

34

@Primary

35

@ConfigurationProperties("app.datasource")

36

public DataSource applicationDataSource() {

37

return DataSourceBuilder.create().build();

38

}

39

40

@Bean

41

@BatchDataSource

42

@ConfigurationProperties("batch.datasource")

43

public DataSource batchDataSource() {

44

return DataSourceBuilder.create().build();

45

}

46

}

47

48

# application.yml

49

app:

50

datasource:

51

url: jdbc:postgresql://localhost/appdb

52

username: app_user

53

password: app_pass

54

55

batch:

56

datasource:

57

url: jdbc:postgresql://localhost/batchdb

58

username: batch_user

59

password: batch_pass

60

```

61

62

#### @BatchTransactionManager

63

64

Qualifier annotation for specifying a dedicated PlatformTransactionManager for batch operations.

65

66

```java { .api }

67

/**

68

* Qualifier annotation for a PlatformTransactionManager to be injected into Batch

69

* auto-configuration. Can be used on a secondary PlatformTransactionManager, if

70

* there is another one marked as @Primary.

71

*/

72

@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE })

73

@Retention(RetentionPolicy.RUNTIME)

74

@Documented

75

@Qualifier

76

public @interface BatchTransactionManager {

77

}

78

```

79

80

**Usage Examples:**

81

82

```java

83

@Configuration

84

public class TransactionManagerConfiguration {

85

86

@Bean

87

@Primary

88

public PlatformTransactionManager applicationTransactionManager(

89

@Qualifier("applicationDataSource") DataSource dataSource) {

90

return new DataSourceTransactionManager(dataSource);

91

}

92

93

@Bean

94

@BatchTransactionManager

95

public PlatformTransactionManager batchTransactionManager(

96

@BatchDataSource DataSource batchDataSource) {

97

DataSourceTransactionManager tm = new DataSourceTransactionManager(batchDataSource);

98

tm.setDefaultTimeout(3600); // Longer timeout for batch operations

99

return tm;

100

}

101

}

102

```

103

104

#### @BatchTaskExecutor

105

106

Qualifier annotation for specifying a dedicated TaskExecutor for batch job processing, enabling custom thread pool configuration for batch operations.

107

108

```java { .api }

109

/**

110

* Qualifier annotation for a TaskExecutor to be injected into Batch

111

* auto-configuration. Can be used on a secondary task executor source, if there is

112

* another one marked as @Primary.

113

*/

114

@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE })

115

@Retention(RetentionPolicy.RUNTIME)

116

@Documented

117

@Qualifier

118

public @interface BatchTaskExecutor {

119

}

120

```

121

122

**Usage Examples:**

123

124

```java

125

@Configuration

126

@EnableAsync

127

public class TaskExecutorConfiguration {

128

129

@Bean

130

@Primary

131

public TaskExecutor applicationTaskExecutor() {

132

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

133

executor.setCorePoolSize(2);

134

executor.setMaxPoolSize(5);

135

executor.setQueueCapacity(10);

136

executor.setThreadNamePrefix("app-");

137

executor.initialize();

138

return executor;

139

}

140

141

@Bean

142

@BatchTaskExecutor

143

public TaskExecutor batchTaskExecutor() {

144

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

145

executor.setCorePoolSize(10);

146

executor.setMaxPoolSize(50);

147

executor.setQueueCapacity(1000);

148

executor.setThreadNamePrefix("batch-");

149

executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

150

executor.initialize();

151

return executor;

152

}

153

}

154

155

// Use in step configuration

156

@Bean

157

public Step parallelProcessingStep(JobRepository jobRepository,

158

@BatchTransactionManager PlatformTransactionManager transactionManager,

159

@BatchTaskExecutor TaskExecutor taskExecutor) {

160

return new StepBuilder("parallelStep", jobRepository)

161

.<String, String>chunk(100, transactionManager)

162

.reader(itemReader())

163

.processor(itemProcessor())

164

.writer(itemWriter())

165

.taskExecutor(taskExecutor)

166

.build();

167

}

168

```

169

170

### Customization Interfaces

171

172

#### BatchConversionServiceCustomizer

173

174

Functional interface for customizing the ConversionService used by Spring Batch for type conversions in job parameters and other batch operations.

175

176

```java { .api }

177

/**

178

* Callback interface that can be implemented by beans wishing to customize the

179

* ConfigurableConversionService that is provided by DefaultBatchConfiguration

180

* while retaining its default auto-configuration.

181

*/

182

@FunctionalInterface

183

public interface BatchConversionServiceCustomizer {

184

185

/**

186

* Customize the ConfigurableConversionService used by batch infrastructure

187

* @param configurableConversionService the ConfigurableConversionService to customize

188

*/

189

void customize(ConfigurableConversionService configurableConversionService);

190

}

191

```

192

193

**Usage Examples:**

194

195

```java

196

@Component

197

public class CustomBatchConversionServiceCustomizer implements BatchConversionServiceCustomizer {

198

199

@Override

200

public void customize(ConfigurableConversionService conversionService) {

201

// Add custom converters for specific types

202

conversionService.addConverter(new StringToLocalDateConverter());

203

conversionService.addConverter(new LocalDateToStringConverter());

204

conversionService.addConverter(new StringToEnumConverter());

205

206

// Add custom formatting for specific patterns

207

FormattingConversionService formattingService = (FormattingConversionService) conversionService;

208

formattingService.addFormatter(new CustomDateFormatter("yyyy-MM-dd"));

209

}

210

}

211

212

// Custom converter example

213

public class StringToLocalDateConverter implements Converter<String, LocalDate> {

214

215

@Override

216

public LocalDate convert(String source) {

217

try {

218

return LocalDate.parse(source, DateTimeFormatter.ISO_LOCAL_DATE);

219

} catch (DateTimeParseException e) {

220

throw new ConversionFailedException(

221

TypeDescriptor.valueOf(String.class),

222

TypeDescriptor.valueOf(LocalDate.class),

223

source, e);

224

}

225

}

226

}

227

228

// Usage in job parameters

229

java -jar app.jar --startDate=2024-01-15 --endDate=2024-01-31

230

// Automatically converted to LocalDate objects in job parameters

231

```

232

233

### Database Initialization Components

234

235

#### BatchDataSourceScriptDatabaseInitializer

236

237

Handles automatic initialization of batch database schema using SQL scripts with platform-specific support.

238

239

```java { .api }

240

/**

241

* Database initializer for Spring Batch schema using SQL scripts.

242

* Supports platform-specific scripts and custom schema locations.

243

*/

244

public class BatchDataSourceScriptDatabaseInitializer extends DataSourceScriptDatabaseInitializer {

245

246

/**

247

* Creates database initializer with specified DataSource and configuration

248

* @param dataSource DataSource to initialize (may be qualified with @BatchDataSource)

249

* @param properties JDBC configuration properties for initialization behavior

250

*/

251

public BatchDataSourceScriptDatabaseInitializer(

252

DataSource dataSource,

253

BatchProperties.Jdbc properties);

254

}

255

```

256

257

**Usage Examples:**

258

259

```java

260

@Configuration

261

public class CustomBatchDatabaseConfiguration {

262

263

@Bean

264

@ConditionalOnMissingBean

265

public BatchDataSourceScriptDatabaseInitializer customBatchInitializer(

266

@BatchDataSource DataSource batchDataSource,

267

BatchProperties batchProperties) {

268

269

BatchProperties.Jdbc jdbcProperties = batchProperties.getJdbc();

270

271

// Customize initialization behavior

272

jdbcProperties.setSchema("classpath:custom-batch-schema.sql");

273

jdbcProperties.setPlatform("postgresql");

274

jdbcProperties.setInitializeSchema(DatabaseInitializationMode.ALWAYS);

275

276

return new BatchDataSourceScriptDatabaseInitializer(batchDataSource, jdbcProperties);

277

}

278

}

279

280

# Custom schema file: custom-batch-schema.sql

281

CREATE TABLE IF NOT EXISTS CUSTOM_BATCH_JOB_INSTANCE (

282

JOB_INSTANCE_ID BIGINT PRIMARY KEY,

283

VERSION BIGINT,

284

JOB_NAME VARCHAR(100) NOT NULL,

285

JOB_KEY VARCHAR(32) NOT NULL,

286

constraint JOB_INST_UN unique (JOB_NAME, JOB_KEY)

287

);

288

-- Additional custom tables...

289

```

290

291

#### JobRepositoryDependsOnDatabaseInitializationDetector

292

293

Ensures proper initialization order between database schema creation and job repository configuration.

294

295

```java { .api }

296

/**

297

* Detector that ensures JobRepository beans depend on database initialization completion.

298

* Part of Spring Boot's database initialization dependency management system.

299

*/

300

public class JobRepositoryDependsOnDatabaseInitializationDetector

301

implements DependsOnDatabaseInitializationDetector {

302

303

/**

304

* Returns bean names that should depend on database initialization

305

* @return Set of bean names that require database initialization to complete first

306

*/

307

public Set<String> getDependsOnDatabaseInitializationBeanNames();

308

}

309

```

310

311

## Advanced Customization Patterns

312

313

### Multi-Tenant Batch Configuration

314

315

Configure separate batch infrastructure for different tenants:

316

317

```java

318

@Configuration

319

public class MultiTenantBatchConfiguration {

320

321

@Bean("tenant1BatchConfig")

322

@ConfigurationProperties("tenant1.batch")

323

public BatchProperties tenant1BatchProperties() {

324

return new BatchProperties();

325

}

326

327

@Bean("tenant2BatchConfig")

328

@ConfigurationProperties("tenant2.batch")

329

public BatchProperties tenant2BatchProperties() {

330

return new BatchProperties();

331

}

332

333

@Bean

334

@BatchDataSource

335

@Qualifier("tenant1DataSource")

336

public DataSource tenant1DataSource() {

337

return DataSourceBuilder.create()

338

.url("jdbc:postgresql://localhost/tenant1_batch")

339

.build();

340

}

341

342

@Bean

343

@Qualifier("tenant2DataSource")

344

public DataSource tenant2DataSource() {

345

return DataSourceBuilder.create()

346

.url("jdbc:postgresql://localhost/tenant2_batch")

347

.build();

348

}

349

}

350

```

351

352

### Custom Error Handling and Monitoring

353

354

Integrate custom monitoring and error handling:

355

356

```java

357

@Component

358

public class BatchMonitoringCustomizer implements BatchConversionServiceCustomizer {

359

360

@Autowired

361

private MeterRegistry meterRegistry;

362

363

@Override

364

public void customize(ConfigurableConversionService conversionService) {

365

// Add monitoring capabilities to conversion service

366

conversionService.addConverter(new MonitoredStringToDateConverter(meterRegistry));

367

}

368

369

@EventListener

370

public void handleJobExecution(JobExecutionEvent event) {

371

JobExecution execution = event.getJobExecution();

372

373

// Custom metrics

374

Timer.Sample sample = Timer.start(meterRegistry);

375

sample.stop(Timer.builder("batch.job.duration")

376

.tag("job.name", execution.getJobInstance().getJobName())

377

.tag("status", execution.getStatus().toString())

378

.register(meterRegistry));

379

380

// Custom alerting

381

if (execution.getStatus() == BatchStatus.FAILED) {

382

sendAlert(execution);

383

}

384

}

385

386

private void sendAlert(JobExecution execution) {

387

// Integration with alerting systems

388

}

389

}

390

```

391

392

### Dynamic Job Parameter Resolution

393

394

Create dynamic job parameter resolution based on environment:

395

396

```java

397

@Component

398

public class EnvironmentAwareBatchConversionServiceCustomizer

399

implements BatchConversionServiceCustomizer {

400

401

@Autowired

402

private Environment environment;

403

404

@Override

405

public void customize(ConfigurableConversionService conversionService) {

406

conversionService.addConverter(new EnvironmentAwareConverter(environment));

407

}

408

}

409

410

public class EnvironmentAwareConverter implements Converter<String, String> {

411

412

private final Environment environment;

413

414

public EnvironmentAwareConverter(Environment environment) {

415

this.environment = environment;

416

}

417

418

@Override

419

public String convert(String source) {

420

// Resolve environment-specific placeholders

421

if (source.startsWith("${") && source.endsWith("}")) {

422

String property = source.substring(2, source.length() - 1);

423

return environment.getProperty(property, source);

424

}

425

return source;

426

}

427

}

428

```

429

430

## Integration Best Practices

431

432

### Resource Management

433

434

```java

435

@Configuration

436

public class BatchResourceConfiguration {

437

438

@Bean

439

@BatchTaskExecutor

440

public TaskExecutor batchTaskExecutor() {

441

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

442

executor.setCorePoolSize(Runtime.getRuntime().availableProcessors());

443

executor.setMaxPoolSize(Runtime.getRuntime().availableProcessors() * 2);

444

executor.setQueueCapacity(1000);

445

executor.setThreadNamePrefix("batch-worker-");

446

executor.setWaitForTasksToCompleteOnShutdown(true);

447

executor.setAwaitTerminationSeconds(60);

448

executor.initialize();

449

return executor;

450

}

451

}

452

```

453

454

### Security Integration

455

456

```java

457

@Configuration

458

@EnableBatchProcessing

459

public class SecureBatchConfiguration {

460

461

@Bean

462

@BatchDataSource

463

public DataSource secureDataSource() {

464

HikariConfig config = new HikariConfig();

465

config.setJdbcUrl("jdbc:postgresql://localhost/secure_batch");

466

config.setUsername("batch_service");

467

// Use encrypted password or credential management

468

config.setPassword(passwordDecoder.decode(encryptedPassword));

469

config.setMaximumPoolSize(20);

470

return new HikariDataSource(config);

471

}

472

}