or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aop.mdcore-container.mddata-access.mdindex.mdintegration.mdmessaging.mdreactive-web.mdtesting.mdweb-framework.md

core-container.mddocs/

0

# Core Container & Dependency Injection

1

2

The Spring Core Container is the foundation of the Spring Framework, providing the Inversion of Control (IoC) container and dependency injection capabilities. It consists of three main modules: spring-core, spring-beans, and spring-context.

3

4

## Maven Dependencies

5

6

```xml

7

<!-- Core container with application context -->

8

<dependency>

9

<groupId>org.springframework</groupId>

10

<artifactId>spring-context</artifactId>

11

<version>5.3.39</version>

12

</dependency>

13

14

<!-- For minimal IoC container only -->

15

<dependency>

16

<groupId>org.springframework</groupId>

17

<artifactId>spring-beans</artifactId>

18

<version>5.3.39</version>

19

</dependency>

20

```

21

22

## Core Imports

23

24

```java { .api }

25

// Application Context and Configuration

26

import org.springframework.context.ApplicationContext;

27

import org.springframework.context.ConfigurableApplicationContext;

28

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

29

import org.springframework.context.support.ClassPathXmlApplicationContext;

30

31

// Configuration Annotations

32

import org.springframework.context.annotation.Configuration;

33

import org.springframework.context.annotation.Bean;

34

import org.springframework.context.annotation.ComponentScan;

35

import org.springframework.context.annotation.Import;

36

37

// Dependency Injection

38

import org.springframework.beans.factory.annotation.Autowired;

39

import org.springframework.beans.factory.annotation.Qualifier;

40

import org.springframework.beans.factory.annotation.Value;

41

42

// Component Stereotypes

43

import org.springframework.stereotype.Component;

44

import org.springframework.stereotype.Service;

45

import org.springframework.stereotype.Repository;

46

47

// Bean Factory Interfaces

48

import org.springframework.beans.factory.BeanFactory;

49

import org.springframework.beans.factory.ListableBeanFactory;

50

import org.springframework.beans.factory.config.ConfigurableBeanFactory;

51

52

// Resource and Environment

53

import org.springframework.core.io.Resource;

54

import org.springframework.core.io.ResourceLoader;

55

import org.springframework.core.env.Environment;

56

57

// Application Startup Metrics (Spring 5.3+)

58

import org.springframework.core.metrics.ApplicationStartup;

59

import org.springframework.core.metrics.StartupStep;

60

import org.springframework.core.metrics.DefaultApplicationStartup;

61

import org.springframework.core.metrics.jfr.FlightRecorderApplicationStartup;

62

63

// Reactive Type Adapters

64

import org.springframework.core.ReactiveAdapterRegistry;

65

import org.springframework.core.ReactiveAdapter;

66

import org.springframework.core.ReactiveTypeDescriptor;

67

import org.springframework.context.annotation.PropertySource;

68

```

69

70

## Core Container Architecture

71

72

### Spring Core Module (org.springframework.core)

73

74

The core module provides fundamental utilities, I/O abstractions, and type resolution.

75

76

#### Type Resolution and Metadata

77

78

```java { .api }

79

// Encapsulates Java Type information with generic support

80

public class ResolvableType {

81

public static ResolvableType forClass(Class<?> clazz);

82

public static ResolvableType forInstance(Object instance);

83

public ResolvableType[] getGenerics();

84

public Class<?> getRawClass();

85

public ResolvableType getSuperType();

86

public ResolvableType[] getInterfaces();

87

}

88

89

// Helper for resolving method parameters and return types

90

public class MethodParameter {

91

public MethodParameter(Method method, int parameterIndex);

92

public MethodParameter(Constructor<?> constructor, int parameterIndex);

93

public Class<?> getParameterType();

94

public Type getGenericParameterType();

95

public String getParameterName();

96

public ResolvableType getResolvableType();

97

}

98

```

99

100

#### Application Startup Metrics (Spring 5.3+)

101

102

