or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotation-processing.mdaot-optimization.mdcore-infrastructure.mdenvironment-config.mdindex.mdresource-management.mdtask-execution.mdtype-conversion.mdutilities.md

environment-config.mddocs/

0

# Environment and Configuration

1

2

Spring Core provides a comprehensive environment abstraction that manages application properties, profiles, and configuration from various sources. This system enables flexible configuration management across different deployment environments.

3

4

## Environment Interface

5

6

The `Environment` interface provides the main abstraction for the runtime environment and application properties.

7

8

**Environment Interface**

9

```java { .api }

10

public interface Environment extends PropertyResolver {

11

String[] getActiveProfiles();

12

String[] getDefaultProfiles();

13

14

@Deprecated

15

boolean acceptsProfiles(String... profiles);

16

boolean acceptsProfiles(Profiles profiles);

17

}

18

19

public interface ConfigurableEnvironment extends Environment, ConfigurablePropertyResolver {

20

void setActiveProfiles(String... profiles);

21

void addActiveProfile(String profile);

22

void setDefaultProfiles(String... profiles);

23

24

MutablePropertySources getPropertySources();

25

Map<String, Object> getSystemProperties();

26

Map<String, Object> getSystemEnvironment();

27

28

void merge(ConfigurableEnvironment parent);

29

}

30

```

31

32

**Standard Environment Implementation**

33

```java { .api }

34

public class StandardEnvironment extends AbstractEnvironment {

35

public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";

36

public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";

37

38

public StandardEnvironment();

39

40

@Override

41

protected void customizePropertySources(MutablePropertySources propertySources);

42

}

43

44

public abstract class AbstractEnvironment implements ConfigurableEnvironment {

45

public static final String IGNORE_GETENV_PROPERTY_NAME = "spring.getenv.ignore";

46

public static final String ACTIVE_PROFILES_PROPERTY_NAME = "spring.profiles.active";

47

public static final String DEFAULT_PROFILES_PROPERTY_NAME = "spring.profiles.default";

48

49

protected final Log logger = LogFactory.getLog(getClass());

50

private final Set<String> activeProfiles = new LinkedHashSet<>();

51

private final Set<String> defaultProfiles = new LinkedHashSet<>(getReservedDefaultProfiles());

52

private final MutablePropertySources propertySources = new MutablePropertySources();

53

private final ConfigurablePropertyResolver propertyResolver = new PropertySourcesPropertyResolver(this.propertySources);

54

55

public AbstractEnvironment();

56

57

protected void customizePropertySources(MutablePropertySources propertySources);

58

protected Set<String> getReservedDefaultProfiles();

59

protected boolean isProfileActive(String profile);

60

61

@Override

62

public String[] getActiveProfiles();

63

@Override

64

public void setActiveProfiles(String... profiles);

65

@Override

66

public void addActiveProfile(String profile);

67

68

@Override

69

public String[] getDefaultProfiles();

70

@Override

71

public void setDefaultProfiles(String... profiles);

72

73

@Override

74

public boolean acceptsProfiles(Profiles profiles);

75

76

@Override

77

public MutablePropertySources getPropertySources();

78

}

79

```

80

81

**Usage Examples**

82

```java

83

// Basic environment usage

84

Environment env = new StandardEnvironment();

85

86

// Check active profiles

87

String[] activeProfiles = env.getActiveProfiles();

88

boolean isProduction = env.acceptsProfiles(Profiles.of("production"));

89

boolean isDevelopment = env.acceptsProfiles(Profiles.of("development"));

90

91

// Complex profile expressions

92

boolean isCloudOrDocker = env.acceptsProfiles(Profiles.of("cloud | docker"));

93

boolean isNotTest = env.acceptsProfiles(Profiles.of("!test"));

94

95

// Configure environment programmatically

96

ConfigurableEnvironment configurableEnv = new StandardEnvironment();

97

configurableEnv.setActiveProfiles("production", "cloud");

98

configurableEnv.addActiveProfile("monitoring");

99

100

// Access properties

101

String serverPort = env.getProperty("server.port", "8080");

102

Integer maxConnections = env.getProperty("server.max-connections", Integer.class, 100);

103

```

104

105

## Property Resolution

106

107

The property resolver system provides flexible property access with placeholder resolution and type conversion.

108

109

**PropertyResolver Interface**

110

