or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mderror-handling.mdevaluation-contexts.mdexpression-evaluation.mdindex.mdmethod-constructor-resolution.mdproperty-index-access.mdspel-configuration.mdtype-system-support.md

spel-configuration.mddocs/

0

# SpEL Configuration

1

2

This document covers SpEL's configuration capabilities, including parser configuration, compiler settings, and performance tuning options.

3

4

## Parser Configuration

5

6

### SpelParserConfiguration Class

7

8

```java

9

public class SpelParserConfiguration {

10

// Constants

11

public static final int DEFAULT_MAX_EXPRESSION_LENGTH = 10000;

12

public static final String SPRING_EXPRESSION_COMPILER_MODE_PROPERTY_NAME =

13

"spring.expression.compiler.mode";

14

15

// Constructors

16

public SpelParserConfiguration();

17

public SpelParserConfiguration(SpelCompilerMode compilerMode, ClassLoader compilerClassLoader);

18

public SpelParserConfiguration(boolean autoGrowNullReferences, boolean autoGrowCollections);

19

public SpelParserConfiguration(boolean autoGrowNullReferences, boolean autoGrowCollections,

20

int maximumAutoGrowSize);

21

public SpelParserConfiguration(SpelCompilerMode compilerMode, ClassLoader compilerClassLoader,

22

boolean autoGrowNullReferences, boolean autoGrowCollections,

23

int maximumAutoGrowSize, int maximumExpressionLength);

24

25

// Accessors

26

public SpelCompilerMode getCompilerMode();

27

public ClassLoader getCompilerClassLoader();

28

public boolean isAutoGrowNullReferences();

29

public boolean isAutoGrowCollections();

30

public int getMaximumAutoGrowSize();

31

public int getMaximumExpressionLength();

32

}

33

```

34

{ .api }

35

36

### Basic Configuration Examples

37

38

```java

39

// Default configuration

40

SpelParserConfiguration defaultConfig = new SpelParserConfiguration();

41

42

// Configuration with compilation enabled

43

SpelParserConfiguration compiledConfig = new SpelParserConfiguration(

44

SpelCompilerMode.IMMEDIATE,

45

Thread.currentThread().getContextClassLoader()

46

);

47

48

// Configuration with auto-grow features

49

SpelParserConfiguration autoGrowConfig = new SpelParserConfiguration(

50

true, // autoGrowNullReferences

51

true, // autoGrowCollections

52

100 // maximumAutoGrowSize

53

);

54

55

// Complete configuration

56

SpelParserConfiguration fullConfig = new SpelParserConfiguration(

57

SpelCompilerMode.MIXED, // compilerMode

58

Thread.currentThread().getContextClassLoader(), // compilerClassLoader

59

true, // autoGrowNullReferences

60

true, // autoGrowCollections

61

1000, // maximumAutoGrowSize

62

50000 // maximumExpressionLength

63

);

64

65

// Use configuration with parser

66

SpelExpressionParser parser = new SpelExpressionParser(fullConfig);

67

```

68

{ .api }

69

70

## Compiler Configuration

71

72

### SpelCompilerMode Enum

73

74

```java

75

public enum SpelCompilerMode {

76

OFF, // No compilation, interpreted mode only (default)

77

IMMEDIATE, // Compile immediately after first interpretation

78

MIXED // Switch between interpreted and compiled modes as needed

79

}

80

```

81

{ .api }

82

83

### Compilation Modes Explained

84

85

#### OFF Mode (Default)

86

87

```java

88

SpelParserConfiguration config = new SpelParserConfiguration(

89

SpelCompilerMode.OFF,

90

null

91

);

92

SpelExpressionParser parser = new SpelExpressionParser(config);

93

94

// All expressions will be interpreted, no compilation

95

Expression exp = parser.parseExpression("name.toUpperCase() + ' ' + age");

96

// Always uses interpretation, slower but more flexible

97

```

98

{ .api }

99

100

#### IMMEDIATE Mode

101

102

```java

103

SpelParserConfiguration config = new SpelParserConfiguration(

104

SpelCompilerMode.IMMEDIATE,

105

Thread.currentThread().getContextClassLoader()

106

);

107

SpelExpressionParser parser = new SpelExpressionParser(config);

108

109

SpelExpression exp = parser.parseRaw("name.toUpperCase() + ' ' + age");

110

111

// First evaluation triggers compilation

112

String result1 = exp.getValue(person, String.class); // Interpreted + compiled

113

// Subsequent evaluations use compiled code

114

String result2 = exp.getValue(person, String.class); // Compiled (much faster)

115

```

116

