In Spring, a bean is simply an object that is managed by the Spring IoC container. To tell Spring how to manage a bean, we need to define the bean. This chapter will dive into the concept of bean definitions, which describe how Spring should create and manage the beans in the container.
A bean definition consists of:
We will explore various ways to define beans and how Spring’s IoC container manages these definitions.
Spring provides several ways to define beans:
In this chapter, we will focus on Java-based configuration, which is the most modern and recommended approach.
In Java-based configuration, we define beans using the
@Bean
annotation within a
@Configuration
-annotated class. Let’s take a look at a
simple example:
HelloWorldService.java
):package com.example.springapplication;
public class HelloWorldService {
public void sayHello() {
System.out.println("Hello, World!");
}
}
AppConfig.java
):package com.example.springapplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public HelloWorldService helloWorldService() {
return new HelloWorldService();
}
}
In this code, the @Bean
annotation is used to define the
helloWorldService()
method as a Spring bean.
By default, Spring assigns the name of the method
(helloWorldService
) as the name of the bean. However, you
can change the bean name by passing a name to the @Bean
annotation.
@Bean(name = "myHelloWorldService")
public HelloWorldService helloWorldService() {
return new HelloWorldService();
}
In this case, the bean will be named myHelloWorldService
instead of the default helloWorldService
.
The scope of a bean determines the lifecycle and visibility of the bean in the container. Spring supports the following bean scopes:
To define the scope of a bean, we use the @Scope
annotation:
@Bean
@Scope("prototype")
public HelloWorldService helloWorldService() {
return new HelloWorldService();
}
In this example, the helloWorldService
bean will be
created as a prototype, meaning a new instance will be created every
time it is requested.
Spring allows you to inject dependencies into beans in several ways:
Let’s explore how to inject dependencies using constructor injection.
GreetingService.java
):package com.example.springapplication;
public class GreetingService {
private String greetingMessage;
public GreetingService(String greetingMessage) {
this.greetingMessage = greetingMessage;
}
public void greet() {
System.out.println(greetingMessage);
}
}
Here, GreetingService
has a constructor that accepts a
greetingMessage
.
AppConfig.java
:package com.example.springapplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public HelloWorldService helloWorldService() {
return new HelloWorldService();
}
@Bean
public GreetingService greetingService() {
return new GreetingService("Hello from GreetingService!");
}
@Bean
public void injectDependencies(HelloWorldService helloWorldService, GreetingService greetingService) {
.sayHello();
helloWorldService.greet();
greetingService}
}
In this example, the GreetingService
bean is created,
and its dependency (greetingMessage
) is injected via the
constructor. The injectDependencies
method calls both
HelloWorldService
and GreetingService
.
Spring also provides a feature called Autowiring, which allows you to automatically inject dependencies into your beans without explicitly specifying them.
You can autowire a bean by annotating a field, setter, or constructor
with the @Autowired
annotation.
Example:
package com.example.springapplication;
import org.springframework.beans.factory.annotation.Autowired;
public class HelloWorldService {
@Autowired
private GreetingService greetingService;
public void sayHello() {
System.out.println("Hello, World!");
.greet();
greetingService}
}
In this case, Spring will automatically inject the
GreetingService
bean into the
HelloWorldService
bean.
To enable autowiring, you also need to enable component scanning by
adding the @ComponentScan
annotation to your
configuration:
@Configuration
@ComponentScan(basePackages = "com.example.springapplication")
public class AppConfig {
// Bean definitions
}
Spring allows you to define initialization and destruction methods for your beans. These methods are called after the bean is created and before it is destroyed.
You can specify initialization and destruction methods using the
@PostConstruct
and @PreDestroy
annotations or
by implementing the InitializingBean
and
DisposableBean
interfaces.
Example using annotations:
package com.example.springapplication;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class HelloWorldService {
@PostConstruct
public void init() {
System.out.println("HelloWorldService is being initialized");
}
@PreDestroy
public void destroy() {
System.out.println("HelloWorldService is being destroyed");
}
public void sayHello() {
System.out.println("Hello, World!");
}
}
In this chapter, we have learned about bean definitions in Spring. We covered:
Understanding bean definitions is essential because they form the foundation of the Spring IoC container. In the next chapter, we will dive deeper into Bean Scopes and explore how to manage the lifecycle of beans in more detail.