@Bean Annotation Spring
@Bean Annotation Spring
java
Copy code
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
● Every time you call myService(), a new instance of MyService will be created
because Spring does not manage the class as a configuration class.
java
Copy code
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService(); // Singleton, managed by Spring
}
}
● Here, Spring ensures that only one instance of MyService is created and managed as
a singleton.
Summary:
● Without @Configuration: New bean instances will be created each time the method
is called (not managed by Spring properly).
● With @Configuration: Spring will handle the bean lifecycle correctly, ensuring
singleton behavior (or other specified scopes).
@Bean Annotation:
● The @Bean annotation is a method-level annotation in the Spring framework.
● It indicates that a method will produce a bean to be managed by the Spring IoC
(Inversion of Control) container.
Key Points:
1. Method-Level Annotation:
○ @Bean is applied on a method, not on a class.
○The method annotated with @Bean returns an object that Spring registers as a
bean in its application context.
2. Usage in @Configuration Classes:
○ It is most commonly used in classes annotated with @Configuration, which
are Java-based configurations in Spring.
The methods in a @Configuration class, annotated with @Bean, define how
○
Spring should create and manage those beans.
3. Flexible Usage:
○ Though primarily used within @Configuration classes, @Bean can also be
used in other contexts.
○ This provides flexibility when the developer wants to have fine control over the
instantiation and configuration of beans.
4. Difference from @Component:
○ Unlike @Component, which is a class-level annotation, @Bean works at the
method level.
○ @Component relies on classpath scanning (@ComponentScan), whereas @Bean
explicitly defines the bean.
Example Usage:
@Configuration
public class AppConfig {
@Bean
public Car car() {
return new Car("Toyota");
}
}
● In this example, the car() method is annotated with @Bean. When the method is called,
Spring creates an instance of the Car class and registers it as a bean.
Key Takeaways:
● Flexibility: Provides control over bean creation, ideal for external or non-Spring classes.
● IoC: Ensures Spring manages the lifecycle and dependencies of the objects created.
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
MyService m = new MyService();
return m;
}
}
In XML-based configuration, when defining beans using the <bean> tag, you would explicitly
provide the class using the class="" attribute, which tells Spring the fully qualified class name
(FQCN) of the bean to be created. Here's an example:
xml
Copy code
<bean id="myService" class="com.example.MyService" />
In this case, myService is the bean name, and com.example.MyService is the fully
qualified class name (class path).
When you switch to the annotation-based approach, you no longer need to define the class path
explicitly in XML because the class instantiation happens inside the method annotated with
@Bean. The class path is implicitly set when you return the new object of the class within the
method.
Example:
java
Copy code
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService(); // Here, the class is instantiated
directly
}
}
In this case:
● The class MyService is directly instantiated (new MyService()), and Spring knows
where to find this class because it's part of the project's package structure and is loaded
via the classpath.
● The bean's name defaults to the method name (myService in this case).
You can customize the bean name using the name attribute of the @Bean annotation:
java
Copy code
@Bean(name = "customService")
public MyService myService() {
return new MyService();
}
Here, the bean name would be customService, and you could refer to this bean by that name
in your application.
In summary:
Bean Defined using the <bean> tag in an XML Defined using methods annotated
Declarati file. with @Bean inside a Java
on configuration class.
Class Class path is provided explicitly using the Class path is inferred based on the
Path class attribute inside the <bean> tag. package structure of the class
Example: <bean id="myService" instantiated within the method.
class="com.example.MyService"/ Example: new MyService()
>
File Requires an external XML file (e.g., Requires a Java configuration class
Location applicationContext.xml). annotated with @Configuration.
Readabil Not as readable or maintainable for large More readable and maintainable as
ity applications; hard to track dependencies it's standard Java code with methods,
and bean configurations in XML files. making it easier to trace
dependencies and configurations.
Flexibilit Less flexible; changes require modifying More flexible; changes can be made
y XML files. directly in the Java configuration
code, making refactoring easier.
Key Differences:
1. Object Creation:
○ XML: Spring automatically creates the object from the class path provided in the
XML <bean> tag.
○ @Bean: The object is explicitly created inside the method that is annotated with
@Bean.
2. Class Path:
○ XML: The class path must be manually specified using the class attribute.
○ @Bean: The class is instantiated directly inside the method, and Spring infers
the class path based on the package structure.
3. Bean Name:
○ XML: Bean name is set via the id or name attribute of the <bean> tag.
○ @Bean: Bean name defaults to the method name but can be customized with
the name attribute in the @Bean annotation.
4. Extra Configuration:
○ XML: Requires an external XML file, typically named
applicationContext.xml, which Spring loads to initialize the beans.
○ @Bean: Requires a Java configuration class annotated with @Configuration,
which Spring uses to manage the beans. No external XML file is needed.
By using @Bean, you shift from an XML-based approach to a more type-safe, readable, and
flexible Java-based configuration model.
Key Points:
1. Earlier with @ComponentScan, we needed to specify the base packages (e.g.,
basePackages = {"in.scalive.demobeans",
"in.scalive.samplebeans"}) for Spring to automatically detect components within
those packages.
2. With the @Bean annotation, you do not need @ComponentScan for bean creation.
You directly define beans inside a configuration class using methods annotated with
@Bean. Spring will manage these beans without scanning the packages.
3. @ComponentScan is still useful if you're relying on annotation-based component
discovery (e.g., using @Component, @Service, @Repository, etc.). But for manual
bean definitions using @Bean, only @Configuration and @Bean are required.
This makes @Bean more explicit, type-safe, and configuration-focused, while @ComponentScan
is useful for automatic discovery of beans across packages.
This allows for greater flexibility in naming beans, especially when you want to override the
default method-based naming convention.
Changing Bean Scope in Spring:
Example:
java
Copy code
Bean
ublic MyService myService() {
return new MyService(); // Singleton by default
In this case, Spring creates a single instance of MyService, which will be shared across the entire
application.
Syntax:
java
Copy code
Scope("prototype")
ublic MyService myService() {
return new MyService(); // New instance per request
○ Possible values:
■ "singleton" (default): Single instance per container.
■ "prototype": New instance each time the bean is requested.
■ "request": New instance per HTTP request (for web apps).
■ "session": New instance per HTTP session (for web apps).
■ "application": Single instance per ServletContext.
■ "websocket": New instance per WebSocket session.
5. Using Predefined Constants (Safest Way):
○ It's safer to use constants from ConfigurableBeanFactory to avoid typos
and ensure best practices.
Example:
java
Copy code
import
org.springframework.beans.factory.config.ConfigurableBeanFacto
ry;
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public MyService myService() {
return new MyService(); // New instance each time
}
@Bean
public UserService userService() {
return new UserService();
}
// Same instance is shared everywhere.
Using the predefined constants ensures safe and consistent code, avoiding potential errors
from misspelling the scope string values.
1. Predefined Constants:
○ Spring provides predefined constants in the
org.springframework.beans.factory.config.ConfigurableBeanFac
tory interface for specifying bean scopes.
2. Common Scope Constants:
○ Two commonly used constants are:
■ SCOPE_PROTOTYPE: Creates a new instance for each request or
injection.
■ SCOPE_SINGLETON: Creates a single instance for the entire application
(default scope).
3. Syntax:
Use the @Scope annotation with the desired constant for defining bean scope:
java
Copy code
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean
public MyBean myBean() {
return new MyBean(); // New instance for each request
}
4. Additional Notes:
○ SCOPE_PROTOTYPE: A new instance is created each time the bean is requested
or injected.
○ SCOPE_SINGLETON: Only one instance is created for the entire application's
lifecycle (default behavior).
Using constants is the safest and cleanest approach to avoid potential typos or errors.
Control Provides granular control over bean Less control, relies on automatic
instantiation classpath scanning
Complexity Useful for complex beans needing Suitable for simpler, auto-detected
custom handling beans
Key Notes:
● Control:
○ @Bean: Offers fine-grained control over bean instantiation and configuration,
making it ideal for complex beans and external libraries.
○ @Component: Automatically detected by Spring, with less manual setup.
● Configuration:
○ @Bean: Requires manual bean declaration in a configuration class.
○ @Component: Automatically picked up by classpath scanning.
● Use Cases:
○ @Bean: Preferred for external libraries or when beans require explicit
instantiation.
○ @Component: Commonly used for custom classes that can be automatically
managed by Spring.
● Complexity:
○ @Bean: Best for complex bean creation, where you need control over
dependencies or lifecycle.
○ @Component: Great for simple bean management without requiring complex
configuration.
In summary, use @Bean for more control and complex requirements, and use @Component
for convenience and simplicity. Both annotations can complement each other depending on the
specific needs of your application.
● The @Component annotation cannot handle inner beans (dependencies within other
beans) without additional configurations or annotations.
● @Bean can easily manage inner bean creation and dependency injection directly
within its method.
○ Example: In the provided code, @Bean injects the DatabaseConnection into
the UserRepository seamlessly, which would be difficult to achieve with
@Component.
● Complex Bean: Sometimes, creating a bean involves more than just instantiation. You
may need:
○ Initialization.
○ Configuration of properties.
○ Calling multiple methods to set up the bean.
● The @Bean annotation allows encapsulation of this complex logic inside a method,
offering greater control over bean creation and setup.
○ This is not easily achievable with @Component, which is better suited for simple
beans.
● Granular control: The @Bean method gives you greater flexibility for customizing bean
creation, including adding complex logic for initialization, method calls, and property
configurations.
● Method-level control: With @Bean, you can manage bean instantiation
method-by-method, allowing for fine-tuned dependencies.
● @Bean:
○ Use for complex or third-party classes.
○ Provides more control over object creation.
● @Component:
○ Use for your own classes.
○ Simplifies automatic detection and configuration of Spring beans.
In Summary:
● @Bean is ideal when you need more flexibility and control over bean creation and
configuration.
● @Component is a simpler approach for defining your own Spring-managed beans.
Key Points:
1. @Bean:
○ Use Case: Ideal for complex or third-party classes where you need more control
over how the object is created.
○ Advantages:
■ Provides granular control over bean instantiation.
■ Allows you to define custom initialization, configuration, and dependency
injection logic.
■ Typically used when dealing with external libraries or when a bean setup
requires method calls and additional logic.
Code Example:
java
Copy code
@Configuration
public class AppConfig {
@Bean
public DatabaseConnection databaseConnection() {
// Custom initialization or logic for creating the DatabaseConnection
return new DatabaseConnection("my-database-url");
}
@Bean
public UserRepository userRepository() {
// Injecting the DatabaseConnection bean directly
return new UserRepository(databaseConnection());
}
}
Explanation:
■ In this example, the @Bean method allows fine-tuned control over the
DatabaseConnection and UserRepository instantiation.
■ Complex initialization logic can be encapsulated within the @Bean
method.
2. @Component:
○ Use Case: Best for simple, self-contained classes created within your Spring
project that don't require complex setup or external dependencies.
○ Advantages:
■ Automatically detected and registered by Spring's classpath scanning.
■ Best suited for simple bean creation where minimal configuration is
required.
Code Example:
java
Copy code
@Component
public class SimpleService {
public void performTask() {
System.out.println("Task performed by SimpleService.");
}
}
○ Explanation:
■ @Component marks the SimpleService class as a Spring-managed
bean, making it automatically detected and configured by Spring without
needing additional setup.
Comparison Table:
Use Cases External libraries, complex beans Simple services, utility classes
External Libraries: For integrating third-party libraries, where you cannot annotate the classes
directly with @Component, @Bean provides the necessary flexibility.
Example:
java
Copy code
@Bean
public RestTemplate restTemplate() {
// Custom RestTemplate configuration
RestTemplate restTemplate = new RestTemplate();
// Set up interceptors or custom request factory
return restTemplate;
}
In Summary:
● Use @Bean when you need custom configuration or when working with external
classes where Spring's default scanning cannot be applied.
● Use @Component for simple, self-contained beans that can be easily managed with
Spring’s automatic scanning.
Both annotations have their advantages based on the complexity and requirements of your
bean creation. Choose based on your specific need for control and flexibility.
Key Points:
1. Object Creation:
○ In Java-based configuration, you are responsible for creating the bean object
using the new keyword.
○ Spring will automatically manage the bean's lifecycle, but you must create the
instance within the @Bean method.
2. Dependency Injection:
○ Dependency injection is also your responsibility in Java-based configuration.
○ You must manually inject dependencies into the bean within the @Bean method.
In Summary:
● While Spring simplifies configuration, you still have the responsibility of creating bean
objects and managing their dependencies in Java-based configuration.
Example for Usage of @Bean in Java-Based Configuration
Code Example:
java
Copy code
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MailSender mailSender() {
MailSender mailSender = new MailSender();
mailSender.setHost("smtp.example.com");
mailSender.setPort(587);
mailSender.setCredentials("username", "password");
mailSender.initialize(); // Custom initialization logic
return mailSender; // Returning the MailSender bean
}
}
Explanation:
● Control Over Object Creation: Developers can define how a bean is created,
configured, and initialized.
● Custom Logic: Additional logic (such as setting properties or calling initialization
methods) can be applied within the method body.
Important Note:
In this approach, Spring is not responsible for the creation and dependency injection of
the bean; we handle that ourselves, as demonstrated in the MailSender example.
VVIMP
★ The @Bean annotation is beneficial for customizing bean creation and initialization.
★ However, with @Bean, we must manage dependency injection ourselves, which goes
against the core principle of Spring's automated DI.