```java { .api }

103

// Interface for instrumenting application startup phases

104

public interface ApplicationStartup {

105

ApplicationStartup DEFAULT = new DefaultApplicationStartup();

106

107

StartupStep start(String name);

108

}

109

110

// Step recording metrics about a particular phase during startup

111

public interface StartupStep {

112

String getName();

113

long getId();

114

StartupStep.Tags getTags();

115

void end();

116

117

// Nested interface for step metadata

118

interface Tags {

119

Tags tag(String key, String value);

120

Tags tag(String key, Supplier<String> value);

121

}

122

}

123

124

// Default no-op implementation

125

public class DefaultApplicationStartup implements ApplicationStartup {

126

@Override

127

public StartupStep start(String name);

128

}

129

130

// Flight Recorder implementation for JFR integration

131

public class FlightRecorderApplicationStartup implements ApplicationStartup {

132

@Override

133

public StartupStep start(String name);

134

}

135

```

136

137

#### Reactive Type Adapters

138

139

```java { .api }

140

// Registry of adapters to adapt Reactive Streams Publisher to/from various async/reactive types

141

public class ReactiveAdapterRegistry {

142

public static ReactiveAdapterRegistry getSharedInstance();

143

144

public void registerReactiveType(ReactiveTypeDescriptor descriptor,

145

Function<Object, Publisher<?>> toAdapter,

146

Function<Publisher<?>, Object> fromAdapter);

147

148

@Nullable

149

public ReactiveAdapter getAdapter(Class<?> reactiveType);

150

@Nullable

151

public ReactiveAdapter getAdapter(@Nullable Class<?> reactiveType, @Nullable Object source);

152

}

153

154

// Adapter for converting between Reactive Streams Publisher and async/reactive types

155

public class ReactiveAdapter {

156

public ReactiveTypeDescriptor getDescriptor();

157

public Publisher<?> toPublisher(Object source);

158

public Object fromPublisher(Publisher<?> publisher);

159

}

160

161

// Descriptor for reactive types (Mono, Flux, Observable, etc.)

162

public class ReactiveTypeDescriptor {

163

public static ReactiveTypeDescriptor singleOptionalValue(Class<?> type, Supplier<Object> emptySupplier);

164

public static ReactiveTypeDescriptor multiValue(Class<?> type, Supplier<Object> emptySupplier);

165

public static ReactiveTypeDescriptor noValue(Class<?> type, Supplier<Object> emptySupplier);

166

167

public Class<?> getReactiveType();

168

public boolean isMultiValue();

169

public boolean isNoValue();

170

public boolean supportsEmpty();

171

}

172

```

173

174

#### Resource Abstraction

175

176

```java { .api }

177

// Interface for abstracting access to low-level resources

178

public interface Resource extends InputStreamSource {

179

boolean exists();

180

boolean isReadable();

181

boolean isOpen();

182

URL getURL() throws IOException;

183

URI getURI() throws IOException;

184

File getFile() throws IOException;

185

long contentLength() throws IOException;

186

long lastModified() throws IOException;

187

String getFilename();

188

String getDescription();

189

}

190

191

// Strategy interface for loading resources

192

public interface ResourceLoader {

193

String CLASSPATH_URL_PREFIX = "classpath:";

194

Resource getResource(String location);

195

ClassLoader getClassLoader();

196

}

197

198

// Common Resource implementations

199

public class ClassPathResource implements Resource {

200

public ClassPathResource(String path);

201

public ClassPathResource(String path, Class<?> clazz);

202

public ClassPathResource(String path, ClassLoader classLoader);

203

}

204

205

public class FileSystemResource implements Resource {

206

public FileSystemResource(String path);

207

public FileSystemResource(File file);

208

public FileSystemResource(Path path);

209

}

210

211

public class UrlResource extends AbstractResource {

212

public UrlResource(URL url);

213

public UrlResource(String protocol, String location);

214

}

215

```

216

217

#### Environment and Property Resolution

218

219

