Spring Beans
What is a Spring Bean?
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.
Stereotype Annotations
| 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 Scopes
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();
}
}
Ready to Level Up Your Skills?
Explore 500+ free tutorials across 20+ languages and frameworks.