From fe04bfcadb5d68a66c74f7975a7ee01aeccd0fc9 Mon Sep 17 00:00:00 2001 From: Byeong-Uk Park <114344042+Rockernun@users.noreply.github.com> Date: Wed, 17 Sep 2025 16:19:22 +0900 Subject: [PATCH] =?UTF-8?q?Document=20placeholder=20and=20pattern=20suppor?= =?UTF-8?q?t=20for=20@=E2=81=A0ComponentScan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - JavaDoc: clarify that basePackages/value resolve ${…} via Environment and accept Ant-style package patterns (e.g., com.example.**); note patterns don’t apply to basePackageClasses. - Reference: add “Property placeholders and Ant-style patterns” subsection in classpath-scanning.adoc with Java/Kotlin + properties examples. See gh-35288 Closes gh-35491 Signed-off-by: Byeong-Uk Park <114344042+Rockernun@users.noreply.github.com> --- .../pages/core/beans/classpath-scanning.adoc | 39 +++++++++++++++++++ .../context/annotation/ComponentScan.java | 13 +++++++ 2 files changed, 52 insertions(+) diff --git a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc index b3d7e18691..9f6cc02797 100644 --- a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc +++ b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc @@ -323,6 +323,45 @@ sure that they are 'opened' (that is, that they use an `opens` declaration inste `exports` declaration in your `module-info` descriptor). ==== +==== Property placeholders and Ant-style patterns + +`@ComponentScan(basePackages)` supports `${…}` property placeholders resolved +against the `Environment` and Ant-style package patterns such as `com.example.**`. +Multiple packages and/or patterns may be specified. + +[tabs] +====== +Java:: ++ +[source,java,indent=0,subs="verbatim,quotes"] +---- +@Configuration +@ComponentScan(basePackages = "${app.scan.packages}") +public class AppConfig { + // ... +} +---- + +Kotlin:: ++ +[source,kotlin,indent=0,subs="verbatim,quotes"] +---- +@Configuration +@ComponentScan(basePackages = ["\${app.scan.packages}"]) +class AppConfig { + // ... +} +---- +====== + +[source,properties,indent=0,subs="verbatim,quotes"] +---- +app.scan.packages=com.example.**,org.acme.* +---- + +NOTE: Ant-style patterns do not apply to `basePackageClasses`, which accepts concrete +classes and derives packages from those classes. + Furthermore, the `AutowiredAnnotationBeanPostProcessor` and `CommonAnnotationBeanPostProcessor` are both implicitly included when you use the component-scan element. That means that the two components are autodetected and diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ComponentScan.java b/spring-context/src/main/java/org/springframework/context/annotation/ComponentScan.java index a6e4f7f873..34ecb85198 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ComponentScan.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ComponentScan.java @@ -76,6 +76,10 @@ public @interface ComponentScan { *

Allows for more concise annotation declarations if no other attributes * are needed — for example, {@code @ComponentScan("org.my.pkg")} * instead of {@code @ComponentScan(basePackages = "org.my.pkg")}. + *

This attribute has the same semantics as {@link #basePackages}, including + * support for {@code ${...}} placeholders (resolved against the + * {@link org.springframework.core.env.Environment Environment}) and + * Ant-style package patterns (for example, {@code com.example.**}). */ @AliasFor("basePackages") String[] value() default {}; @@ -86,6 +90,13 @@ public @interface ComponentScan { * attribute. *

Use {@link #basePackageClasses} for a type-safe alternative to * String-based package names. + *

Supports {@code ${...}} placeholders resolved against the + * {@link org.springframework.core.env.Environment Environment} as well as + * Ant-style package patterns (for example, {@code com.example.**}). + * Multiple packages and/or patterns may be specified. + *

Note: Ant-style patterns are not applicable to + * {@link #basePackageClasses()}, which accepts concrete classes for type-safe + * package selection. */ @AliasFor("value") String[] basePackages() default {}; @@ -95,6 +106,8 @@ public @interface ComponentScan { * to scan for annotated components. The package of each class specified will be scanned. *

Consider creating a special no-op marker class or interface in each package * that serves no purpose other than being referenced by this attribute. + *

Note: Ant-style package patterns do not apply here; this + * attribute accepts concrete classes only and derives packages from those classes. */ Class[] basePackageClasses() default {};