```java { .api }

220

// Interface representing the environment with profiles and properties

221

public interface Environment extends PropertyResolver {

222

String[] getActiveProfiles();

223

String[] getDefaultProfiles();

224

boolean acceptsProfiles(String... profiles);

225

boolean acceptsProfiles(Profiles profiles);

226

}

227

228

// Interface for resolving properties against any underlying source

229

public interface PropertyResolver {

230

boolean containsProperty(String key);

231

String getProperty(String key);

232

String getProperty(String key, String defaultValue);

233

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

234

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

235

String resolvePlaceholders(String text);

236

String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;

237

}

238

239

// Abstract base class representing a source of name/value property pairs

240

public abstract class PropertySource<T> {

241

public PropertySource(String name, T source);

242

public String getName();

243

public T getSource();

244

public abstract Object getProperty(String name);

245

}

246

```

247

248

### Spring Beans Module (org.springframework.beans)

249

250

The beans module provides the IoC container implementation and bean lifecycle management.

251

252

#### Bean Factory Interfaces

253

254

```java { .api }

255

// Root interface for accessing Spring bean container

256

public interface BeanFactory {

257

String FACTORY_BEAN_PREFIX = "&";

258

259

Object getBean(String name) throws BeansException;

260

<T> T getBean(String name, Class<T> requiredType) throws BeansException;

261

Object getBean(String name, Object... args) throws BeansException;

262

<T> T getBean(Class<T> requiredType) throws BeansException;

263

<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

264

265

boolean containsBean(String name);

266

boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

267

boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

268

boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

269

Class<?> getType(String name) throws NoSuchBeanDefinitionException;

270

String[] getAliases(String name);

271

}

272

273

// Extension for factories that can enumerate all beans

274

public interface ListableBeanFactory extends BeanFactory {

275

boolean containsBeanDefinition(String beanName);

276

int getBeanDefinitionCount();

277

String[] getBeanDefinitionNames();

278

String[] getBeanNamesForType(Class<?> type);

279

String[] getBeanNamesForType(ResolvableType type);

280

<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;

281

String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);

282

Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;

283

<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) throws NoSuchBeanDefinitionException;

284

}

285

286

// Configuration interface for most bean factories

287

public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {

288

String SCOPE_SINGLETON = "singleton";

289

String SCOPE_PROTOTYPE = "prototype";

290

291

void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;

292

void setBeanClassLoader(ClassLoader beanClassLoader);

293

ClassLoader getBeanClassLoader();

294

void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

295

int getBeanPostProcessorCount();

296

void registerScope(String scopeName, Scope scope);

297

String[] getRegisteredScopeNames();

298

Scope getRegisteredScope(String scopeName);

299

}

300

```

301

302

#### Bean Definitions

303

304

```java { .api }

305

// Describes a bean instance with property values and constructor arguments

306

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

307

String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

308

String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

309

310

String getBeanClassName();

311

void setBeanClassName(String beanClassName);

312

String getScope();

313

void setScope(String scope);

314

boolean isLazyInit();

315

void setLazyInit(boolean lazyInit);

316

String[] getDependsOn();

317

void setDependsOn(String... dependsOn);

318

boolean isAutowireCandidate();

319

void setAutowireCandidate(boolean autowireCandidate);

320

String getInitMethodName();

321

void setInitMethodName(String initMethodName);

322

String getDestroyMethodName();

323

void setDestroyMethodName(String destroyMethodName);

324

325

ConstructorArgumentValues getConstructorArgumentValues();

326

MutablePropertyValues getPropertyValues();

327

}

328

329

// Holder for BeanDefinition with name and aliases

330

public class BeanDefinitionHolder implements BeanMetadataElement {

331

public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName);

332

public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName, String[] aliases);

333

334

public BeanDefinition getBeanDefinition();

335

public String getBeanName();

336

public String[] getAliases();

337

}

338

```

339

340

#### Bean Post Processing

341

342