```java { .api }

111

public interface PropertyResolver {

112

boolean containsProperty(String key);

113

String getProperty(String key);

114

String getProperty(String key, String defaultValue);

115

<T> T getProperty(String key, Class<T> targetType);

116

<T> T getProperty(String key, Class<T> targetType, T defaultValue);

117

118

String getRequiredProperty(String key) throws IllegalStateException;

119

<T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException;

120

121

String resolvePlaceholders(String text);

122

String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;

123

}

124

125

public interface ConfigurablePropertyResolver extends PropertyResolver {

126

ConfigurableConversionService getConversionService();

127

void setConversionService(ConfigurableConversionService conversionService);

128

129

void setPlaceholderPrefix(String placeholderPrefix);

130

void setPlaceholderSuffix(String placeholderSuffix);

131

void setValueSeparator(String valueSeparator);

132

133

void setIgnoreUnresolvableNestedPlaceholders(boolean ignoreUnresolvableNestedPlaceholders);

134

void setRequiredProperties(String... requiredProperties);

135

void validateRequiredProperties() throws MissingRequiredPropertiesException;

136

}

137

```

138

139

**PropertySourcesPropertyResolver**

140

```java { .api }

141

public class PropertySourcesPropertyResolver extends AbstractPropertyResolver {

142

public PropertySourcesPropertyResolver(PropertySources propertySources);

143

144

@Override

145

public boolean containsProperty(String key);

146

@Override

147

public String getProperty(String key);

148

@Override

149

public <T> T getProperty(String key, Class<T> targetType);

150

151

protected <T> T getProperty(String key, Class<T> targetType, boolean resolveNestedPlaceholders);

152

protected PropertySource<?> findPropertySource(String key);

153

}

154

```

155

156

**Usage Examples**

157

```java

158

// Property resolution with type conversion

159

PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources);

160

161

// Basic property access

162

String appName = resolver.getProperty("app.name", "MyApp");

163

Integer port = resolver.getProperty("server.port", Integer.class, 8080);

164

Boolean enableSsl = resolver.getProperty("security.ssl.enabled", Boolean.class, false);

165

166

// Required properties (throw exception if missing)

167

String dbUrl = resolver.getRequiredProperty("database.url");

168

Integer maxPoolSize = resolver.getRequiredProperty("database.pool.max-size", Integer.class);

169

170

// Placeholder resolution

171

String template = "App ${app.name} running on port ${server.port}";

172

String resolved = resolver.resolvePlaceholders(template);

173

// Result: "App MyApp running on port 8080"

174

175

// Configure resolver

176

ConfigurablePropertyResolver configurable = new PropertySourcesPropertyResolver(propertySources);

177

configurable.setPlaceholderPrefix("#{");

178

configurable.setPlaceholderSuffix("}");

179

configurable.setValueSeparator(":");

180

configurable.setIgnoreUnresolvableNestedPlaceholders(true);

181

182

// Set required properties for validation

183

configurable.setRequiredProperties("database.url", "app.secret");

184

try {

185

configurable.validateRequiredProperties();

186

} catch (MissingRequiredPropertiesException ex) {

187

// Handle missing required properties

188

}

189

```

190

191

## Property Sources

192

193

Property sources provide the actual property values from various sources like files, environment variables, and system properties.

194

195

**PropertySource Classes**

196

```java { .api }

197

public abstract class PropertySource<T> {

198

protected final String name;

199

protected final T source;

200

201

public PropertySource(String name, T source);

202

public PropertySource(String name);

203

204

public String getName();

205

public T getSource();

206

public boolean containsProperty(String name);

207

public abstract Object getProperty(String name);

208

209

@Override

210

public boolean equals(Object other);

211

@Override

212

public int hashCode();

213

@Override

214

public String toString();

215

216

public static PropertySource<?> named(String name);

217

}

218

219

public class MapPropertySource extends EnumerablePropertySource<Map<String, Object>> {

220

public MapPropertySource(String name, Map<String, Object> source);

221

222

@Override

223

public Object getProperty(String name);

224

@Override

225

public boolean containsProperty(String name);

226

@Override

227

public String[] getPropertyNames();

228

}

229

230

public class SystemEnvironmentPropertySource extends MapPropertySource {

231

public SystemEnvironmentPropertySource(String name, Map<String, Object> source);

232

233

@Override

234

public boolean containsProperty(String name);

235

@Override

236

public Object getProperty(String name);

237

238

protected boolean isSecurityManagerPresent();

239

protected String resolvePropertyName(String name);

240

}

241

242

public abstract class EnumerablePropertySource<T> extends PropertySource<T> {

243

public EnumerablePropertySource(String name, T source);

244

public EnumerablePropertySource(String name);

245

246

@Override

247

public boolean containsProperty(String name);

248

public abstract String[] getPropertyNames();

249

}

250

```

251

252

**PropertySources Container**

253

