Files
spring-framework/spring-core
Sam Brannen b96592e4af Guard CharSequence-based logging methods in LogAccessor
Prior to this commit, LogAccessor's CharSequence-based logging methods
delegated directly to the corresponding method on the underlying
commons-logging Log instance without first checking whether the target
level was enabled. This differed from the Supplier-based overloads,
which have checked isXxxEnabled() before delegating since Spring
Framework 5.2.9.

That asymmetry was harmless as long as spring-jcl supplied the
underlying Log implementation, since its SLF4J adapter itself checked
the level before rendering the message. However, since Spring Framework
7 replaced spring-jcl with Apache commons-logging, whose SLF4J adapters
call String.valueOf(message) unconditionally, any CharSequence argument
-- most notably a LogMessage supplied via LogMessage.format(...) or
LogMessage.of(...) -- is now rendered eagerly, even when the
corresponding level is disabled. Since LogMessage exists specifically
to defer that work, and the idiom is used extensively throughout the
framework and its portfolio projects, this leads to unnecessary
computation and allocation whenever logging is disabled.

To address this, this commit adds the same isXxxEnabled() guard to all
twelve CharSequence-based methods in LogAccessor, matching the
existing Supplier-based overloads and making LogAccessor's laziness
guarantee independent of the underlying Log implementation.

This commit also introduces LogAccessorTests, which verifies that a
lazily rendering LogMessage passed to one of the CharSequence-based
methods is only rendered when the corresponding level is enabled.

See gh-25741
Closes gh-37266
2026-09-10 16:17:34 +02:00
..