{ .api }

117

118

#### MIXED Mode

119

120

```java

121

SpelParserConfiguration config = new SpelParserConfiguration(

122

SpelCompilerMode.MIXED,

123

Thread.currentThread().getContextClassLoader()

124

);

125

SpelExpressionParser parser = new SpelExpressionParser(config);

126

127

// Expressions can switch between interpreted and compiled modes

128

// based on success/failure of compilation and execution patterns

129

SpelExpression exp = parser.parseRaw("complexExpression()");

130

```

131

{ .api }

132

133

### System Property Configuration

134

135

```java

136

// Set compiler mode via system property

137

System.setProperty("spring.expression.compiler.mode", "IMMEDIATE");

138

139

// Parser will use system property if no explicit configuration provided

140

SpelExpressionParser parser = new SpelExpressionParser();

141

// Equivalent to:

142

// SpelExpressionParser parser = new SpelExpressionParser(

143

// new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, classLoader)

144

// );

145

```

146

{ .api }

147

148

### Manual Compilation Control

149

150

```java

151

SpelExpressionParser parser = new SpelExpressionParser();

152

SpelExpression expression = parser.parseRaw("name.length() > 5 ? name.toUpperCase() : name");

153

154

// Check if expression can be compiled

155

boolean compilable = expression.compileExpression();

156

157

if (compilable) {

158

// Expression was successfully compiled

159

String result = expression.getValue(person, String.class); // Uses compiled code

160

} else {

161

// Compilation failed, will use interpreted mode

162

String result = expression.getValue(person, String.class); // Uses interpretation

163

}

164

165

// Revert to interpreted mode

166

expression.revertToInterpreted();

167

String result = expression.getValue(person, String.class); // Back to interpretation

168

```

169

{ .api }

170

171

## Auto-Growth Configuration

172

173

### Null Reference Auto-Growth

174

175

```java

176

public class Container {

177

private NestedObject nested;

178

// getter and setter

179

}

180

181

public class NestedObject {

182

private String value;

183

// getter and setter

184

}

185

186

// Enable null reference auto-growth

187

SpelParserConfiguration config = new SpelParserConfiguration(

188

true, // autoGrowNullReferences

189

false // autoGrowCollections

190

);

191

SpelExpressionParser parser = new SpelExpressionParser(config);

192

193

Container container = new Container(); // nested is null

194

StandardEvaluationContext context = new StandardEvaluationContext(container);

195

196

// Without auto-growth, this would throw NullPointerException

197

// With auto-growth, it creates the nested object automatically

198

Expression exp = parser.parseExpression("nested.value");

199

exp.setValue(context, "Hello World");

200

201

// nested object was created automatically

202

NestedObject created = container.getNested(); // not null

203

String value = created.getValue(); // "Hello World"

204

```

205

{ .api }

206

207

### Collection Auto-Growth

208

209

```java

210

public class ListContainer {

211

private List<String> items = new ArrayList<>();

212

// getter and setter

213

}

214

215

// Enable collection auto-growth

216

SpelParserConfiguration config = new SpelParserConfiguration(

217

false, // autoGrowNullReferences

218

true, // autoGrowCollections

219

10 // maximumAutoGrowSize

220

);

221

SpelExpressionParser parser = new SpelExpressionParser(config);

222

223

ListContainer container = new ListContainer(); // empty list

224

StandardEvaluationContext context = new StandardEvaluationContext(container);

225

226

// Set value at index 5 in empty list

227

Expression exp = parser.parseExpression("items[5]");

228

exp.setValue(context, "Hello");

229

230

// List automatically grows to accommodate index 5

231

List<String> items = container.getItems();

232

// items.size() == 6, items.get(5) == "Hello", others are null

233

```

234

{ .api }

235

236

### Combined Auto-Growth

237

238

```java

239

public class ComplexContainer {

240

private List<NestedObject> objects;

241

// getter and setter

242

}

243

244

// Enable both auto-growth features

245

SpelParserConfiguration config = new SpelParserConfiguration(

246

true, // autoGrowNullReferences

247

true, // autoGrowCollections

248

50 // maximumAutoGrowSize

249

);

250

SpelExpressionParser parser = new SpelExpressionParser(config);

251

252

ComplexContainer container = new ComplexContainer(); // objects is null

253

StandardEvaluationContext context = new StandardEvaluationContext(container);

254

255

// This will:

256

// 1. Create the objects list (null reference auto-growth)

257

// 2. Grow the list to accommodate index 3 (collection auto-growth)

258

// 3. Create NestedObject at index 3 (null reference auto-growth)

259

Expression exp = parser.parseExpression("objects[3].value");

260

exp.setValue(context, "Deep Value");

261

262

NestedObject obj = container.getObjects().get(3);

263

String value = obj.getValue(); // "Deep Value"

264

```