```java { .api }

343

// Factory hook for custom modification of new bean instances

344

public interface BeanPostProcessor {

345

default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

346

return bean;

347

}

348

349

default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

350

return bean;

351

}

352

}

353

354

// Subinterface that adds before-instantiation callback

355

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

356

default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

357

return null;

358

}

359

360

default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {

361

return true;

362

}

363

364

default PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

365

return pvs;

366

}

367

}

368

369

// Factory hook for custom modification of application context's bean definitions

370

public interface BeanFactoryPostProcessor {

371

void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

372

}

373

```

374

375

#### Dependency Injection Annotations

376

377

```java { .api }

378

// Marks constructor, field, or method as to be autowired

379

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

380

@Retention(RetentionPolicy.RUNTIME)

381

@Documented

382

public @interface Autowired {

383

boolean required() default true;

384

}

385

386

// Qualifier annotation for specifying which bean to inject

387

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

388

@Retention(RetentionPolicy.RUNTIME)

389

@Inherited

390

@Documented

391

public @interface Qualifier {

392

String value() default "";

393

}

394

395

// Indicates default value expression for field or parameter

396

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

397

@Retention(RetentionPolicy.RUNTIME)

398

@Documented

399

public @interface Value {

400

String value();

401

}

402

```

403

404

### Spring Context Module (org.springframework.context)

405

406

The context module provides the ApplicationContext and additional enterprise services.

407

408

#### Application Context

409

410

```java { .api }

411

// Central interface providing configuration for an application

412

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,

413

MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

414

415

String getId();

416

String getApplicationName();

417

String getDisplayName();

418

long getStartupDate();

419

ApplicationContext getParent();

420

AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;

421

}

422

423

// Configuration interface for most application contexts

424

public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {

425

String CONFIG_LOCATION_DELIMITERS = ",; \t\n";

426

String CONVERSION_SERVICE_BEAN_NAME = "conversionService";

427

String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";

428

String ENVIRONMENT_BEAN_NAME = "environment";

429

String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";

430

String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";

431

432

void setId(String id);

433

void setParent(ApplicationContext parent);

434

void setEnvironment(ConfigurableEnvironment environment);

435

ConfigurableEnvironment getEnvironment();

436

void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);

437

void addApplicationListener(ApplicationListener<?> listener);

438

void refresh() throws BeansException, IllegalStateException;

439

void registerShutdownHook();

440

void close();

441

boolean isActive();

442

ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

443

}

444

445

// Standalone application context accepting annotated classes as input

446

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

447

public AnnotationConfigApplicationContext();

448

public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory);

449

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses);

450

public AnnotationConfigApplicationContext(String... basePackages);

451

452

public void register(Class<?>... annotatedClasses);

453

public void scan(String... basePackages);

454

}

455

```

456

457

#### Configuration Annotations

458

459

```java { .api }

460

// Indicates that a class declares one or more @Bean methods

461

@Target(ElementType.TYPE)

462

@Retention(RetentionPolicy.RUNTIME)

463

@Documented

464

@Component

465

public @interface Configuration {

466

@AliasFor(annotation = Component.class)

467

String value() default "";

468

469

boolean proxyBeanMethods() default true;

470

}

471

472

// Indicates that a method produces a bean to be managed by Spring container

473

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})

474

@Retention(RetentionPolicy.RUNTIME)

475

@Documented

476

public @interface Bean {

477

@AliasFor("name")

478

String[] value() default {};

479

480

String[] name() default {};

481

Autowire autowire() default Autowire.NO;

482

boolean autowireCandidate() default true;

483

String initMethod() default "";

484

String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;

485

}

486

487

// Configures component scanning directives

488

@Target(ElementType.TYPE)

489

@Retention(RetentionPolicy.RUNTIME)

490

@Documented

491

@Repeatable(ComponentScans.class)

492

public @interface ComponentScan {

493

@AliasFor("basePackages")

494

String[] value() default {};

495

496

String[] basePackages() default {};

497

Class<?>[] basePackageClasses() default {};

498

Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

499

Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;

500

ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;

501

String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;

502

boolean useDefaultFilters() default true;

503

Filter[] includeFilters() default {};

504

Filter[] excludeFilters() default {};

505

boolean lazyInit() default false;

506

}

507

```

