What are 'primary sources' passed to SpringApplication, and how do they differ from component scanning?
answer
- seed classes registered before refresh
- usually one @SpringBootApplication class
- @ComponentScan grows the rest
- add sources for configs outside scanned package
- class / package / XML resource can be a source
basics
~20 sPrimary sources are the classes (or bean-definition sources) you hand to SpringApplication to seed the context — usually your one @SpringBootApplication class. Component scanning then discovers the rest of your beans from that class's package downward.
solid answer
~40 sPrimary sources are the initial bean-definition sources SpringApplication registers into the context — the classes you pass to run() or add via addPrimarySources(). Typically it's the single @SpringBootApplication class. These sources are the seed: Boot registers them as configuration, and because @SpringBootApplication includes @ComponentScan and @EnableAutoConfiguration, that seed transitively pulls in your scanned @Components and all auto-configuration. So you rarely pass more than one. You'd pass additional primary sources when you want extra @Configuration classes that aren't reachable by the default component scan (e.g., a config in a different base package), or to compose multiple configs in tests. Sources can also be XML resources or package names, but class-based configuration is the norm. They're 'primary' because SpringApplication distinguishes them from sources added later programmatically.
code
java · 11 lines// Single primary source — the common case:
SpringApplication.run(DemoApplication.class, args);
// Multiple primary sources (e.g. a config outside the scanned package):
SpringApplication app = new SpringApplication(DemoApplication.class, OutOfPackageConfig.class);
app.run(args);
// Or add later:
SpringApplication app2 = new SpringApplication(DemoApplication.class);
app2.addPrimarySources(java.util.List.of(OutOfPackageConfig.class));
app2.run(args);go deeper
Should know it's the class(es) passed to run(), normally the main app class.
Should distinguish explicit sources from component scanning and know how to add extra sources.
Should explain source types (class/package/resource) and when to add configs outside the scan.
Should use sources deliberately for context composition, test slices, and parent/child hierarchies.
## Definition When you write `SpringApplication.run(MyApp.class, args)`, `MyApp.class` is a **primary source**. Internally `SpringApplication` keeps a `Set<Class<?>> primarySources` (plus a general `Set<Object> sources` you can add). These are the objects Boot loads as **bean definitions** before refreshing the context, via a `BeanDefinitionLoader`. A source can be: - a `@Configuration`/`@Component` **class** (by far the most common), - a **package name** (String) to scan, - an XML or Groovy **resource** location. ## Why usually just one The conventional single source is your `@SpringBootApplication` class. Because that annotation bundles `@ComponentScan` (scanning its own package and sub-packages) and `@EnableAutoConfiguration`, registering just that one class triggers discovery of every other `@Component`, `@Service`, `@RestController`, `@Configuration`, etc., in your codebase, plus all matching auto-configuration. So the single primary source is the seed from which the whole bean graph grows. ## Primary sources vs component scanning - **Primary sources** are *explicitly* registered — Boot always processes them. - **Component scanning** is a *mechanism triggered by* one of those sources (`@ComponentScan`) that *discovers additional* beans by package. They're complementary: the primary source turns scanning on; scanning finds the rest. A class that lives **outside** the scanned packages is invisible to scanning — to include it you must add it as an explicit source (or `@Import` it). ## Adding more sources - Constructor: `new SpringApplication(AppConfig.class, ExtraConfig.class)`. - `app.addPrimarySources(Collections.singleton(ExtraConfig.class))`. - `SpringApplicationBuilder`: `.sources(ExtraConfig.class)` / `.sources(ParentConfig.class).child(ChildConfig.class)`. - The `getSources()`/`setSources(...)` collection for non-primary (String/resource) sources. ## When to add extra sources - A `@Configuration` in a package **not** under the main class (avoids widening `@ComponentScan` basePackages). - **Tests** composing several slice configs. - **Parent/child context** hierarchies via the builder, where each level gets its own sources. ## Gotchas - Passing a class that is **not** a configuration (no stereotype/@Configuration) usually contributes nothing useful. - Duplicating a class both as an explicit source and via component scan is harmless (Boot dedups bean definitions by name) but signals a package-layout smell. - If your beans 'aren't found', it's almost always because they sit **outside** the primary source's package and aren't added as a source or `@Import`ed.
- Why is one primary source usually enough?Because @SpringBootApplication includes @ComponentScan and @EnableAutoConfiguration, so that single seed transitively registers all scanned beans and auto-configuration.
- A @Configuration class isn't being picked up — likely cause?It lives outside the component-scan base package. Either move it under the main class's package, add it as a primary source, or @Import it.
saying these in an interview costs you the question
- Confusing primary sources with the full list of every bean
- Thinking you must list every @Configuration class as a source
- Believing component scanning finds classes in unrelated packages automatically