Bean 定义注册阶段
程序启动阶段,应用从XML文件或者注解中找到bean definition并注册到Spring IoC容器,代码入口参考 :
// 参考代码 :
// package : org.springframework.beans.factory.support
// class : DefaultListableBeanFactory
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// ... 省略实现
}
Bean定义注册到Spring IoC容器并不表示已经有了Bean实例,只是表明如果要获取相应的Bean实例,Spring IoC容器已经拥有了相应的Bean实例创建的完整信息。
Bean 实例获取阶段
当获取一个Bean实例时,可能是因为以下操作之一 :
- 某个
bean需要被注入到其他bean; - 某个
bean被用户直接调用Spring IoC容器上的getBean()方法获取其实例;
最终上面的这些操作都会导致一个bean实例被准备(新建或者使用一个已经缓存的bean),代码参考入口:
// package : org.springframework.beans.factory.support
// class : AbstractBeanFactory (DefaultListableBeanFactory的父类)
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 省略实现
}
下面主要看一个bean被新建的过程,代码参考入口:
// package : org.springframework.beans.factory.support
// class : AbstractAutowireCapableBeanFactory (DefaultListableBeanFactory的父类)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,
final @Nullable Object[] args) throws BeanCreationException
// 省略实现
}
- 实例化
bean对象(可以理解成new一个对象); Spring依赖注入填充所有bean definition中涉及到的属性;1.
@Autowired依赖注入在此阶段完成,此过程可能会触发其他bean实例的准备;
2.@Value注解注入来自配置文件的属性的设置也发生在此阶段;- 初始化
bean;-
Aware接口方法调用;- 如果
bean实现了接口BeanNameAware, 调用方法setBeanName(该bean的ID); - 如果
bean实现了接口BeanClassLoaderAware,调用方法setBeanClassLoader(容器记录的bean的classLoader); - 如果
bean实现了接口BeanFactoryAware, 调用方法setBeanName(该bean的ID);
- 如果
-
BeanPostProcessor#postProcessBeforeInitialization()应用到该bean;Spring容器标准情况下会关联两个BeanPostProcessor:
1.ApplicationContextAwareProcessor
2.ApplicationListenerDetector在应用
ApplicationContextAwareProcessor#postProcessBeforeInitialization()时 :
1. 如果bean实现了接口EnvironmentAware, 调用方法setEnvironment();
2. 如果bean实现了接口EmbeddedValueResolverAware,调用方法setEmbeddedValueResolver();
3. 如果bean实现了接口ResourceLoaderAware, 调用方法setResourceLoader();
4. 如果bean实现了接口ApplicationEventPublisherAware, 调用方法setApplicationEventPublisher();
5. 如果bean实现了接口ResourceLoaderAware, 调用方法setResourceLoader();
6. 如果bean实现了接口MessageSourceAware, 调用方法setMessageSource();
7. 如果bean实现了接口ApplicationContextAware, 调用方法setApplicationContext(); -
如果该
bean上有JSR-250注解@PostConstruct注解的方法,调用该方法; -
如果该
bean实现了接口InitializingBean,容器调用该bean的方法afterPropertiesSet(); -
如果该
bean上定义了设置了init属性,容器调用该属性对应的bean方法;如果想对一个
bean定制初始化逻辑,要么实现接口InitializingBean,要么在定义时设置init属性。
如果两种方法同时使用,仅仅使用接口InitializingBean定义的初始化方法afterPropertiesSet()。代码参考 :
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable() { // 省略实现 } -
BeanPostProcessor#postProcessAfterInitialization()应用到在该bean。
-
Bean 实例销毁阶段
当bean不再需要时,会被销毁 :
- 如果该
bean上有JSR-250注解@PreDestroy注解的方法,调用该方法; - 如果该
bean实现了DisposableBean接口,会调用该bean实现的该接口的destroy()方法; - 如果这个
bean定义中设置了destroy属性,容器调用该属性对应的bean方法。
本文详细介绍了Spring框架中Bean的生命周期,包括Bean定义注册、实例获取、初始化及销毁等关键阶段,并解释了各阶段的主要操作及涉及的重要接口和注解。
1万+

被折叠的 条评论
为什么被折叠?



