Internals, module map, deployment topology, configuration reference, security posture, and operations playbook for the Spring Framework codebase. Audience: developers, architects, contributors, and operators who need to understand what Spring is doing under the hood, how to operate Spring-based applications safely, and how to navigate the source tree.
1. Executive Summary
Spring Framework is a multi-module, layered, reflection-and-AOP-driven JVM platform that provides Inversion-of-Control containers, declarative transactions, the Spring MVC and Spring WebFlux web stacks, the TestContext framework, and integration modules for messaging, scheduling, caching, JMS, JMX, mail, and observability. It is the foundation of the Spring portfolio (Boot, Security, Data, Cloud, Batch, etc.).
| Metric | Value |
|---|---|
| Source commit | 5e6e223 (2026-04-23) |
| Total files | 11,143 |
| Total source characters | 23,434,516 |
| Complexity tier | Massive |
| Primary language | Java (with first-class Kotlin support) |
| Build system | Gradle multi-module (custom plugins in buildSrc/) |
| Minimum JDK | 17 (compile target 17+; Java 21 multi-release JARs for virtual threads) |
| Jakarta EE baseline | Jakarta EE 10+ (jakarta.* namespace) |
| License | Apache License 2.0 |
Important
Spring Framework 7.x requires Jakarta EE 10+ APIs (
jakarta.*namespace). Applications still onjavax.*must migrate before upgrading. This is a hard breaking change from the 5.x era.
What This Guide Covers
This Admin Guide targets three personas:
- Operators deploying and tuning Spring-based applications in production — configuration knobs, JVM flags, connection pool sizing, thread pool tuning, health probes.
- Architects evaluating Spring for new projects or auditing existing ones — module dependency graph, extension points, security boundaries, concurrency model.
- Contributors and framework developers navigating the source tree — build system, code conventions, test infrastructure, release process.
2. Architecture Overview
2.1 Layered Module Architecture
Spring Framework follows a strict layered dependency model. Lower layers never depend on higher layers. The entire framework compiles from a single Gradle multi-module build rooted at build.gradle.
┌─────────────────────────────────────────────────────────────────┐
│ APPLICATION LAYER │
│ spring-webmvc · spring-webflux · spring-websocket · spring-jms │
│ spring-messaging · spring-orm · spring-oxm │
├─────────────────────────────────────────────────────────────────┤
│ DATA ACCESS LAYER │
│ spring-jdbc · spring-r2dbc · spring-tx │
├─────────────────────────────────────────────────────────────────┤
│ CONTAINER LAYER │
│ spring-context · spring-context-support · spring-context-indexer│
│ spring-aop · spring-aspects · spring-instrument │
├─────────────────────────────────────────────────────────────────┤
│ CORE LAYER │
│ spring-core · spring-beans · spring-expression · spring-core-test│
├─────────────────────────────────────────────────────────────────┤
│ BOM / PLATFORM │
│ framework-bom · framework-platform │
├─────────────────────────────────────────────────────────────────┤
│ BUILD INFRASTRUCTURE │
│ buildSrc (6 custom Gradle plugins) · framework-docs (Antora) │
└─────────────────────────────────────────────────────────────────┘
2.2 Module Inventory
The framework contains 22 publishable modules plus build and documentation infrastructure. Every module ships as a separate JAR with its own module-info.java (JPMS support).
| Module | Layer | Purpose | Key Packages |
|---|---|---|---|
spring-core |
Core | Type conversion, resource abstraction, environment, annotation utils, CGLIB repackaging, jspecify nullability | o.s.core, o.s.cglib, o.s.util, o.s.asm |
spring-beans |
Core | BeanFactory, BeanDefinition, PropertyEditor, factory config | o.s.beans.factory.config, o.s.beans.factory.support |
spring-expression |
Core | SpEL parser, compiler, evaluation context | o.s.expression, o.s.expression.spel |
spring-core-test |
Core | Test utilities for AOT and runtime hints verification | o.s.aot.test, o.s.core.test |
spring-aop |
Container | AOP Alliance integration, AspectJ auto-proxying, advisor adapters | o.s.aop.framework, o.s.aop.config, o.s.aop.aspectj |
spring-aspects |
Container | AspectJ compile-time weaving aspects for @Transactional, @Configurable |
o.s.scheduling.aspectj, o.s.transaction.aspectj |
spring-instrument |
Container | JVM agent for class instrumentation / load-time weaving | o.s.instrument |
spring-context |
Container | ApplicationContext, lifecycle, events, scheduling, caching, scripting, EJB/JNDI | o.s.context, o.s.scheduling.config, o.s.cache.config |
spring-context-support |
Container | JCache, Quartz, mail, FreeMarker integration | o.s.cache.jcache, o.s.scheduling.quartz |
spring-context-indexer |
Container | Compile-time component index generator (META-INF/spring.components) |
o.s.context.index |
spring-tx |
Data Access | PlatformTransactionManager, @Transactional, reactive tx, JTA |
o.s.transaction, o.s.transaction.config |
spring-jdbc |
Data Access | JdbcTemplate, JdbcClient, NamedParameterJdbcTemplate, embedded DB, config |
o.s.jdbc.core, o.s.jdbc.config |
spring-r2dbc |
Data Access | R2dbcOperations, DatabaseClient, reactive row mapping |
o.s.r2dbc.core, o.s.r2dbc.connection |
spring-orm |
Application | JPA/Hibernate integration, EntityManagerFactory setup, OpenEntityManagerInView |
o.s.orm.jpa |
spring-oxm |
Application | XML marshalling (JAXB2) abstraction | o.s.oxm, o.s.oxm.config |
spring-jms |
Application | JMS template, listener containers, @JmsListener |
o.s.jms.core, o.s.jms.config, o.s.jms.listener |
spring-messaging |
Application | Message abstraction, STOMP/SIMP broker, channel interceptors | o.s.messaging.core, o.s.messaging.simp.config |
spring-web |
Application | HTTP abstractions, RestClient, WebClient, HTTP interface proxies, multipart, codec |
o.s.web, o.s.http, o.s.web.service.registry |
spring-webmvc |
Application | DispatcherServlet, handler mapping, view resolution, MVC config | o.s.web.servlet, o.s.web.servlet.config |
spring-webflux |
Application | Reactive web stack, DispatcherHandler, functional endpoints, API versioning |
o.s.web.reactive, o.s.web.reactive.config |
spring-websocket |
Application | WebSocket/SockJS server support, STOMP messaging | o.s.web.socket, o.s.web.socket.config |
spring-test |
Cross-cutting | TestContext, MockMvc, WebTestClient, bean override, AOT test support |
o.s.test.context, o.s.test.web |
Note
Package prefix
o.s.is shorthand fororg.springframework.throughout this guide.
2.3 BOM and Platform Modules
Two non-code modules manage dependency alignment across the ecosystem:
framework-bom— Bill of Materials importing all 22 Spring Framework module JARs at the same version. Consumers import this in their<dependencyManagement>to avoid version mismatches.framework-platform— Enforced platform (GradleenforcedPlatform) that pins all third-party dependency versions used by the framework's own modules. Everyspring-*module inherits this via the rootbuild.gradleconfiguration.
2.4 Build Infrastructure (buildSrc/)
The build uses 6 custom Gradle plugins defined in buildSrc/:
| Plugin ID | Class | Purpose |
|---|---|---|
org.springframework.architecture |
ArchitecturePlugin |
ArchUnit rules enforcing module boundaries and package layering |
org.springframework.build.conventions |
ConventionsPlugin |
Java compilation settings, Javadoc config, checkstyle, test configuration |
org.springframework.build.localdev |
LocalDevelopmentPlugin |
Local dev overrides (snapshot repos, changed-module caching) |
org.springframework.build.multiReleaseJar |
MultiReleaseJarPlugin |
Multi-release JAR packaging (Java 21 code under src/main/java21/) |
org.springframework.build.optional-dependencies |
OptionalDependenciesPlugin |
optional configuration scope for compile-only dependencies |
org.springframework.build.runtimehints-agent |
RuntimeHintsAgentPlugin |
GraalVM runtime hints agent for AOT metadata validation |
Additional build tooling:
- Checkstyle — Spring Java Format (
io.spring.javaformat) enforced viabuildSrcand checked at JAR time (jar.dependsOn check). - Dokka — Kotlin documentation generation via
org.jetbrains.dokkaplugin. - AspectJ —
io.freefair.aspectjplugin (version 8.13.1) applied selectively for CTW modules. - JMH —
me.champeau.jmhplugin for micro-benchmarks (spring-core/src/jmh/). - Nullability —
io.spring.nullabilityplugin (0.0.11) for jspecify@Nullable/@NonNullenforcement.
2.5 Dependency Resolution Strategy
// From root build.gradle — ALL subprojects inherit this:
configurations.all {
resolutionStrategy {
cacheChangingModulesFor 0, "seconds" // SNAPSHOT never cached
cacheDynamicVersionsFor 0, "seconds" // dynamic versions always re-resolved
}
}
Repository resolution order:
- Maven Central (always)
https://repo.spring.io/milestone— only for milestone versions (version contains-)https://repo.spring.io/snapshot— only for SNAPSHOT versions
2.6 Documentation Infrastructure
Spring Framework uses Antora (version 3.2.0-alpha.11) for its reference documentation site:
framework-docs/antora-playbook.yml— multi-branch site build (branches:6.2.x,7.0.xthrough9.x)framework-docs/antora.yml— module attributes, asciidoc extensions- Extensions:
@antora/collector-extension,@springio/antora-extensions,@asciidoctor/tabs - Example code lives in
framework-docs/src/main/java/andframework-docs/src/main/kotlin/
3. System Requirements
3.1 JDK Requirements
| Spring Framework | Minimum JDK | Recommended JDK | Notes |
|---|---|---|---|
| 7.0.x | 17 | 21+ | Virtual thread support via multi-release JARs |
| 6.2.x | 17 | 21 | LTS maintenance branch |
Warning
Spring Framework 7.x ships multi-release JARs with Java 21-specific code in
META-INF/versions/21/. Running on JDK 17 is supported but misses virtual thread optimizations and structured concurrency integration.
3.2 Jakarta EE Baseline
Spring Framework 7.0 requires Jakarta EE 10+ APIs:
| API | Minimum Version | Maven Coordinates |
|---|---|---|
| Servlet | 6.0+ | jakarta.servlet:jakarta.servlet-api |
| JPA | 3.1+ | jakarta.persistence:jakarta.persistence-api |
| Bean Validation | 3.0+ | jakarta.validation:jakarta.validation-api |
| JMS | 3.1+ | jakarta.jms:jakarta.jms-api |
| JTA | 2.0+ | jakarta.transaction:jakarta.transaction-api |
| WebSocket | 2.1+ | jakarta.websocket:jakarta.websocket-api |
| Annotation | 2.1+ | jakarta.annotation:jakarta.annotation-api |
| JSON Binding | 3.0+ | jakarta.json.bind:jakarta.json.bind-api |
| 2.1+ | jakarta.mail:jakarta.mail-api |
3.3 Third-Party Dependencies
Key runtime dependencies (versions pinned by framework-platform):
| Library | Purpose | Used By |
|---|---|---|
Project Reactor (reactor-core) |
Reactive Streams implementation | spring-webflux, spring-r2dbc, spring-messaging |
| Kotlin stdlib + coroutines | Kotlin language support + suspend function bridges |
All modules with Kotlin extensions |
| Jackson | JSON serialization | spring-web, spring-webmvc, spring-webflux |
| CGLIB (repackaged) | Runtime proxy generation | spring-core (internal repackage at o.s.cglib) |
| ASM (repackaged) | Bytecode analysis for annotation metadata | spring-core (internal repackage at o.s.asm) |
| jspecify | Nullability annotations | All modules |
| SLF4J / Log4j 2 | Logging abstraction | Test runtime; production uses commons-logging bridge |
| Hibernate ORM 7.2 | JPA provider | spring-orm (optional) |
3.4 Application Server Compatibility
Caution
Spring Framework 7.0.5 introduced changes that may break certification with some application servers (see GitHub issue #36617). Verify compatibility with your target server before upgrading.
Tested server runtimes:
- Apache Tomcat 11.0+
- Eclipse Jetty 12+
- GlassFish 8+ / Eclipse GlassFish
- WildFly 33+ (Jakarta EE 11)
- Undertow 2.4+ (standalone)
4. Configuration Reference
4.1 XML Namespace Reference
Spring defines several XML namespaces, each backed by NamespaceHandler implementations that register BeanDefinitionParser classes. These are the namespaces available and their elements (from source code):
context Namespace (ContextNamespaceHandler)
URI: http://www.springframework.org/schema/context
| Element | Purpose |
|---|---|
<context:property-placeholder> |
Register PropertySourcesPlaceholderConfigurer for ${...} resolution |
<context:property-override> |
Override bean properties from an external .properties file |
<context:annotation-config> |
Enable @Autowired, @PostConstruct, @Resource, @Value processing |
<context:component-scan> |
Classpath scanning for @Component, @Service, @Repository, @Controller |
<context:load-time-weaver> |
Register LoadTimeWeaver for AspectJ LTW |
<context:spring-configured> |
Enable @Configurable domain object DI (requires AspectJ) |
<context:mbean-export> |
Export Spring beans as JMX MBeans |
<context:mbean-server> |
Locate or create an MBeanServer |
tx Namespace (Transaction)
URI: http://www.springframework.org/schema/tx
| Element | Purpose |
|---|---|
<tx:annotation-driven> |
Enable @Transactional processing (proxy or aspectj mode) |
<tx:advice> |
Declarative transaction advice for AOP pointcut binding |
<tx:jta-transaction-manager> |
Register JTA-aware PlatformTransactionManager |
Key attributes on <tx:annotation-driven>:
transaction-manager— bean name of thePlatformTransactionManager(default:transactionManager)mode—proxy(default, JDK dynamic proxies) oraspectj(compile-time/load-time weaving)proxy-target-class—trueforces CGLIB class-based proxies instead of interface-based
task Namespace (Scheduling)
URI: http://www.springframework.org/schema/task
| Element | Purpose |
|---|---|
<task:annotation-driven> |
Enable @Async and @Scheduled annotation processing |
<task:executor> |
Define a ThreadPoolTaskExecutor bean |
<task:scheduler> |
Define a ThreadPoolTaskScheduler bean |
<task:scheduled-tasks> |
Declarative cron/fixed-rate/fixed-delay task definitions |
Attributes on <task:annotation-driven>:
executor— bean reference for@Asyncexecutionscheduler— bean reference for@Scheduledexecutionexception-handler—AsyncUncaughtExceptionHandlerbean referencemode—proxyoraspectj
aop Namespace
URI: http://www.springframework.org/schema/aop
| Element | Purpose |
|---|---|
<aop:config> |
Top-level AOP configuration container |
<aop:aspectj-autoproxy> |
Enable @AspectJ annotation-driven auto-proxying |
<aop:advisor> |
Bind an Advice to a pointcut |
<aop:aspect> |
Declare an aspect with pointcuts and advice |
<aop:pointcut> |
Named pointcut expression |
cache Namespace
URI: http://www.springframework.org/schema/cache
| Element | Purpose |
|---|---|
<cache:annotation-driven> |
Enable @Cacheable, @CacheEvict, @CachePut |
<cache:advice> |
Declarative cache advice |
jms Namespace
URI: http://www.springframework.org/schema/jms
| Element | Purpose |
|---|---|
<jms:listener-container> |
Define a DefaultMessageListenerContainer factory |
<jms:listener> |
Individual message listener binding |
<jms:jca-listener-container> |
JCA-based listener container |
jdbc Namespace (DatabasePopulatorConfigUtils)
URI: http://www.springframework.org/schema/jdbc
| Element | Purpose |
|---|---|
<jdbc:embedded-database> |
Create an in-memory H2/HSQL/Derby database with init scripts |
<jdbc:initialize-database> |
Run SQL scripts against an existing DataSource |
Attributes on <jdbc:initialize-database>:
data-source—DataSourcebean referenceignore-failures—NONE(default),DROPS, orALLseparator— SQL statement separator (default:;)
websocket Namespace
URI: http://www.springframework.org/schema/websocket
| Element | Purpose |
|---|---|
<websocket:handlers> |
Register WebSocket handler mappings |
<websocket:message-broker> |
Configure STOMP message broker relay |
4.2 Java Configuration
Java-based configuration supersedes XML in modern Spring applications. The key entry points:
Core Container
@Configuration
@ComponentScan("com.example")
@PropertySource("classpath:app.properties")
public class AppConfig {
@Bean
public DataSource dataSource() { /* ... */ }
}
| Annotation | Purpose |
|---|---|
@Configuration |
Marks class as bean definition source (CGLIB-proxied by default for singleton semantics) |
@Bean |
Factory method for a bean definition |
@ComponentScan |
Classpath scanning (equivalent to <context:component-scan>) |
@PropertySource |
Load .properties / .yml into Environment |
@Profile |
Conditional bean registration by active profile |
@Conditional |
Programmatic condition (basis for Boot's auto-configuration) |
@Import |
Import additional @Configuration classes |
@ImportResource |
Bridge XML config into Java config |
@Lazy |
Defer bean initialization until first access |
@DependsOn |
Explicit bean initialization ordering |
@Primary |
Preferred bean when multiple candidates exist |
@Qualifier |
Disambiguation by name |
@Scope |
Bean scope: singleton (default), prototype, request, session, application |
@Order / @Priority |
Bean ordering for lists and event listeners |
Web MVC Configuration
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
}
}
@EnableWebMvc imports DelegatingWebMvcConfiguration, which auto-registers:
RequestMappingHandlerMappingandRequestMappingHandlerAdapterExceptionHandlerExceptionResolver- All detected
HttpMessageConverterimplementations (Jackson, JAXB, Atom, RSS, etc.) FormattingConversionServicewith standard formattersValidator(Bean Validation if on classpath)ContentNegotiationManager
Note
The
AnnotationDrivenBeanDefinitionParserinspring-webmvcauto-detects message converters by classpath presence — Jackson →MappingJackson2HttpMessageConverter, JAXB →Jaxb2RootElementHttpMessageConverter, etc. No explicit registration is needed for standard formats.
WebFlux Configuration
@Configuration
@EnableWebFlux
public class WebFluxConfig implements WebFluxConfigurer {
@Override
public void configureApiVersioning(ApiVersionConfigurer configurer) {
configurer.useRequestHeader("X-API-Version")
.useQueryParam("version")
.setDefaultVersion("1.0");
}
}
Important
ApiVersionConfigureris new in Spring Framework 7.0. It supports four strategies:useRequestHeader(),useQueryParam(),usePathSegment(), anduseMediaTypeParameter(). A customsetVersionParser()can handle non-numeric version schemes.
Transaction Configuration
@Configuration
@EnableTransactionManagement // mode = AdviceMode.PROXY by default
public class TxConfig {
@Bean
public PlatformTransactionManager transactionManager(DataSource ds) {
return new DataSourceTransactionManager(ds);
}
}
@EnableTransactionManagement attributes:
mode—AdviceMode.PROXY(default) orAdviceMode.ASPECTJproxyTargetClass—false(JDK proxies) ortrue(CGLIB proxies)order— Advisor ordering (default:Ordered.LOWEST_PRECEDENCE)
The transaction infrastructure registers:
BeanFactoryTransactionAttributeSourceAdvisorTransactionInterceptorTransactionalEventListenerFactory(for@TransactionalEventListener)
Scheduling Configuration
@Configuration
@EnableScheduling
@EnableAsync
public class SchedulingConfig implements SchedulingConfigurer, AsyncConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar registrar) {
registrar.setScheduler(taskScheduler());
}
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(25);
executor.setThreadNamePrefix("async-");
executor.initialize();
return executor;
}
}
Cache Configuration
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("users", "products");
}
}
4.3 Environment & Profiles
Spring's Environment abstraction provides:
- Property sources — ordered list (
System.getProperties()→System.getenv()→@PropertySourcefiles → servlet config/context) - Active profiles — activated via
spring.profiles.activesystem property, env var, or programmatically - Default profiles — fallback when no profile is active (
spring.profiles.default)
Profile activation methods:
# JVM argument
-Dspring.profiles.active=prod,monitoring
# Environment variable
SPRING_PROFILES_ACTIVE=prod,monitoring
# Programmatic
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("prod", "monitoring");
ctx.register(AppConfig.class);
ctx.refresh();
4.4 SpEL (Spring Expression Language)
SpEL is used in @Value annotations, XML configuration, security expressions, and cache key generation. Key capabilities:
| Feature | Example |
|---|---|
| Property access | #{systemProperties['user.home']} |
| Method invocation | #{T(java.lang.Math).random()} |
| Ternary operator | #{age > 18 ? 'adult' : 'minor'} |
| Elvis operator | #{name ?: 'Unknown'} |
| Safe navigation | #{person?.address?.city} |
| Collection projection | #{members.![name]} |
| Collection selection | #{members.?[age > 18]} |
| Bean reference | #{@myBean.value} |
The SpEL compiler (SpelCompiler) can compile expressions to bytecode for improved evaluation performance. Enable via SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, classLoader).
5. Deployment & Operations
5.1 Deployment Models
Spring Framework supports multiple deployment topologies:
| Model | Stack | Entry Point |
|---|---|---|
| Embedded server (typical) | Spring Boot wrapping Spring Framework | SpringApplication.run() → embedded Tomcat/Jetty/Undertow |
| WAR deployment | Traditional servlet container | web.xml or AbstractAnnotationConfigDispatcherServletInitializer |
| Reactive server | Netty / Undertow (reactive) | AbstractReactiveWebInitializer → HttpHandler adapter |
| Non-web | Standalone JVM process | AnnotationConfigApplicationContext / GenericXmlApplicationContext |
Note
AbstractReactiveWebInitializer(inspring-web) bridges the reactiveHttpHandlerto a Servlet 6.0+ container viaServletHttpHandlerAdapter. It implementsServletContainerInitializerfor zero-XML deployment.
5.2 Thread Pool Tuning
MVC Thread Model (Servlet-based)
Spring MVC uses the servlet container's thread pool. Tune these at the container level:
| Parameter | Tomcat Default | Recommended (Production) |
|---|---|---|
maxThreads |
200 | Scale by CPU: 2 × cores for CPU-bound, higher for I/O-bound |
minSpareThreads |
10 | Match expected baseline load |
acceptCount |
100 | Queue depth for connection backlog |
connectionTimeout |
20000 ms | Reduce for microservices (5000-10000 ms) |
WebFlux Thread Model (Reactive)
WebFlux uses a small, fixed event-loop pool (Reactor Netty default: Runtime.availableProcessors() threads). The key principle: never block the event loop.
| Parameter | Default | Notes |
|---|---|---|
| Event loop threads | CPU cores | reactor.netty.ioWorkerCount system property |
| Scheduler pool | Schedulers.parallel() |
CPU-bound work; size = CPU cores |
| Bounded elastic pool | Schedulers.boundedElastic() |
Blocking I/O offloading; capped at 10 × cores |
Task Execution Thread Pools
@Bean
public ThreadPoolTaskExecutor applicationTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(100);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("app-exec-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(30);
return executor;
}
5.3 Connection Pool Sizing
For JDBC applications (spring-jdbc, spring-orm):
| Parameter | Guidance |
|---|---|
maximumPoolSize |
connections = threads × (1 - blocking_ratio) as baseline; HikariCP recommends (2 × CPU cores) + spindle_count |
minimumIdle |
Match maximumPoolSize for consistent performance (HikariCP default) |
connectionTimeout |
30000 ms default; reduce for fail-fast microservices |
idleTimeout |
600000 ms (10 min); must be less than DB's wait_timeout |
maxLifetime |
1800000 ms (30 min); must be less than DB's connection TTL |
For R2DBC applications (spring-r2dbc):
| Parameter | Guidance |
|---|---|
initialSize |
Match steady-state concurrent queries |
maxSize |
Limit by DB max connections / number of app instances |
maxIdleTime |
Keep below DB idle timeout |
5.4 Caching Operations
Spring's cache abstraction (@Cacheable, @CacheEvict, @CachePut) is provider-agnostic. Production providers:
| Provider | Maven Artifact | CacheManager Implementation |
|---|---|---|
| Caffeine | com.github.ben-manes.caffeine:caffeine |
CaffeineCacheManager |
| Redis | org.springframework.data:spring-data-redis |
RedisCacheManager |
| Ehcache 3 | org.ehcache:ehcache |
JCacheCacheManager |
| Hazelcast | com.hazelcast:hazelcast |
HazelcastCacheManager |
| Simple (dev only) | Built-in | ConcurrentMapCacheManager |
Caution
ConcurrentMapCacheManagerhas no eviction, no TTL, and unbounded memory growth. Use only for development/testing. TheCacheErrorHandlerinterface (configured viaCachingConfigurer.errorHandler()) controls behavior when cache operations fail — the default propagates exceptions.
5.5 Health & Observability
Spring Framework provides hooks for observability (expanded by Spring Boot Actuator):
SmartLifecycle— phased startup/shutdown ordering; implementgetPhase()to control sequenceHealthIndicator(Boot) — exposesDataSource, JMS, mail healthMeterBinder(Micrometer) — auto-instrumentsJdbcTemplate,RestClient,WebClient- Lifecycle events —
ContextRefreshedEvent,ContextStartedEvent,ContextStoppedEvent,ContextClosedEvent - Graceful shutdown —
SmartLifecycle.stop(Runnable callback)withsetPhase()ordering
5.6 JVM Flags for Production
# Essential for Spring Framework applications
-XX:+UseG1GC # Or ZGC for low-latency
-XX:MaxGCPauseMillis=200
-Xms2g -Xmx2g # Avoid heap resizing
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/var/log/app/
# Spring-specific
-Dspring.profiles.active=prod
-Dspring.jmx.enabled=false # Disable JMX unless needed (saves ~50ms startup)
-Dspring.aop.proxy-target-class=true # CGLIB proxies (avoids interface-only proxy issues)
# Virtual threads (JDK 21+)
-Dspring.threads.virtual.enabled=true # Spring Boot property; Framework uses multi-release JARs
6. Security Analysis
6.1 Security Architecture
Spring Framework provides security building blocks but delegates comprehensive security to Spring Security. The framework-level security surface includes:
| Area | Mechanism | Module |
|---|---|---|
| CORS | CorsConfiguration, @CrossOrigin, CorsRegistry |
spring-web, spring-webmvc, spring-webflux |
| CSRF | Not built-in — Spring Security's CsrfFilter |
External |
| Input validation | Bean Validation integration (@Valid, @Validated), DataBinder |
spring-context, spring-web |
| SQL injection | JdbcTemplate parameterized queries, NamedParameterJdbcTemplate |
spring-jdbc |
| XSS | No built-in output encoding — use template engine escaping | N/A |
| Static resources | ResourceHttpRequestHandler path traversal protection |
spring-webmvc, spring-webflux |
| Serialization | Jackson ObjectMapper (no default typing), no Java serialization by default |
spring-web |
| WebSocket origin | OriginHandshakeInterceptor enforces allowed-origins |
spring-websocket |
Warning
GitHub issue #36695 led to rejection of unsafe static resource locations in MVC and WebFlux. Ensure resource handler paths do not expose sensitive directories. Always constrain
addResourceLocations()to specific, known-safe paths.
6.2 Input Validation
Spring integrates Bean Validation (Jakarta Validation 3.0+) at three levels:
- Controller parameter validation —
@Valid/@Validatedon@RequestBody,@ModelAttribute - Method-level validation —
@Validatedon service classes activatesMethodValidationPostProcessor - Configuration properties —
@ConfigurationPropertieswith@Validated(Spring Boot)
The ModelAttributeMethodArgumentResolver performs binding and validation. Extension points validateIfApplicable() and isBindExceptionRequired() are available for customization (GitHub issue #36690 proposes making these protected).
6.3 CORS Configuration
@Configuration
@EnableWebMvc
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("https://app.example.com")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("Authorization", "Content-Type")
.allowCredentials(true)
.maxAge(3600);
}
}
Caution
Never use
allowedOrigins("*")withallowCredentials(true)— this is rejected by browsers and Spring will throw an error. UseallowedOriginPatterns("*")if you genuinely need wildcard patterns with credentials.
6.4 Transaction Security
The @Transactional annotation controls propagation, isolation, and rollback:
| Attribute | Default | Security Implication |
|---|---|---|
propagation |
REQUIRED |
Joins existing tx — data visibility inherited |
isolation |
DEFAULT (DB default) |
READ_UNCOMMITTED can leak uncommitted data; prefer READ_COMMITTED or higher |
readOnly |
false |
Set true for queries; some JDBC drivers optimize, some DBs enforce |
rollbackFor |
RuntimeException, Error |
Checked exceptions do NOT trigger rollback by default |
timeout |
-1 (none) | Long-running tx hold locks; set explicit timeouts |
6.5 Serialization Safety
- Jackson — Spring auto-configures
MappingJackson2HttpMessageConverterwithout default typing. Do not enableObjectMapper.enableDefaultTyping()— it is a known deserialization gadget attack vector. - Java serialization — Not used by default for HTTP. If you expose
Serializableobjects via JMS or RMI, ensureSerializationUtilsorAllowedClassesObjectInputStreamwhitelisting is in place. - STOMP/WebSocket — Message payloads are deserialized via configured
MessageConverterimplementations; ensure Jackson (not Java serialization) is used.
6.6 Secrets Management
Spring Framework's Environment abstraction reads secrets from:
- System properties (
-Ddb.password=...) — visible in process listings - Environment variables (
DB_PASSWORD) — preferred for containers @PropertySourcefiles — do not commit to version control- JNDI (application server managed) — strongest isolation for WAR deployments
Important
Spring Framework itself does not provide secret encryption or vault integration. Use Spring Cloud Vault, HashiCorp Vault, AWS Secrets Manager, or similar for production secret management. Never store secrets in
application.propertiesfiles committed to source control.
7. Performance
7.1 AOT (Ahead-of-Time) Processing
Spring Framework 6+ includes AOT compilation support for GraalVM native images:
BeanFactoryInitializationAotProcessor— generates code to replace runtime reflectionRuntimeHints— declare reflection, resources, serialization, and JNI hintsRuntimeHintsAgent(buildSrc plugin) — validates hints against actual runtime access patterns- Component Index (
spring-context-indexer) — compile-timeMETA-INF/spring.componentsavoids classpath scanning
7.2 SpEL Compilation
The SpEL compiler converts interpreted expressions to bytecode:
| Mode | Behavior |
|---|---|
OFF (default) |
Interpreted evaluation |
IMMEDIATE |
Compile on first evaluation |
MIXED |
Interpret first, compile after threshold; falls back on error |
Enable globally: -Dspring.expression.compiler.mode=MIXED
7.3 Bean Initialization Optimization
| Technique | Impact | How |
|---|---|---|
| Lazy initialization | Faster startup | @Lazy on beans or defaultLazyInit="true" on <beans> |
| Component index | Eliminates classpath scanning | Add spring-context-indexer to annotation processor path |
| Constructor injection | Avoids reflection for field injection | Use @Autowired on constructor (or single-constructor auto-detection) |
@Conditional |
Skip unnecessary beans | Programmatic conditions on configuration classes |
7.4 HTTP Client Performance
| Client | Threading Model | When to Use |
|---|---|---|
RestClient (7.0+) |
Blocking (servlet thread) | MVC apps, synchronous APIs |
WebClient |
Non-blocking (Reactor event loop) | WebFlux apps, high-concurrency I/O |
RestTemplate |
Blocking (deprecated for new code) | Legacy compatibility only |
HTTP Interface (@HttpExchange) |
Either (depends on backing client) | Declarative API clients |
The HttpServiceProxyRegistry (new in 7.0, via @ImportHttpServices) manages HTTP Interface client proxies organized by HttpServiceGroup. Each group binds to either a RestClient or WebClient instance.
8. Troubleshooting
8.1 Container Startup Issues
| Symptom | Likely Cause | Fix |
|---|---|---|
NoSuchBeanDefinitionException |
Missing @ComponentScan, wrong base package, missing @Configuration |
Verify scan paths; check @Conditional evaluations |
BeanCurrentlyInCreationException |
Circular dependency | Refactor to break cycle; use @Lazy on one injection point |
BeanNotOfRequiredTypeException |
Proxy type mismatch (JDK vs CGLIB) | Set proxy-target-class="true" or inject by interface |
| Slow startup (>30s) | Classpath scanning thousands of classes | Use spring-context-indexer; narrow @ComponentScan base packages |
UnsatisfiedDependencyException with generics |
Type erasure losing generic info | Use ResolvableType or @Qualifier |
8.2 Web Tier Issues
| Symptom | Likely Cause | Fix |
|---|---|---|
| 404 on all endpoints | Missing @EnableWebMvc or DispatcherServlet not mapped |
Check servlet registration; verify @RequestMapping paths |
HttpMediaTypeNotSupportedException |
Missing message converter | Add Jackson/JAXB to classpath; check Content-Type header |
MockHttpServletRequest.isRequestedSessionIdValid() returns wrong value |
Servlet 6.1 behavior change | See #36631; update mock usage |
| Versioned resources drop path segments | Resource resolver bug | See #36699; upgrade to patched version |
@AliasFor behaving inconsistently |
Annotation synthesis edge case | See #36680; verify alias target declarations |
8.3 Data Access Issues
| Symptom | Likely Cause | Fix |
|---|---|---|
@Transactional ignored |
Calling @Transactional method from same class (self-invocation) |
Extract to separate bean; or use AspectJ mode |
@Sql fails with TransactionAwareDataSourceProxy |
Wrapper interferes with script runner DataSource lookup | See #36635; use unwrapped DataSource |
TransactionRequiredException in JPA |
Missing @Transactional on write operations |
Add @Transactional to service methods performing writes |
| Connection pool exhaustion | Threads blocked waiting; pool too small; leaked connections | Increase pool; add connection timeout; ensure @Transactional boundaries are tight |
8.4 Reactive Stack Issues
| Symptom | Likely Cause | Fix |
|---|---|---|
IllegalStateException: block()/blockFirst()/blockLast() |
Blocking call on non-blocking thread | Offload to Schedulers.boundedElastic(); refactor to reactive chain |
| Non-deterministic "Body token not expected" in multipart | PartGenerator concurrency issue |
See #36694; may require retry or version upgrade |
traceId not propagated to Kotlin coroutines |
Context not flowing through awaitExchange |
See #36182; use CoroutineContext propagation |
| Nullable Kotlin value classes fail in reactive query params | Value class unwrapping issue | See #36704 |
8.5 JMS Issues
| Symptom | Likely Cause | Fix |
|---|---|---|
| DLQ messages have null cause | DefaultMessageListenerContainer retry loses exception |
See #22817; implement custom ErrorHandler to capture cause |
| Duplicate message processing | Listener container restarts without commit | Configure sessionAcknowledgeMode to CLIENT_ACKNOWLEDGE; ensure tx-aware container |
8.6 Diagnostic Techniques
// Enable detailed bean loading logging
-Dlogging.level.org.springframework.beans.factory=DEBUG
// Trace AOP proxy creation
-Dlogging.level.org.springframework.aop=TRACE
// Log all SQL from JdbcTemplate
-Dlogging.level.org.springframework.jdbc.core=DEBUG
-Dlogging.level.org.springframework.jdbc.core.StatementCreatorUtils=TRACE
// WebFlux request/response logging
-Dlogging.level.org.springframework.web.reactive=DEBUG
// Transaction logging
-Dlogging.level.org.springframework.transaction=TRACE
9. Developer Internals
9.1 Source Tree Navigation
spring-framework/
├── build.gradle Root build (plugins, allprojects config, javadocLinks)
├── buildSrc/ 6 custom Gradle plugins
│ └── src/main/java/org/springframework/build/
│ ├── architecture/ ArchUnit layer rules
│ ├── ConventionsPlugin.java
│ ├── dev/ LocalDevelopmentPlugin
│ ├── hint/ RuntimeHintsAgentPlugin
│ ├── multirelease/ Multi-release JAR support
│ └── optional/ Optional dependency configuration
├── framework-bom/ BOM POM for consumers
├── framework-platform/ Enforced platform (3rd-party version pins)
├── framework-docs/ Antora documentation site
│ ├── antora-playbook.yml
│ ├── antora.yml
│ ├── package.json Antora + extensions
│ └── modules/ROOT/ AsciiDoc pages + code examples
├── spring-core/ Foundation: types, resources, env, CGLIB, ASM
├── spring-beans/ BeanFactory, BeanDefinition parsing, property editors
├── spring-expression/ SpEL parser + compiler
├── spring-aop/ AOP Alliance, AspectJ auto-proxy, advisor framework
├── spring-context/ ApplicationContext, events, scheduling, caching
├── spring-tx/ Transaction abstraction, @Transactional
├── spring-jdbc/ JdbcTemplate, JdbcClient, embedded DB
├── spring-r2dbc/ Reactive database client
├── spring-orm/ JPA/Hibernate integration
├── spring-web/ HTTP core, clients (RestClient, WebClient), codecs
├── spring-webmvc/ DispatcherServlet, MVC config, handler mapping
├── spring-webflux/ DispatcherHandler, reactive config, API versioning
├── spring-websocket/ WebSocket/SockJS, STOMP relay
├── spring-jms/ JMS template, listener containers
├── spring-messaging/ Message abstraction, STOMP/SIMP broker
├── spring-oxm/ XML marshalling
├── spring-context-support/ JCache, Quartz, mail, FreeMarker
├── spring-context-indexer/ Compile-time component index
├── spring-aspects/ AspectJ CTW aspects
├── spring-instrument/ JVM class instrumentation agent
├── spring-core-test/ AOT and runtime hints test utilities
├── spring-test/ TestContext, MockMvc, WebTestClient
├── integration-tests/ Cross-module integration tests
└── src/ IDE settings (IntelliJ, Eclipse), checkstyle, nohttp
9.2 Code Patterns
BeanDefinitionParser Pattern
Most XML namespace elements are handled by BeanDefinitionParser implementations. The standard pattern:
NamespaceHandler.init()registers element names → parser classes- Parser's
parse(Element, ParserContext)createsBeanDefinitionBuilderinstances - Parsers use
parserContext.getRegistry()to register beans atomically CompositeComponentDefinitiongroups related beans for tooling visibility
Example from AnnotationDrivenBeanDefinitionParser (task namespace):
// Registers AsyncAnnotationBeanPostProcessor (proxy mode)
// or AnnotationAsyncExecutionAspect (aspectj mode)
String mode = element.getAttribute("mode");
if ("aspectj".equals(mode)) {
registerAsyncExecutionAspect(element, parserContext);
} else {
// proxy mode - register BeanPostProcessor
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
"org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor");
builder.addPropertyReference("executor", executor);
// ...
}
Advisor Adapter Pattern (AOP)
The AOP framework uses an adapter pattern to bridge different advice types to the unified MethodInterceptor interface:
AdvisorAdapter— SPI for convertingAdvicetypes toMethodInterceptorDefaultAdvisorAdapterRegistry— ships adapters forBeforeAdvice,AfterReturningAdvice,ThrowsAdviceAdvisorAdapterRegistrationManager—BeanPostProcessorthat auto-registers customAdvisorAdapterbeans
HTTP Service Registry Pattern (7.0+)
The @ImportHttpServices + AbstractHttpServiceRegistrar pattern provides declarative HTTP client proxy registration:
AbstractHttpServiceRegistrarimplementsImportBeanDefinitionRegistrar- Scans for interfaces annotated with
@HttpExchange - Groups interfaces into
HttpServiceGroupinstances - Registers
HttpServiceProxyRegistryFactoryBeanto create proxies at runtime - Multiple registrar imports merge into a single registry
Event System
Spring's event system (spring-context) follows the observer pattern:
ApplicationEventPublisher— publish events@EventListener/ApplicationListener<E>— receive events@TransactionalEventListener— process after transaction commit/rollbackApplicationEventMulticaster— dispatches to listeners (default:SimpleApplicationEventMulticaster)@Async @EventListener— asynchronous event handling (requires@EnableAsync)
9.3 Testing Infrastructure
Spring's test module (spring-test) provides:
TestContext Framework
@SpringBootTest(Boot) /@ContextConfiguration— loadApplicationContextfor tests@MockitoBean,@MockitoSpyBean— bean override in context (new in 6.2+; strict stubbing support: #34419)@Sql— execute SQL scripts before/after test methods@ActiveProfiles— activate profiles for test context@DirtiesContext— mark context for re-creation (use sparingly — expensive)
MockMvc (MVC Testing)
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired MockMvc mockMvc;
@Test
void shouldReturnUser() throws Exception {
mockMvc.perform(get("/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("Alice"));
}
}
WebTestClient (WebFlux Testing)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ReactiveTest {
@Autowired WebTestClient client;
@Test
void shouldStreamEvents() {
client.get().uri("/events")
.accept(MediaType.TEXT_EVENT_STREAM)
.exchange()
.expectStatus().isOk()
.expectBodyList(Event.class).hasSize(3);
}
}
AOT Test Support
@DisabledInAotMode— skip tests incompatible with AOTRuntimeHintsPredicates— assert that runtime hints are correctly registeredTestCompiler(spring-core-test) — compile and load generated AOT code in tests
9.4 Kotlin Integration
Spring Framework provides first-class Kotlin support:
| Feature | Module | Details |
|---|---|---|
| Null-safety | All | jspecify annotations; Kotlin sees them as nullability markers |
| Extension functions | spring-jdbc, spring-r2dbc |
JdbcOperations.queryForObject<T>(), DatabaseClient extensions |
| Coroutine support | spring-webflux, spring-web |
suspend functions in controllers, Flow<T> return types |
| Bean DSL | spring-context |
beans { bean<MyService>() } functional registration |
| Router DSL | spring-webflux, spring-webmvc |
router { GET("/api") { ok().body(service.findAll()) } } |
@MockitoBean with Kotlin |
spring-test |
Works with value classes (with known issues: #36704) |
9.5 JPMS (Java Platform Module System)
Every spring-* module includes a module-info.java for JPMS compatibility. Key exports:
- Modules export their public API packages
- Internal packages use
exports ... tofor framework-internal access requires transitivefor API dependencies (e.g.,spring-beansrequires transitivespring-core)opensdirectives for reflection access (required by DI container)
9.6 Contributing & Build
Building from Source
# Clone
git clone https://github.com/spring-projects/spring-framework.git
cd spring-framework
# Full build (requires JDK 17+)
./gradlew build
# Skip tests
./gradlew build -x test
# Build specific module
./gradlew :spring-core:build
# Run checkstyle only
./gradlew checkstyleMain checkstyleTest
# Generate documentation site
cd framework-docs && npx antora antora-playbook.yml
Code Style
- Spring Java Format — enforced via checkstyle plugin at build time
- Tabs for indentation (not spaces)
- Import ordering:
java.*, blank line,javax.*/jakarta.*, blank line, all others - No wildcard imports
- Copyright header on all files:
Copyright 2002-present the original author or authors
Test Organization
| Directory | Purpose |
|---|---|
src/test/java/ |
Unit and integration tests |
src/test/kotlin/ |
Kotlin-specific tests |
src/test/resources/ |
Test XML configs, SQL scripts, property files |
src/testFixtures/java/ |
Shared test utilities published as test fixtures |
src/jmh/java/ |
JMH micro-benchmarks (spring-core only) |
10. Quick Reference
10.1 XML Namespace URIs
| Namespace | URI | Module |
|---|---|---|
beans |
http://www.springframework.org/schema/beans |
spring-beans |
context |
http://www.springframework.org/schema/context |
spring-context |
aop |
http://www.springframework.org/schema/aop |
spring-aop |
tx |
http://www.springframework.org/schema/tx |
spring-tx |
task |
http://www.springframework.org/schema/task |
spring-context |
cache |
http://www.springframework.org/schema/cache |
spring-context |
jms |
http://www.springframework.org/schema/jms |
spring-jms |
jdbc |
http://www.springframework.org/schema/jdbc |
spring-jdbc |
websocket |
http://www.springframework.org/schema/websocket |
spring-websocket |
oxm |
http://www.springframework.org/schema/oxm |
spring-oxm |
10.2 Key Annotations
| Annotation | Module | Purpose |
|---|---|---|
@Component / @Service / @Repository / @Controller |
spring-context |
Stereotype annotations for component scanning |
@Autowired |
spring-beans |
Dependency injection |
@Value("${...}") / @Value("#{...}") |
spring-beans |
Property / SpEL injection |
@Transactional |
spring-tx |
Declarative transaction demarcation |
@Cacheable / @CacheEvict / @CachePut |
spring-context |
Cache operations |
@Async |
spring-context |
Asynchronous method execution |
@Scheduled |
spring-context |
Cron/fixed-rate/fixed-delay scheduling |
@EventListener |
spring-context |
Application event handling |
@RequestMapping / @GetMapping / etc. |
spring-web |
HTTP endpoint mapping |
@RestController |
spring-web |
@Controller + @ResponseBody |
@HttpExchange |
spring-web |
Declarative HTTP service interface |
@CrossOrigin |
spring-web |
Per-controller CORS configuration |
@JmsListener |
spring-jms |
JMS message consumer |
@Valid / @Validated |
spring-context |
Bean Validation trigger |
@SpringJUnitConfig |
spring-test |
Test context configuration shortcut |
10.3 Common System Properties
| Property | Default | Purpose |
|---|---|---|
spring.profiles.active |
(none) | Activate named profiles |
spring.profiles.default |
default |
Fallback profile |
spring.jmx.enabled |
true |
Enable/disable JMX MBean export |
spring.aop.proxy-target-class |
true (Boot) / false (Framework) |
Force CGLIB class proxies |
spring.expression.compiler.mode |
OFF |
SpEL compiler mode (OFF, IMMEDIATE, MIXED) |
spring.beaninfo.ignore |
true |
Skip java.beans.Introspector (faster startup) |
10.4 Module Maven Coordinates
All modules use group org.springframework and version aligned via framework-bom:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
10.5 Logging Configuration
Spring Framework uses commons-logging as its logging API (bridged to SLF4J/Log4j 2 at runtime):
| Logger Category | Level | What It Shows |
|---|---|---|
org.springframework.beans |
DEBUG |
Bean creation, wiring, definition registration |
org.springframework.context |
DEBUG |
Context lifecycle, event publishing |
org.springframework.web |
DEBUG |
Request dispatch, handler mapping resolution |
org.springframework.jdbc |
DEBUG |
SQL statements, parameter binding |
org.springframework.transaction |
TRACE |
Transaction creation, commit, rollback, propagation |
org.springframework.aop |
TRACE |
Proxy creation, advisor matching |
org.springframework.test |
DEBUG |
Test context caching, SQL script execution |
Note
This guide was generated from source analysis of the Spring Framework repository at commit
5e6e223. It reflects the codebase as of that commit and may not cover changes made after 2026-04-23. For the latest information, consult the official Spring Framework reference documentation and release notes.