Document placeholder and pattern support for @⁠ComponentScan

- 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>
This commit is contained in:
Byeong-Uk Park 2025-09-17 16:19:22 +09:00 committed by Sam Brannen
parent 015edb33cd
commit fe04bfcadb
2 changed files with 52 additions and 0 deletions

View File

@ -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

View File

@ -76,6 +76,10 @@ public @interface ComponentScan {
* <p>Allows for more concise annotation declarations if no other attributes
* are needed &mdash; for example, {@code @ComponentScan("org.my.pkg")}
* instead of {@code @ComponentScan(basePackages = "org.my.pkg")}.
* <p>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.
* <p>Use {@link #basePackageClasses} for a type-safe alternative to
* String-based package names.
* <p>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.
* <p><strong>Note:</strong> Ant-style patterns are <em>not</em> 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.
* <p>Consider creating a special no-op marker class or interface in each package
* that serves no purpose other than being referenced by this attribute.
* <p><strong>Note:</strong> Ant-style package patterns do not apply here; this
* attribute accepts concrete classes only and derives packages from those classes.
*/
Class<?>[] basePackageClasses() default {};