265

{ .api }

266

267

## Expression Length Limits

268

269

### Maximum Expression Length

270

271

```java

272

// Set custom maximum expression length

273

SpelParserConfiguration config = new SpelParserConfiguration(

274

SpelCompilerMode.OFF,

275

null,

276

false, // autoGrowNullReferences

277

false, // autoGrowCollections

278

0, // maximumAutoGrowSize

279

5000 // maximumExpressionLength (default is 10,000)

280

);

281

282

SpelExpressionParser parser = new SpelExpressionParser(config);

283

284

// Expressions longer than 5000 characters will be rejected

285

String longExpression = "very".repeat(2000) + "long expression";

286

try {

287

Expression exp = parser.parseExpression(longExpression);

288

} catch (ParseException e) {

289

// Expression too long

290

}

291

```

292

{ .api }

293

294

## Advanced Configuration Patterns

295

296

### Environment-Based Configuration

297

298

```java

299

public class SpelConfigurationFactory {

300

301

public static SpelParserConfiguration createProductionConfig() {

302

return new SpelParserConfiguration(

303

SpelCompilerMode.IMMEDIATE, // Aggressive compilation for performance

304

Thread.currentThread().getContextClassLoader(),

305

false, // Disable auto-growth for predictable behavior

306

false,

307

0,

308

10000 // Standard expression length limit

309

);

310

}

311

312

public static SpelParserConfiguration createDevelopmentConfig() {

313

return new SpelParserConfiguration(

314

SpelCompilerMode.OFF, // No compilation for easier debugging

315

null,

316

true, // Enable auto-growth for convenience

317

true,

318

100,

319

50000 // Larger expression limit for experimentation

320

);

321

}

322

323

public static SpelParserConfiguration createTestConfig() {

324

return new SpelParserConfiguration(

325

SpelCompilerMode.MIXED, // Mixed mode for testing both paths

326

Thread.currentThread().getContextClassLoader(),

327

true, // Auto-growth for test data setup

328

true,

329

10,

330

10000

331

);

332

}

333

}

334

335

// Usage

336

String environment = System.getProperty("environment", "development");

337

SpelParserConfiguration config = switch (environment) {

338

case "production" -> SpelConfigurationFactory.createProductionConfig();

339

case "test" -> SpelConfigurationFactory.createTestConfig();

340

default -> SpelConfigurationFactory.createDevelopmentConfig();

341

};

342

343

SpelExpressionParser parser = new SpelExpressionParser(config);

344

```

345

{ .api }

346

347

### Configuration with Custom ClassLoader

348

349

```java

350

// Custom class loader for isolation

351

ClassLoader customClassLoader = new URLClassLoader(

352

new URL[]{new URL("file:///path/to/custom/classes/")},

353

Thread.currentThread().getContextClassLoader()

354

);

355

356

SpelParserConfiguration config = new SpelParserConfiguration(

357

SpelCompilerMode.IMMEDIATE,

358

customClassLoader // Use custom class loader for compilation

359

);

360

361

SpelExpressionParser parser = new SpelExpressionParser(config);

362

363

// Compiled expressions will use the custom class loader

364

Expression exp = parser.parseExpression("T(com.custom.MyClass).staticMethod()");

365

```

366

{ .api }

367

368

## Configuration Best Practices

369

370

### Performance-Oriented Configuration

371

372

```java

373

// High-performance configuration for production systems

374

SpelParserConfiguration performanceConfig = new SpelParserConfiguration(

375

SpelCompilerMode.IMMEDIATE, // Immediate compilation

376

Thread.currentThread().getContextClassLoader(), // Appropriate class loader

377

false, // Disable auto-growth (predictable)

378

false, // Disable auto-growth

379

0, // No auto-growth

380

10000 // Standard limit

381

);

382

383

// Use with cached expressions

384

Map<String, Expression> expressionCache = new ConcurrentHashMap<>();

385

SpelExpressionParser parser = new SpelExpressionParser(performanceConfig);

386

387

public Expression getCachedExpression(String expressionString) {

388

return expressionCache.computeIfAbsent(expressionString, parser::parseExpression);

389

}

390

```

391

{ .api }

392

393

### Security-Conscious Configuration

394

395

