Why this matters
- Every
@Service,@Repository, and@Controllerin BookStore is a bean managed by the container — not created withnew. - Misunderstanding bean lifecycle leads to
NullPointerExceptionfrom field injection or duplicate instances from manual construction. - Container internals are a core Spring interview topic; explaining bean creation order demonstrates real framework knowledge.
What is a bean?
A bean is any object whose lifecycle Spring controls. For BookStore:
@Service
public class BookService {
private final BookRepository repository;
public BookService(BookRepository repository) {
this.repository = repository;
}
}
Spring instantiates BookService once, injects the BookRepository bean, and reuses that same instance for every HTTP request.
Bean registration methods
- Component scanning —
@Service,@Component,@Repository,@Controlleron a class. @Beanmethods — Explicit factory methods inside@Configurationclasses.- Auto-configuration — Boot creates beans like
DataSourcewhen starters are on the classpath.
Arrows show @Autowired wiring — container injects at startup
ApplicationContext vs BeanFactory
BeanFactory is the low-level interface for bean retrieval. ApplicationContext extends it with:
ApplicationContext extras
- Automatic
BeanPostProcessorregistration - Message source internationalisation
- Event publication (
ApplicationEventPublisher) - Resource loading from classpath
Boot uses AnnotationConfigServletWebServerApplicationContext — you never instantiate it directly.
Bean definition and creation
At startup the container processes bean definitions — metadata describing how to build each bean:
Bean creation pipeline
- Scan — Find
@Componentclasses incom.example.bookstore.** - Parse — Read constructor parameters as injection points
- Sort — Order beans to satisfy dependencies (topological sort)
- Instantiate — Call constructors, apply
@Autowiredwhere needed - Initialise — Run
@PostConstruct,InitializingBean.afterPropertiesSet() - Register — Store in the singleton cache
If BookService depends on BookRepository which depends on DataSource, the container creates them in that order automatically.
Retrieving beans programmatically
Rarely needed in application code, but useful in tests:
@SpringBootTest
class BeanInspectionTest {
@Autowired
private ApplicationContext context;
@Test
void bookServiceIsSingleton() {
BookService a = context.getBean(BookService.class);
BookService b = context.getBean(BookService.class);
assertSame(a, b);
}
}
Both references point to the same object — default scope is singleton.
When the container fails
Circular dependencies crash startup:
@Service
public class OrderService {
public OrderService(BookService bookService) { ... }
}
@Service
public class BookService {
public BookService(OrderService orderService) { ... } // cycle!
}
Spring detects the cycle and throws BeanCurrentlyInCreationException. Fix by restructuring dependencies or using @Lazy on one side.
Bean naming
Default bean name is the decapitalised class name: bookService for BookService. Override with @Service("catalogService") when multiple implementations exist.
public interface BookRepository { ... }
@Repository
public class JpaBookRepository implements BookRepository { ... }
Injection by type works when only one implementation exists. Multiple implementations require @Qualifier or @Primary.
Context refresh and shutdown
In production the context starts once and runs until shutdown. @PreDestroy methods clean up resources:
@Service
public class CacheWarmupService {
@PreDestroy
public void shutdown() {
// flush pending cache writes
}
}
Boot registers a shutdown hook so SIGTERM triggers graceful bean destruction.
Quick recall
Everything you need if you only revisit this box.
- Beans are objects whose lifecycle and dependencies the ApplicationContext manages.
- Default scope is singleton — one instance per application context.
- Registration via component scanning (
@Service) or explicit@Beanmethods. - The container topologically sorts dependencies and fails fast on circular references.
- Never use
newfor Spring-managed services; injection provides wired instances. ApplicationContextextendsBeanFactorywith events, resources, and post-processors.
Test yourself
Answer these before moving on — recall is what makes it stick.