Spring Beans Bean Definition, Lifecycle, Scopes is an important Spring topic because it appears in real projects, debugging sessions, and interviews. Learn the meaning first, then connect it to a small working example so the rule does not stay abstract.
For this page, focus on what problem Spring Beans Bean Definition, Lifecycle, Scopes solves, where developers usually make mistakes, and how to verify the result. The audit note for this lesson was: under 650 content words; limited checklist/practice/mistake/FAQ notes .
A strong understanding of Spring Beans Bean Definition, Lifecycle, Scopes should include syntax, behavior, one realistic use case, one failure case, and one quick way to check your work with tools or output.
Spring Beans Bean Definition Lifecycle Scopes should be studied as a practical Spring lesson, not as a label. Start by naming the input, the rule that changes the input, and the result a learner should be able to predict after reading the page.
In the spring > spring-beans page, the notes should connect the definition with a working scenario, a mistake that beginners actually make, and the exact check that proves the fix. That makes the topic useful for coding, debugging, and interview revision.
A Spring Bean is any object that is managed by the Spring IoC container. Spring creates, configures, and manages the lifecycle of beans. You register beans with Spring using stereotype annotations or @Bean methods in @Configuration classes.
| Annotation | Layer | Description |
|---|---|---|
| @Component | Any | Generic Spring-managed component |
| @Service | Service | Business logic layer |
| @Repository | Data Access | Data access layer (adds exception translation) |
| @Controller | Web | MVC controller (returns views) |
| @RestController | Web | REST controller (@Controller + @ResponseBody) |
// Data Access Layer
@Repository
public class UserRepository {
// Spring adds exception translation: SQL exceptions -> Spring DataAccessException
public User findById(Long id) { /* JDBC/JPA code */ return null; }
public void save(User user) { /* JDBC/JPA code */ }
}
// Service Layer
@Service
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User getUser(Long id) {
return userRepository.findById(id);
}
}
// Web Layer
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.getUser(id);
}
}
// Generic component
@Component
public class DataInitializer implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
System.out.println("Application started, initializing data...");
}
}
Bean scope defines how many instances of a bean Spring creates and how long they live:
| Scope | Description | Use Case |
|---|---|---|
| singleton (default) | One instance per Spring container | Stateless services, repositories |
| prototype | New instance every time requested | Stateful beans, command objects |
| request | One instance per HTTP request | Web: request-scoped data |
| session | One instance per HTTP session | Web: user session data |
| application | One instance per ServletContext | Web: application-wide data |
import org.springframework.context.annotation.*;
import org.springframework.web.context.annotation.*;
import javax.annotation.*;
// Singleton (default) - one instance
@Service
// @Scope("singleton") // This is the default, no need to specify
public class SingletonService {
private int counter = 0;
public int increment() { return ++counter; }
}
// Prototype - new instance each time
@Component
@Scope("prototype")
public class PrototypeBean {
private final String id = java.util.UUID.randomUUID().toString();
public String getId() { return id; }
}
// Request scope (web only)
@Component
@RequestScope
public class RequestContext {
private String requestId = java.util.UUID.randomUUID().toString();
public String getRequestId() { return requestId; }
}
// Session scope (web only)
@Component
@SessionScope
public class UserSession {
private String username;
private List<String> cart = new ArrayList<>();
// getters/setters
}
// Bean lifecycle callbacks
@Service
public class DatabaseService {
@PostConstruct // Called after bean is created and dependencies injected
public void init() {
System.out.println("DatabaseService initialized");
}
@PreDestroy // Called before bean is destroyed
public void cleanup() {
System.out.println("DatabaseService cleanup");
}
}
// Lazy initialization - bean created only when first requested
@Service
@Lazy
public class HeavyService {
public HeavyService() {
System.out.println("HeavyService created (lazy)");
}
}
@Configuration
public class AppConfig {
// Singleton bean (default)
@Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}
// Prototype bean via @Bean
@Bean
@Scope("prototype")
public HttpClient httpClient() {
return HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
}
// Conditional bean - only created if property is set
@Bean
@ConditionalOnProperty(name = "feature.cache.enabled", havingValue = "true")
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("users", "products");
}
// Bean with init and destroy methods
@Bean(initMethod = "start", destroyMethod = "stop")
public SchedulerService schedulerService() {
return new SchedulerService();
}
}
When studying Spring Beans Bean Definition, Lifecycle, Scopes, separate three things: the concept, the syntax, and the situation where it is useful. This prevents the lesson from becoming a list of commands with no practical meaning.
In Spring, Spring Beans Bean Definition, Lifecycle, Scopes becomes easier when you build a tiny example first, then increase complexity. Add one realistic input, one invalid or boundary input, and one explanation of why the result changes.
class SpringBeansBeanDefinitionLifecycleScopesReview {
public static void main(String[] args) {
String state = "ready";
System.out.println("Spring Beans Bean Definition Lifecycle Scopes: " + state);
}
}
String value = null;
if (value == null) {
System.out.println("Spring Beans Bean Definition Lifecycle Scopes: handle the missing value before continuing");
}
Memorizing Spring Beans Bean Definition Lifecycle Scopes without the situation where it is useful.
Connect Spring Beans Bean Definition Lifecycle Scopes to a concrete Spring task.
Testing Spring Beans Bean Definition Lifecycle Scopes only with the perfect input.
Include empty, missing, duplicate, incompatible, or failed cases when relevant.
Changing code before reading the visible symptom or error message.
Inspect the output, state, configuration, or stack trace connected to Spring Beans Bean Definition Lifecycle Scopes.
Memorizing Spring Beans Bean Definition Lifecycle Scopes without the situation where it is useful.
Connect Spring Beans Bean Definition Lifecycle Scopes to a concrete Spring task.
The common mistake is memorizing syntax without understanding when the behavior changes or fails.
Remember the problem it solves in Spring, then attach the syntax or steps to that problem.
You can predict the result of a small example, explain a failure case, and choose it over a nearby alternative for a clear reason.
They often copy the syntax but skip the state, input, dependency, selector, route, type, or configuration that controls the behavior.
Explore 500+ free tutorials across 20+ languages and frameworks.