508

509

#### Component Stereotypes

510

511

```java { .api }

512

// Indicates that an annotated class is a "component"

513

@Target(ElementType.TYPE)

514

@Retention(RetentionPolicy.RUNTIME)

515

@Documented

516

@Indexed

517

public @interface Component {

518

String value() default "";

519

}

520

521

// Indicates that an annotated class is a "Service"

522

@Target(ElementType.TYPE)

523

@Retention(RetentionPolicy.RUNTIME)

524

@Documented

525

@Component

526

public @interface Service {

527

@AliasFor(annotation = Component.class)

528

String value() default "";

529

}

530

531

// Indicates that an annotated class is a "Repository"

532

@Target(ElementType.TYPE)

533

@Retention(RetentionPolicy.RUNTIME)

534

@Documented

535

@Component

536

public @interface Repository {

537

@AliasFor(annotation = Component.class)

538

String value() default "";

539

}

540

```

541

542

#### Event System

543

544

```java { .api }

545

// Class to be extended by all application events

546

public abstract class ApplicationEvent extends EventObject {

547

public ApplicationEvent(Object source);

548

public final long getTimestamp();

549

}

550

551

// Interface to be implemented by application event listeners

552

@FunctionalInterface

553

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

554

void onApplicationEvent(E event);

555

}

556

557

// Interface that encapsulates event publication functionality

558

@FunctionalInterface

559

public interface ApplicationEventPublisher {

560

default void publishEvent(ApplicationEvent event) {

561

publishEvent((Object) event);

562

}

563

564

void publishEvent(Object event);

565

}

566

567

// Annotation-based event listener

568

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})

569

@Retention(RetentionPolicy.RUNTIME)

570

@Documented

571

public @interface EventListener {

572

@AliasFor("classes")

573

Class<?>[] value() default {};

574

575

Class<?>[] classes() default {};

576

String condition() default "";

577

}

578

```

579

580

## Practical Usage Examples

581

582

### Basic IoC Container Setup

583

584

```java { .api }

585

// Java configuration approach

586

@Configuration

587

@ComponentScan(basePackages = "com.example")

588

public class AppConfig {

589

590

@Bean

591

public DataSource dataSource() {

592

BasicDataSource ds = new BasicDataSource();

593

ds.setDriverClassName("org.h2.Driver");

594

ds.setUrl("jdbc:h2:mem:testdb");

595

return ds;

596

}

597

598

@Bean

599

public PlatformTransactionManager transactionManager(DataSource dataSource) {

600

return new DataSourceTransactionManager(dataSource);

601

}

602

}

603

604

// Application startup

605

public class Application {

606

public static void main(String[] args) {

607

ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

608

609

// Retrieve beans

610

UserService userService = ctx.getBean(UserService.class);

611

DataSource dataSource = ctx.getBean(DataSource.class);

612

613

// Use the beans

614

User user = userService.findById(1L);

615

616

// Clean shutdown

617

((ConfigurableApplicationContext) ctx).close();

618

}

619

}

620

```

621

622

### Dependency Injection Patterns

623

624

```java { .api }

625

// Constructor injection (recommended)

626

@Service

627

public class UserService {

628

629

private final UserRepository userRepository;

630

private final EmailService emailService;

631

632

// @Autowired optional on single constructor

633

public UserService(UserRepository userRepository, EmailService emailService) {

634

this.userRepository = userRepository;

635

this.emailService = emailService;

636

}

637

638

public User createUser(User user) {

639

User saved = userRepository.save(user);

640

emailService.sendWelcomeEmail(saved);

641

return saved;

642

}

643

}

644

645

// Field injection with qualifiers

646

@Component

647

public class NotificationManager {

648

649

@Autowired

650

@Qualifier("emailNotifier")

651

private Notifier emailNotifier;

652

653

@Autowired

654

@Qualifier("smsNotifier")

655

private Notifier smsNotifier;

656

657

public void sendNotification(String message, NotificationType type) {

658

switch (type) {

659

case EMAIL:

660

emailNotifier.send(message);

661

break;

662

case SMS:

663

smsNotifier.send(message);

664

break;

665

}

666

}

667

}

668

669

// Multiple implementations with qualifiers

670

@Component

671

@Qualifier("emailNotifier")

672

public class EmailNotifier implements Notifier {

673

public void send(String message) {

674

// Send email

675

}

676

}

677

678

@Component

679

@Qualifier("smsNotifier")

680

public class SmsNotifier implements Notifier {

681

public void send(String message) {

682

// Send SMS

683

}

684

}

685

```