```java { .api }

254

public interface PropertySources extends Iterable<PropertySource<?>> {

255

default Stream<PropertySource<?>> stream();

256

boolean contains(String name);

257

PropertySource<?> get(String name);

258

}

259

260

public class MutablePropertySources implements PropertySources {

261

public MutablePropertySources();

262

public MutablePropertySources(PropertySources propertySources);

263

264

@Override

265

public Iterator<PropertySource<?>> iterator();

266

@Override

267

public Spliterator<PropertySource<?>> spliterator();

268

@Override

269

public Stream<PropertySource<?>> stream();

270

@Override

271

public boolean contains(String name);

272

@Override

273

public PropertySource<?> get(String name);

274

275

public void addFirst(PropertySource<?> propertySource);

276

public void addLast(PropertySource<?> propertySource);

277

public void addBefore(String relativePropertySourceName, PropertySource<?> propertySource);

278

public void addAfter(String relativePropertySourceName, PropertySource<?> propertySource);

279

280

public int precedenceOf(PropertySource<?> propertySource);

281

public PropertySource<?> remove(String name);

282

public void replace(String name, PropertySource<?> propertySource);

283

284

public int size();

285

@Override

286

public String toString();

287

}

288

```

289

290

**Usage Examples**

291

```java

292

// Create property sources from various sources

293

Map<String, Object> appProps = new HashMap<>();

294

appProps.put("app.name", "MyApplication");

295

appProps.put("app.version", "1.0.0");

296

PropertySource<?> appPropertySource = new MapPropertySource("applicationProperties", appProps);

297

298

// System environment and properties

299

PropertySource<?> systemEnvSource = new SystemEnvironmentPropertySource(

300

StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,

301

System.getenv()

302

);

303

304

PropertySource<?> systemPropsSource = new PropertiesPropertySource(

305

StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME,

306

System.getProperties()

307

);

308

309

// Manage property source precedence

310

MutablePropertySources propertySources = new MutablePropertySources();

311

propertySources.addFirst(appPropertySource); // Highest priority

312

propertySources.addLast(systemPropsSource); // Lowest priority

313

propertySources.addAfter("applicationProperties", systemEnvSource);

314

315

// Access through property resolver

316

PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources);

317

String appName = resolver.getProperty("app.name"); // "MyApplication"

318

319

// Property source operations

320

boolean hasAppProps = propertySources.contains("applicationProperties");

321

PropertySource<?> appSource = propertySources.get("applicationProperties");

322

int precedence = propertySources.precedenceOf(appSource); // 0 (highest)

323

324

// Replace property source

325

Map<String, Object> newProps = new HashMap<>(appProps);

326

newProps.put("app.version", "2.0.0");

327

PropertySource<?> updatedSource = new MapPropertySource("applicationProperties", newProps);

328

propertySources.replace("applicationProperties", updatedSource);

329

```

330

331

## Profile Support

332

333

Spring provides sophisticated profile support for environment-specific configuration.

334

335

**Profiles Interface**

336

```java { .api }

337

public interface Profiles {

338

boolean matches(Predicate<String> activeProfiles);

339

340

static Profiles of(String... profiles);

341

}

342

343

class ProfilesParser {

344

static Profiles parse(String... expressions);

345

}

346

```

347

348

**Profile Expression Language**

349

```java

350

// Profile expressions support logical operators

351

Profiles production = Profiles.of("production");

352

Profiles cloudOrDocker = Profiles.of("cloud | docker");

353

Profiles notTest = Profiles.of("!test");

354

Profiles complexExpr = Profiles.of("(cloud | docker) & !test");

355

```

356

357

**Usage Examples**

358

```java

359

// Profile-based configuration

360

ConfigurableEnvironment env = new StandardEnvironment();

361

362

// Set profiles programmatically

363

env.setActiveProfiles("development", "debug");

364

env.addActiveProfile("local");

365

366

// Or via system properties

367

System.setProperty("spring.profiles.active", "production,cloud");

368

369

// Check profile conditions

370

boolean isDevEnvironment = env.acceptsProfiles(Profiles.of("development"));

371

boolean isCloudDeployment = env.acceptsProfiles(Profiles.of("cloud | docker"));

372

boolean isNotTesting = env.acceptsProfiles(Profiles.of("!test"));

373

374

// Complex profile logic in configuration

375

@Configuration

376

@Profile("production & !development")

377

public class ProductionConfig {

378

379

@Bean

380

@Profile("cloud | docker")

381

public DataSource cloudDataSource() {

382

// Cloud-specific datasource

383

}

384

385

@Bean

386

@Profile("!cloud")

387

public DataSource localDataSource() {

388

// Local datasource

389

}

390

}

391

392

// Conditional bean creation based on profiles

393

@Component

394

public class EnvironmentAwareService {

395

396

@Autowired

397

public EnvironmentAwareService(Environment env) {

398

if (env.acceptsProfiles(Profiles.of("development"))) {

399

// Development-specific initialization

400

} else if (env.acceptsProfiles(Profiles.of("production"))) {

401

// Production-specific initialization

402

}

403

}

404

}

405

```

