Spring configuration defines how beans are created, wired, and managed by the Spring IoC container.
Over time, Spring has evolved from heavy XML-based configuration to annotation-driven and Java-based configuration, with Spring Boot pushing this even further through auto-configuration.
Understanding configuration types is important because it explains:
- How Spring knows what beans exist
- How dependencies are wired
- How modern Spring applications reduce boilerplate
Spring configuration is the process of providing metadata to the Spring container so that it can:
- Identify beans
- Instantiate them
- Inject dependencies
- Manage lifecycle
This metadata can be provided in multiple ways, called configuration types.
Spring supports four main configuration styles:
- XML-Based Configuration (Legacy)
- Annotation-Based Configuration
- Java-Based Configuration (
@Configuration) - Spring Boot Auto-Configuration
These are not mutually exclusive — they can be combined, but modern Spring prefers Java + annotations.
In early Spring versions, all beans and dependencies were defined in XML files.
Spring reads these XML files and creates beans accordingly.
<beans>
<bean id="engine" class="com.example.Engine"/>
<bean id="car" class="com.example.Car">
<property name="engine" ref="engine"/>
</bean>
</beans>ApplicationContext context =
new ClassPathXmlApplicationContext("beans.xml");
Car car = context.getBean(Car.class);- Centralized configuration
- No annotations required in Java classes
- Verbose and hard to maintain
- No compile-time safety
- Errors discovered at runtime
- Large enterprise applications
- Strict separation of config and code
- Legacy systems
In modern Spring, XML is rarely used.
In this approach, Spring uses annotations inside Java classes to:
- Identify beans
- Inject dependencies
- Define behavior
Spring scans classpath for annotations.
@Component
@Service
@Repository
@Controller
@RestControllerExample:
@Service
public class UserService { }This tells Spring:
“Create and manage this class as a bean.”
@Component
public class Car {
private final Engine engine;
@Autowired
public Car(Engine engine) {
this.engine = engine;
}
}@ComponentScan("com.example")<context:component-scan base-package="com.example"/>- Less boilerplate
- Easy to read
- Faster development
- Works well with modern tooling
- Configuration mixed with code
- Over-annotation can clutter classes
Java-based configuration uses pure Java classes to define beans explicitly.
This approach replaced most XML usage.
@Configuration
public class AppConfig {
@Bean
public Engine engine() {
return new Engine();
}
@Bean
public Car car() {
return new Car(engine());
}
}@Configuration→ marks config class@Bean→ defines a bean
Spring treats @Configuration classes specially to ensure:
- Singleton behavior
- Dependency consistency
@Configurationclasses are proxied using CGLIB- Ensures that calling
engine()multiple times returns the same bean instance
This avoids accidental multiple object creation.
- Compile-time safety
- Refactoring-friendly
- No XML
- Clear bean definitions
- Works perfectly with Spring Boot
Most real-world applications use a hybrid approach.
Example:
@Configuration
@ComponentScan("com.example")
public class AppConfig { }@ComponentScanpicks up annotated classes@Beandefines explicit beans
This is a recommended approach.
Spring Boot automatically configures beans based on:
- Classpath dependencies
- Application properties
- Environment
Example:
-
Add
spring-boot-starter-web -
Spring Boot configures:
- DispatcherServlet
- Embedded Tomcat
- JSON converters
- Error handling
No explicit bean definitions required.
Spring Boot uses:
@EnableAutoConfigurationspring.factories/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports- Conditional annotations
Example:
@ConditionalOnClass(DataSource.class)
@ConditionalOnProperty("spring.datasource.url")Beans are created only if conditions match.
You can override auto-configured beans:
@Bean
public DataSource dataSource() {
return customDataSource();
}Spring Boot backs off automatically.
server.port=8081
spring.datasource.url=jdbc:mysql://localhost/testserver:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost/test@ConfigurationProperties(prefix = "app")
@Component
public class AppConfigProps {
private String name;
private int timeout;
}| Configuration Type | Style | Usage Today |
|---|---|---|
| XML | Declarative | Legacy |
| Annotation-Based | Declarative | Common |
| Java-Based | Programmatic | Very Common |
| Auto-Configuration | Convention-based | Spring Boot Default |
- Prefer Java-based + annotation configuration
- Avoid XML unless maintaining legacy code
- Let Spring Boot auto-configure as much as possible
- Override only when necessary
- Keep configuration clean and modular
- Separate configuration from business logic
XML, Annotation-based, Java-based, and Auto-configuration.
Java-based and annotation-based configuration.
Verbose, error-prone, and not refactoring-friendly.
Marks a class as a source of bean definitions.
Through auto-configuration and sensible defaults.
-
Spring configuration defines how beans are created and wired
-
XML was the original approach but is now legacy
-
Annotation-based and Java-based configuration are modern standards
-
Spring Boot auto-configuration minimizes manual setup
-
Understanding configuration types is essential for debugging and customization