686

687

### Property Management

688

689

```java { .api }

690

// Property source configuration

691

@Configuration

692

@PropertySource("classpath:application.properties")

693

@PropertySource("classpath:database.properties")

694

public class PropertyConfig {

695

696

@Autowired

697

private Environment env;

698

699

@Bean

700

public DatabaseConfig databaseConfig() {

701

DatabaseConfig config = new DatabaseConfig();

702

config.setUrl(env.getProperty("db.url"));

703

config.setUsername(env.getProperty("db.username"));

704

config.setPassword(env.getProperty("db.password"));

705

config.setMaxConnections(env.getProperty("db.maxConnections", Integer.class, 10));

706

return config;

707

}

708

}

709

710

// Value injection in components

711

@Component

712

public class EmailService {

713

714

@Value("${email.smtp.host}")

715

private String smtpHost;

716

717

@Value("${email.smtp.port:587}")

718

private int smtpPort;

719

720

@Value("${email.from}")

721

private String fromAddress;

722

723

public void sendEmail(String to, String subject, String body) {

724

// Use injected properties

725

}

726

}

727

```

728

729

### Profile-Based Configuration

730

731

```java { .api }

732

// Environment-specific beans

733

@Configuration

734

public class ProfileConfig {

735

736

@Bean

737

@Profile("development")

738

public DataSource devDataSource() {

739

return new EmbeddedDatabaseBuilder()

740

.setType(EmbeddedDatabaseType.H2)

741

.addScript("classpath:schema.sql")

742

.addScript("classpath:test-data.sql")

743

.build();

744

}

745

746

@Bean

747

@Profile("production")

748

public DataSource prodDataSource() {

749

HikariDataSource dataSource = new HikariDataSource();

750

dataSource.setJdbcUrl("jdbc:postgresql://prod-db:5432/myapp");

751

dataSource.setUsername("produser");

752

dataSource.setPassword("prodpass");

753

dataSource.setMaximumPoolSize(20);

754

return dataSource;

755

}

756

757

@Bean

758

@Profile({"development", "test"})

759

public MailSender mockMailSender() {

760

return new MockMailSender();

761

}

762

763

@Bean

764

@Profile("production")

765

public MailSender realMailSender() {

766

JavaMailSenderImpl mailSender = new JavaMailSenderImpl();

767

mailSender.setHost("smtp.company.com");

768

return mailSender;

769

}

770

}

771

```

772

773

### Bean Lifecycle Management

774

775

```java { .api }

776

// Lifecycle interfaces

777

@Component

778

public class DatabaseConnectionManager implements InitializingBean, DisposableBean {

779

780

private Connection connection;

781

782

@Override

783

public void afterPropertiesSet() throws Exception {

784

// Initialize connection after properties are set

785

this.connection = DriverManager.getConnection("jdbc:h2:mem:testdb");

786

System.out.println("Database connection established");

787

}

788

789

@Override

790

public void destroy() throws Exception {

791

// Clean up resources

792

if (connection != null && !connection.isClosed()) {

793

connection.close();

794

System.out.println("Database connection closed");

795

}

796

}

797

}

798

799

// Annotation-based lifecycle

800

@Component

801

public class CacheManager {

802

803

private Map<String, Object> cache;

804

805

@PostConstruct

806

public void initializeCache() {

807

this.cache = new ConcurrentHashMap<>();

808

loadInitialData();

809

System.out.println("Cache initialized");

810

}

811

812

@PreDestroy

813

public void clearCache() {

814

if (cache != null) {

815

cache.clear();

816

System.out.println("Cache cleared");

817

}

818

}

819

820

private void loadInitialData() {

821

// Load initial cache data

822

}

823

}

824

825

// Bean method lifecycle configuration

826

@Configuration

827

public class ServiceConfig {

828

829

@Bean(initMethod = "start", destroyMethod = "stop")

830

public NetworkService networkService() {

831

return new NetworkService();

832

}

833

}

834

```

