Understanding Spring's IoC Container: BeanFactory, ListableBeanFactory, HierarchicalBeanFactory, and AutowireCapableBeanFactory
This article explains the core Spring IoC concepts by analyzing the top‑level BeanFactory interface and its three important sub‑interfaces—HierarchicalBeanFactory, ListableBeanFactory, and AutowireCapableBeanFactory—illustrating their responsibilities, inheritance relationships, and practical usage with code examples.
Spring's Inversion of Control (IoC) container is built around the BeanFactory interface, which defines the basic operations for obtaining, checking, and managing bean instances. It serves as the foundation for more specialized factories that add powerful features such as hierarchical relationships, bulk bean enumeration, and automatic wiring.
BeanFactory provides methods like getBean(String name) , containsBean(String name) , and various type‑checking utilities. Implementations manage the lifecycle and dependencies of beans, enabling low‑coupling and easier testing.
public interface BeanFactory {
Object getBean(String name) throws BeansException;
// ... other overloaded getBean methods
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}The ListableBeanFactory extends BeanFactory and adds methods for retrieving bean names by type, annotation, or simply listing all definitions, making bulk operations straightforward.
public interface ListableBeanFactory extends BeanFactory {
String[] getBeanNamesForType(ResolvableType type);
String[] getBeanDefinitionNames();
String[] getBeanNamesForAnnotation(Class
annotationType);
}Example usage to obtain all beans of type UserService :
// Build application context
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
ListableBeanFactory factory = (ListableBeanFactory) context;
String[] serviceBeanNames = factory.getBeanNamesForType(UserService.class);
for (String beanName : serviceBeanNames) {
System.out.println("Bean name: " + beanName);
}The HierarchicalBeanFactory introduces parent‑child relationships between bean factories, allowing a child factory to delegate bean lookups to its parent when necessary.
public interface HierarchicalBeanFactory extends BeanFactory {
@Nullable BeanFactory getParentBeanFactory();
boolean containsLocalBean(String name);
}Through getParentBeanFactory() , a bean can be resolved in the nearest factory that defines it, while containsLocalBean checks only the current factory.
The AutowireCapableBeanFactory adds the ability to programmatically autowire existing bean instances, create new beans with dependencies injected, and manage bean lifecycle callbacks.
public interface AutowireCapableBeanFactory extends BeanFactory {
void autowireBean(Object existingBean);
T createBean(Class
beanClass);
Object configureBean(Object existingBean, String beanName);
void initializeBean(Object existingBean, String beanName);
void destroyBean(Object existingBean, String beanName);
}Example of using AutowireCapableBeanFactory to inject a UserMapper into a manually created UserService instance:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
AutowireCapableBeanFactory factory = context.getAutowireCapableBeanFactory();
UserService userService = new UserService();
factory.autowireBean(userService);
userService.performAction();In summary, Spring's bean factories form a layered architecture where BeanFactory defines core bean operations, ListableBeanFactory enables bulk discovery, HierarchicalBeanFactory supports parent‑child composition, and AutowireCapableBeanFactory provides dynamic autowiring and lifecycle management.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.