02-Spring IoC 容器深度解析
·
02. Spring IoC 容器深度解析
2.1 IoC 容器概述
Spring 的 IoC 容器是 Spring Framework 的核心,负责实例化、配置和组装 Bean。容器通过读取配置元数据(XML、注解或 Java 代码)来获取关于要实例化、配置和组装哪些对象的指令。
2.1.1 容器接口层次
BeanFactory (基础容器接口)
↑
ListableBeanFactory (可列举 Bean)
↑
ConfigurableBeanFactory (可配置)
↑
ApplicationContext (应用上下文)
↑
ConfigurableApplicationContext (可配置应用上下文)
2.2 BeanFactory 详解
2.2.1 BeanFactory 接口
BeanFactory 是 Spring 容器的根接口,定义了获取 Bean 的基本操作:
public interface BeanFactory {
// FactoryBean 前缀,用于获取 FactoryBean 本身
String FACTORY_BEAN_PREFIX = "&";
// 根据名称获取 Bean
Object getBean(String name) throws BeansException;
// 根据名称和类型获取 Bean
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
// 根据类型获取 Bean
<T> T getBean(Class<T> requiredType) throws BeansException;
// 根据类型获取 ObjectProvider(延迟加载)
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
// 判断是否包含指定名称的 Bean
boolean containsBean(String name);
// 判断是否为单例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
// 判断是否为原型
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
// 获取 Bean 的类型
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
// 获取 Bean 的别名
String[] getAliases(String name);
}
2.2.2 Bean 生命周期
Spring Bean 的完整生命周期如下:
1. 实例化(Instantiation)
↓
2. 属性赋值(Populate Properties)
↓
3. 设置 BeanName(如果实现了 BeanNameAware)
↓
4. 设置 BeanClassLoader(如果实现了 BeanClassLoaderAware)
↓
5. 设置 BeanFactory(如果实现了 BeanFactoryAware)
↓
6. 设置 Environment(如果实现了 EnvironmentAware)
↓
7. 设置 ApplicationContext(如果实现了 ApplicationContextAware)
↓
8. BeanPostProcessor.postProcessBeforeInitialization()
↓
9. 执行初始化方法(@PostConstruct、InitializingBean.afterPropertiesSet()、自定义 init-method)
↓
10. BeanPostProcessor.postProcessAfterInitialization()
↓
11. Bean 就绪,可供使用
↓
12. 容器关闭
↓
13. BeanPostProcessor.postProcessBeforeDestruction()
↓
14. 执行销毁方法(@PreDestroy、DisposableBean.destroy()、自定义 destroy-method)
2.2.3 生命周期示例代码
@Component
public class LifecycleBean implements
BeanNameAware,
BeanFactoryAware,
ApplicationContextAware,
InitializingBean,
DisposableBean {
private static final Logger logger = LoggerFactory.getLogger(LifecycleBean.class);
// 1. 构造器
public LifecycleBean() {
logger.info("1. Constructor: 实例化");
}
// 2. 属性赋值
@Autowired
public void setDependency(SomeDependency dependency) {
logger.info("2. Setter: 属性赋值");
}
// 3. BeanNameAware
@Override
public void setBeanName(String name) {
logger.info("3. BeanNameAware.setBeanName(): {}", name);
}
// 4. BeanFactoryAware
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
logger.info("4. BeanFactoryAware.setBeanFactory()");
}
// 5. ApplicationContextAware
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
logger.info("5. ApplicationContextAware.setApplicationContext()");
}
// 6. @PostConstruct
@PostConstruct
public void postConstruct() {
logger.info("6. @PostConstruct: 初始化前");
}
// 7. InitializingBean
@Override
public void afterPropertiesSet() throws Exception {
logger.info("7. InitializingBean.afterPropertiesSet()");
}
// 8. 自定义初始化方法
public void customInit() {
logger.info("8. customInit(): 自定义初始化");
}
// 9. @PreDestroy
@PreDestroy
public void preDestroy() {
logger.info("9. @PreDestroy: 销毁前");
}
// 10. DisposableBean
@Override
public void destroy() throws Exception {
logger.info("10. DisposableBean.destroy()");
}
// 11. 自定义销毁方法
public void customDestroy() {
logger.info("11. customDestroy(): 自定义销毁");
}
}
2.3 ApplicationContext 详解
2.3.1 ApplicationContext 功能
ApplicationContext 继承自 BeanFactory,提供了更多企业级功能:
public interface ApplicationContext extends
EnvironmentCapable, // 环境配置能力
ListableBeanFactory, // 可列举所有 Bean
HierarchicalBeanFactory, // 支持父子容器层次
MessageSource, // 国际化消息
ApplicationEventPublisher, // 事件发布
ResourcePatternResolver { // 资源加载
String getId();
String getApplicationName();
String getDisplayName();
long getStartupDate();
ApplicationContext getParent();
AutowireCapableBeanFactory getAutowireCapableBeanFactory();
}
2.3.2 常用 ApplicationContext 实现
// 1. 注解配置上下文
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
// 2. XML 配置上下文
ClassPathXmlApplicationContext xmlCtx =
new ClassPathXmlApplicationContext("applicationContext.xml");
// 3. Web 应用上下文
AnnotationConfigWebApplicationContext webCtx =
new AnnotationConfigWebApplicationContext();
webCtx.register(WebConfig.class);
webCtx.setServletContext(servletContext);
webCtx.refresh();
2.4 BeanDefinition 详解
2.4.1 BeanDefinition 接口
BeanDefinition 描述了 Bean 的元数据信息:
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// 作用域常量
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
// Bean 角色
int ROLE_APPLICATION = 0; // 应用 Bean
int ROLE_SUPPORT = 1; // 支持 Bean
int ROLE_INFRASTRUCTURE = 2; // 基础设施 Bean
// 可配置属性
void setParentName(@Nullable String parentName);
void setBeanClassName(@Nullable String beanClassName);
void setScope(@Nullable String scope);
void setLazyInit(boolean lazyInit);
void setDependsOn(String... dependsOn);
void setAutowireCandidate(boolean autowireCandidate);
void setPrimary(boolean primary);
void setFactoryBeanName(@Nullable String factoryBeanName);
void setFactoryMethodName(@Nullable String factoryMethodName);
// 获取构造参数和属性值
ConstructorArgumentValues getConstructorArgumentValues();
MutablePropertyValues getPropertyValues();
// 初始化/销毁方法
void setInitMethodName(@Nullable String initMethodName);
void setDestroyMethodName(@Nullable String destroyMethodName);
}
2.4.2 程序化注册 Bean
@Configuration
public class DynamicBeanConfig {
public static void registerBean(BeanDefinitionRegistry registry) {
// 创建 BeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition(MyService.class);
// 设置属性
beanDefinition.setScope(ConfigurableBeanFactory.SCOPE_SINGLETON);
beanDefinition.setLazyInit(false);
beanDefinition.setPrimary(true);
// 添加构造参数
ConstructorArgumentValues cav = beanDefinition.getConstructorArgumentValues();
cav.addIndexedArgumentValue(0, "constructorArg1");
cav.addIndexedArgumentValue(1, 100);
// 添加属性值
MutablePropertyValues pvs = beanDefinition.getPropertyValues();
pvs.add("name", "myService");
pvs.add("enabled", true);
// 注册 Bean
registry.registerBeanDefinition("myService", beanDefinition);
}
}
2.5 BeanPostProcessor 扩展点
2.5.1 BeanPostProcessor 接口
BeanPostProcessor 允许在 Bean 初始化前后进行自定义处理:
public interface BeanPostProcessor {
// 初始化前处理
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
// 初始化后处理
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
}
2.5.2 自定义 BeanPostProcessor 示例
@Component
public class MetricsBeanPostProcessor implements BeanPostProcessor {
private final Map<String, Class<?>> beanMetrics = new ConcurrentHashMap<>();
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
// 记录 Bean 创建时间
beanMetrics.put(beanName + "_start", bean.getClass());
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
// 如果是服务层 Bean,添加性能监控代理
if (bean.getClass().isAnnotationPresent(Service.class)) {
return createMetricsProxy(bean, beanName);
}
return bean;
}
private Object createMetricsProxy(Object target, String beanName) {
ProxyFactory proxyFactory = new ProxyFactory(target);
proxyFactory.addAdvice(new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
long start = System.currentTimeMillis();
try {
return invocation.proceed();
} finally {
long elapsed = System.currentTimeMillis() - start;
System.out.printf("Bean [%s] Method [%s] executed in %dms%n",
beanName, invocation.getMethod().getName(), elapsed);
}
}
});
return proxyFactory.getProxy();
}
}
2.6 BeanFactoryPostProcessor 扩展点
2.6.1 BeanFactoryPostProcessor 接口
BeanFactoryPostProcessor 在 BeanFactory 标准初始化之后、Bean 实例化之前执行:
@FunctionalInterface
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException;
}
2.6.2 自定义 BeanFactoryPostProcessor 示例
@Component
public class DataSourceConfigPostProcessor implements BeanFactoryPostProcessor,
EnvironmentAware {
private Environment environment;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
// 动态修改 DataSource BeanDefinition
BeanDefinition dsBeanDef = beanFactory.getBeanDefinition("dataSource");
// 根据环境设置不同的数据库连接
String profile = environment.getActiveProfiles()[0];
if ("dev".equals(profile)) {
dsBeanDef.getPropertyValues().add("url", "jdbc:h2:mem:testdb");
} else if ("prod".equals(profile)) {
dsBeanDef.getPropertyValues().add("url",
environment.getProperty("db.prod.url"));
}
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
}
2.7 作用域(Scope)详解
2.7.1 标准作用域
@Configuration
public class ScopeConfig {
// 单例(默认)- 每个 Spring 容器一个实例
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public SingletonBean singletonBean() {
return new SingletonBean();
}
// 原型 - 每次请求创建新实例
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public PrototypeBean prototypeBean() {
return new PrototypeBean();
}
}
2.7.2 Web 作用域
@Configuration
public class WebScopeConfig {
// Request 作用域 - 每个 HTTP 请求一个实例
@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public RequestContext requestContext() {
return new RequestContext();
}
// Session 作用域 - 每个 HTTP Session 一个实例
@Bean
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public UserSession userSession() {
return new UserSession();
}
// Application 作用域 - 每个 ServletContext 一个实例
@Bean
@Scope(value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public ApplicationCache applicationCache() {
return new ApplicationCache();
}
}
2.8 总结
Spring IoC 容器提供了强大的依赖注入和 Bean 生命周期管理能力:
- BeanFactory 是基础容器接口,提供基本的 Bean 获取功能
- ApplicationContext 是高级容器,提供企业级功能(国际化、事件、资源加载等)
- BeanDefinition 描述 Bean 的元数据信息
- BeanPostProcessor 提供 Bean 初始化前后的扩展点
- BeanFactoryPostProcessor 提供 BeanFactory 创建后的扩展点
- 作用域 控制 Bean 的实例化策略(单例、原型、请求、会话等)
理解这些核心概念是掌握 Spring Framework 的基础。
更多推荐


所有评论(0)