In a Spring Boot application, beans are objects that are managed by the Spring IoC (Inversion of Control) container. Beans are used to define the components, services, and dependencies in an application, and Spring Boot provides several ways to define and configure them.
Ways to Define and Configure Beans in Spring Boot:
1. Using @Component
Annotation (Component Scanning):
- The
@Component
annotation is a generic stereotype used to define a class as a Spring bean. - Spring Boot uses component scanning to automatically detect and register beans in the application context.
#### Example:
java
@Component
public class MyService {
public void performService() {
System.out.println("Performing service...");
}
}
####❓ How It Works:
- When you annotate a class with @Component
, Spring automatically detects and registers it as a bean in the application context.
- Component scanning happens by default in the package where your main application class is located, but you can customize it using the @ComponentScan
annotation.
2. Using @Service
, @Repository
, and @Controller
Annotations:
- These are specialized versions of the
@Component
annotation, used to indicate specific roles in a typical Spring application:@Service
: Indicates a service class.@Repository
: Indicates a DAO or repository class, typically for data access logic.@Controller
: Indicates a web controller for handling HTTP requests in a Spring MVC application.
#### Example:
java
@Service
public class UserService {
public String getUserDetails() {
return "User details";
}
}
3. Using @Bean
Annotation (Java-Based Configuration):
- The
@Bean
annotation is used to explicitly declare a bean inside a@Configuration
class. This approach provides more control over the bean lifecycle and allows you to define and configure beans programmatically.
#### Example:
```java
@Configuration
public class AppConfig {
@Bean public MyService myService() { return new MyService(); }
}
```
####❓ How It Works:
- Spring will invoke the myService()
method to create and manage the MyService
bean in the application context.
- This method can also take arguments if you want to inject other beans into the myService()
bean.
Example with Dependency Injection:
java
@Bean
public UserService userService(MyRepository myRepository) {
return new UserService(myRepository);
}
4. Using @Autowired
for Dependency Injection:
- Spring Boot automatically injects dependencies into beans using constructor injection or field injection with the
@Autowired
annotation.
#### Example (Constructor Injection):
```java
@Component
public class UserController {
private final UserService userService; @Autowired
public UserController(UserService userService) {
this.userService = userService;
}
public void getUserInfo() {
System.out.println(userService.getUserDetails());
}
}
```
#### Example (Field Injection):
```java
@Component
public class UserController {
@Autowired private UserService userService; public void getUserInfo() {
System.out.println(userService.getUserDetails());
}
}
```
5. Using @Primary
and @Qualifier
for Multiple Beans:
- If you have multiple beans of the same type, you can use
@Primary
or@Qualifier
to resolve bean injection conflicts.
#### Using @Primary
:
```java
@Bean
@Primary
public MyService defaultService() {
return new MyService("Default");
}
@Bean
public MyService backupService() {
return new MyService("Backup");
}
```
#### Using @Qualifier
:
```java
@Component
public class ServiceConsumer {
private final MyService myService; @Autowired
public ServiceConsumer(@Qualifier(“backupService”) MyService myService) {
this.myService = myService;
}
}
```
6. Externalizing Bean Configuration with Properties Files:
- You can configure certain aspects of your beans (e.g., database URLs, credentials, or service properties) using
application.properties
orapplication.yml
files. Spring Boot will automatically bind these properties to fields in your beans using the@Value
annotation or@ConfigurationProperties
.
#### Example Using @Value
:
```java
@Component
public class DataSourceConfig {
@Value("${database.url}") private String url; @Value(“${database.username}”)
private String username;
@Value(“${database.password}”)
private String password;
public void printConfig() {
System.out.println("Database URL: " + url);
}
}
```
- In
application.properties
:
properties
database.url=jdbc:mysql://localhost:3306/mydb
database.username=admin
database.password=secret
#### Example Using @ConfigurationProperties
:
```java
@ConfigurationProperties(prefix \= "database")
public class DatabaseConfig {
private String url;
private String username;
private String password;
// getters and setters
}
```
7. Using @Lazy
for Lazy Initialization:
- By default, Spring initializes beans at the time of application startup. However, you can use the
@Lazy
annotation to delay the bean initialization until it’s first requested (lazy loading).
#### Example:
java
@Component
@Lazy
public class HeavyService {
public HeavyService() {
System.out.println("HeavyService initialized");
}
}
- The
HeavyService
bean will only be initialized when it is first requested by another component, not during startup.
8. Using Profiles for Bean Configuration:
- Spring Boot supports different profiles (e.g.,
dev
,prod
) to load specific configurations based on the environment. - Beans can be made profile-specific using the
@Profile
annotation.
#### Example:
```java
@Bean
@Profile("dev")
public DataSource devDataSource() {
return new HikariDataSource();
}
@Bean
@Profile("prod")
public DataSource prodDataSource() {
return new DataSource("jdbc:mysql://prod-server/db", "prod", "password");
}
```
- You can activate a profile using
application.properties
:
properties
spring.profiles.active=dev
Summary of Bean Configuration Methods:
\| Method \| Description \|
\|---------------------------\|---------------------------------------------------------------------------------------------------------\|
\| @Component
\| Automatically detects and registers a class as a Spring bean. \|
\| @Service
, @Repository
, @Controller
\| Specialized versions of @Component
for service, repository, and controller layers. \|
\| @Bean
\| Explicitly declares a bean in a @Configuration
class. \|
\| @Autowired
\| Injects dependencies automatically (constructor or field injection). \|
\| @Primary
\| Marks a bean as the default when multiple beans of the same type exist. \|
\| @Qualifier
\| Used to specify which bean to inject when there are multiple beans of the same type. \|
\| @Value
or @ConfigurationProperties
\| Injects values from externalized configuration (e.g., properties or YAML files). \|
\| @Lazy
\| Initializes the bean only when it is first requested (lazy loading). \|
\| @Profile
\| Specifies that a bean should only be loaded for certain active profiles (e.g., dev
, prod
). \|
Conclusion:
Spring Boot provides multiple ways to define and configure beans, from automatic component scanning with @Component
to manual bean creation using @Bean
. These methods, combined with dependency injection via @Autowired
, profiles, and externalized configuration, give developers flexibility and control over bean management in a Spring Boot application.