406

407

## Property Placeholder Resolution

408

409

**PropertyPlaceholderHelper**

410

```java { .api }

411

public class PropertyPlaceholderHelper {

412

public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix);

413

public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix,

414

String valueSeparator, boolean ignoreUnresolvablePlaceholders);

415

416

public String replacePlaceholders(String value, Properties properties);

417

public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver);

418

419

protected String parseStringValue(String value, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders);

420

421

@FunctionalInterface

422

public interface PlaceholderResolver {

423

String resolvePlaceholder(String placeholderName);

424

}

425

}

426

```

427

428

**Usage Examples**

429

```java

430

// Custom placeholder resolution

431

PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}", ":", true);

432

433

// Simple properties-based resolution

434

Properties props = new Properties();

435

props.setProperty("server.host", "localhost");

436

props.setProperty("server.port", "8080");

437

438

String template = "Server running at ${server.host}:${server.port}";

439

String resolved = helper.replacePlaceholders(template, props);

440

// Result: "Server running at localhost:8080"

441

442

// Custom placeholder resolver

443

PlaceholderResolver resolver = placeholderName -> {

444

switch (placeholderName) {

445

case "timestamp": return String.valueOf(System.currentTimeMillis());

446

case "random": return String.valueOf(Math.random());

447

default: return null;

448

}

449

};

450

451

String dynamicTemplate = "Generated at ${timestamp} with random ${random}";

452

String dynamicResolved = helper.replacePlaceholders(dynamicTemplate, resolver);

453

454

// Default value support

455

String withDefaults = "Host: ${server.host:localhost}, Port: ${server.port:8080}";

456

String resolvedWithDefaults = helper.replacePlaceholders(withDefaults, props);

457

```

458

459

## Environment Profiles Utility

460

461

**ProfilesParser and Profile Expression Support**

462

```java { .api }

463

final class Profiles {

464

private final String[] expressions;

465

466

private Profiles(String[] expressions);

467

468

public static Profiles of(String... profiles);

469

public boolean matches(Predicate<String> activeProfiles);

470

471

private static class ParsedProfiles implements Profiles {

472

private final Set<ProfileExpression> expressions;

473

474

ParsedProfiles(String... expressions);

475

476

@Override

477

public boolean matches(Predicate<String> activeProfiles);

478

}

479

}

480

```

481

482

**Advanced Environment Configuration**

483

```java { .api }

484

public class StandardServletEnvironment extends StandardEnvironment implements ConfigurableWebEnvironment {

485

public static final String SERVLET_CONTEXT_PROPERTY_SOURCE_NAME = "servletContextInitParams";

486

public static final String SERVLET_CONFIG_PROPERTY_SOURCE_NAME = "servletConfigInitParams";

487

public static final String JNDI_PROPERTY_SOURCE_NAME = "jndiProperties";

488

489

@Override

490

protected void customizePropertySources(MutablePropertySources propertySources);

491

492

@Override

493

public void initPropertySources(ServletContext servletContext, ServletConfig servletConfig);

494

}

495

```

496

497

**Usage Examples**

498

```java

499

// Advanced profile expressions

500

Environment env = new StandardEnvironment();

501

502

// Logical AND

503

boolean isProdAndCloud = env.acceptsProfiles(Profiles.of("production & cloud"));

504

505

// Logical OR

506

boolean isDevOrTest = env.acceptsProfiles(Profiles.of("development | test"));

507

508

// Negation

509

boolean isNotProduction = env.acceptsProfiles(Profiles.of("!production"));

510

511

// Complex expressions with grouping

512

boolean complexCondition = env.acceptsProfiles(Profiles.of("(cloud | docker) & !test & production"));

513

514

// Multiple profile checks

515

String[] activeProfiles = env.getActiveProfiles();

516

boolean hasAnyActiveProfile = Arrays.stream(activeProfiles).anyMatch(profile ->

517

env.acceptsProfiles(Profiles.of(profile))

518

);

519

520

// Environment merging for hierarchical configurations

521

ConfigurableEnvironment child = new StandardEnvironment();

522

child.setActiveProfiles("development");

523

524

ConfigurableEnvironment parent = new StandardEnvironment();

525

parent.setActiveProfiles("base");

526

parent.getPropertySources().addFirst(new MapPropertySource("parentProps",

527

Map.of("parent.property", "parent-value")));

528

529

child.merge(parent);

530

// Child now has access to parent's property sources and profiles

531

```

532

533

This environment and configuration system provides the foundation for Spring's flexible, profile-aware configuration management, enabling applications to adapt their behavior based on deployment context while maintaining clean separation of concerns.