```java

396

// Security-focused configuration

397

SpelParserConfiguration secureConfig = new SpelParserConfiguration(

398

SpelCompilerMode.OFF, // No compilation to avoid runtime class generation

399

null,

400

false, // No auto-growth to prevent unexpected object creation

401

false,

402

0,

403

1000 // Strict expression length limit

404

);

405

406

// Combine with SimpleEvaluationContext for additional security

407

SpelExpressionParser parser = new SpelExpressionParser(secureConfig);

408

SimpleEvaluationContext context = SimpleEvaluationContext

409

.forReadOnlyDataBinding()

410

.build();

411

```

412

{ .api }

413

414

### Development-Friendly Configuration

415

416

```java

417

// Development configuration with helpful features

418

SpelParserConfiguration devConfig = new SpelParserConfiguration(

419

SpelCompilerMode.MIXED, // Test both compilation modes

420

Thread.currentThread().getContextClassLoader(),

421

true, // Auto-growth for easier prototyping

422

true,

423

1000, // Generous auto-growth limit

424

100000 // Large expression limit for experimentation

425

);

426

427

SpelExpressionParser parser = new SpelExpressionParser(devConfig);

428

429

// Useful for development: detailed error reporting

430

public Object safeEvaluate(String expressionString, Object root) {

431

try {

432

Expression exp = parser.parseExpression(expressionString);

433

return exp.getValue(root);

434

} catch (ParseException e) {

435

System.err.println("Parse error in expression: " + expressionString);

436

System.err.println("Error: " + e.toDetailedString());

437

return null;

438

} catch (EvaluationException e) {

439

System.err.println("Evaluation error in expression: " + expressionString);

440

System.err.println("Error: " + e.toDetailedString());

441

return null;

442

}

443

}

444

```

445

{ .api }

446

447

## Configuration Validation

448

449

### Runtime Configuration Checks

450

451

```java

452

public class ConfigurationValidator {

453

454

public static void validateConfiguration(SpelParserConfiguration config) {

455

SpelCompilerMode mode = config.getCompilerMode();

456

ClassLoader classLoader = config.getCompilerClassLoader();

457

458

if ((mode == SpelCompilerMode.IMMEDIATE || mode == SpelCompilerMode.MIXED)

459

&& classLoader == null) {

460

throw new IllegalArgumentException(

461

"ClassLoader must be provided for compilation modes");

462

}

463

464

if (config.getMaximumAutoGrowSize() < 0) {

465

throw new IllegalArgumentException(

466

"Maximum auto-grow size must be non-negative");

467

}

468

469

if (config.getMaximumExpressionLength() <= 0) {

470

throw new IllegalArgumentException(

471

"Maximum expression length must be positive");

472

}

473

}

474

475

public static SpelExpressionParser createValidatedParser(SpelParserConfiguration config) {

476

validateConfiguration(config);

477

return new SpelExpressionParser(config);

478

}

479

}

480

```

481

{ .api }

482

483

## Migration and Compatibility

484

485

### Upgrading Configuration

486

487

```java

488

// Legacy configuration (pre-6.0)

489

SpelParserConfiguration legacyConfig = new SpelParserConfiguration(

490

true, // autoGrowNullReferences

491

true // autoGrowCollections

492

);

493

494

// Modern equivalent with explicit settings

495

SpelParserConfiguration modernConfig = new SpelParserConfiguration(

496

SpelCompilerMode.OFF, // Explicit compiler mode

497

Thread.currentThread().getContextClassLoader(), // Explicit class loader

498

true, // autoGrowNullReferences

499

true, // autoGrowCollections

500

Integer.MAX_VALUE, // maximumAutoGrowSize

501

SpelParserConfiguration.DEFAULT_MAX_EXPRESSION_LENGTH

502

);

503

```

504

{ .api }

505

506

### Configuration Compatibility Checking

507

508

```java

509

public class CompatibilityChecker {

510

511

public static boolean isCompilationSupported() {

512

try {

513

SpelParserConfiguration config = new SpelParserConfiguration(

514

SpelCompilerMode.IMMEDIATE,

515

Thread.currentThread().getContextClassLoader()

516

);

517

SpelExpressionParser parser = new SpelExpressionParser(config);

518

SpelExpression exp = parser.parseRaw("'test'");

519

return exp.compileExpression();

520

} catch (Exception e) {

521

return false;

522

}

523

}

524

525

public static SpelParserConfiguration createCompatibleConfig() {

526

if (isCompilationSupported()) {

527

return new SpelParserConfiguration(

528

SpelCompilerMode.IMMEDIATE,

529

Thread.currentThread().getContextClassLoader()

530

);

531

} else {

532

return new SpelParserConfiguration();

533

}

534

}

535

}

536

```

537

{ .api }