835

836

### Custom Scopes and Factory Beans

837

838

```java { .api }

839

// Custom FactoryBean

840

@Component

841

public class ConnectionFactoryBean implements FactoryBean<Connection> {

842

843

@Value("${db.url}")

844

private String url;

845

846

@Value("${db.username}")

847

private String username;

848

849

@Value("${db.password}")

850

private String password;

851

852

@Override

853

public Connection getObject() throws Exception {

854

return DriverManager.getConnection(url, username, password);

855

}

856

857

@Override

858

public Class<?> getObjectType() {

859

return Connection.class;

860

}

861

862

@Override

863

public boolean isSingleton() {

864

return false; // New connection each time

865

}

866

}

867

868

// Custom scope (thread scope example)

869

public class ThreadScope implements Scope {

870

871

private final ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<Map<String, Object>>() {

872

@Override

873

protected Map<String, Object> initialValue() {

874

return new HashMap<>();

875

}

876

};

877

878

@Override

879

public Object get(String name, ObjectFactory<?> objectFactory) {

880

Map<String, Object> scope = threadLocal.get();

881

Object obj = scope.get(name);

882

if (obj == null) {

883

obj = objectFactory.getObject();

884

scope.put(name, obj);

885

}

886

return obj;

887

}

888

889

@Override

890

public Object remove(String name) {

891

return threadLocal.get().remove(name);

892

}

893

894

@Override

895

public void registerDestructionCallback(String name, Runnable callback) {

896

// Implementation depends on requirements

897

}

898

899

@Override

900

public Object resolveContextualObject(String key) {

901

return null;

902

}

903

904

@Override

905

public String getConversationId() {

906

return Thread.currentThread().getName();

907

}

908

}

909

910

// Register custom scope

911

@Configuration

912

public class ScopeConfig implements BeanFactoryPostProcessor {

913

914

@Override

915

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

916

beanFactory.registerScope("thread", new ThreadScope());

917

}

918

}

919

```

920

921

## Error Handling

922

923

### Common Exceptions

924

925

```java { .api }

926

// Bean creation failures

927

try {

928

MyService service = applicationContext.getBean(MyService.class);

929

} catch (NoSuchBeanDefinitionException e) {

930

// Bean not found

931

log.error("Bean not found: " + e.getMessage());

932

} catch (NoUniqueBeanDefinitionException e) {

933

// Multiple beans found when expecting one

934

log.error("Multiple beans found: " + e.getMessage());

935

} catch (BeanCreationException e) {

936

// Bean creation failed

937

log.error("Bean creation failed: " + e.getMessage(), e);

938

} catch (UnsatisfiedDependencyException e) {

939

// Dependency injection failed

940

log.error("Unsatisfied dependency: " + e.getMessage(), e);

941

}

942

943

// ApplicationContext initialization

944

try {

945

ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

946

} catch (BeanDefinitionStoreException e) {

947

// Invalid bean definitions

948

log.error("Invalid bean definition: " + e.getMessage(), e);

949

} catch (ApplicationContextException e) {

950

// Context initialization failed

951

log.error("Context initialization failed: " + e.getMessage(), e);

952

}

953

```

954

955

The Core Container provides the foundation for all Spring applications, offering powerful dependency injection, comprehensive lifecycle management, and flexible configuration options through annotations or Java configuration classes.