网站做优化有什么好处,怎么在网上做外贸,网站建设对企业的影响,网站方案范文我们都知道#xff0c;在面试的过程中#xff0c;关于 Spring 的面试题#xff0c;那是各种各样#xff0c;很多时候就会问到关于 Spring的相关问题#xff0c;比如 AOP #xff0c;IOC 等等#xff0c;还有就是关于 Spring 是如何管理 Bean 的生命周期的相关问题#…我们都知道在面试的过程中关于 Spring 的面试题那是各种各样很多时候就会问到关于 Spring的相关问题比如 AOP IOC 等等还有就是关于 Spring 是如何管理 Bean 的生命周期的相关问题今天了不起就来和大家一起看看 Spring 是如何管理 Bean 的生命周期的。
源码分析
BeanFactory
其实我们对于这个 Spring 管理 Bean 的生命周期有时候并不需要我们去大篇幅的去背诵某块的内容我们需要的就是学会看源代码比如源代码中的注释部分当我们看到这注释部分的时候很大程度上能够帮助我们理解源码的含义。
BeanFactory是Spring框架中的一个接口它是一个工厂类用来创建和管理Spring中的Bean对象。
我们看源码中的注释
* pBean factory implementations should support the standard bean lifecycle interfaces* as far as possible. The full set of initialization methods and their standard order is:这句话直接翻译就是 Bean Factory 实现类应该尽可能的支持标准的生命周期接口。注释的下半段内容就是描述的 Bean 生命周期的相关内容了。所以源码里面的注释需要我们及时的去看一下虽然都是纯英文的但是能读出个大概得内容再去看源码的话至少知道它是干嘛的方法。
Bean 的生命周期
我们在了解他如何管理的时候我们得先知道这个 Bean 的生命周期都有哪几个阶段知道了阶段我们再来看它的实现。
我们先总结
Bean 的生命周期可以总结为如下的几个阶段
1. Bean的实例化阶段
2. Bean的设置属性阶段
3. Bean的 初始化阶段
4. Bean的销毁阶段
也有些人会细分实例化阶段就是把实例化拆分成两部分第一部分是注册阶段第二部分是实例化阶段其实区别不大。
Bean实例化阶段
在Spring框架中Bean的实例化是一个核心过程它涉及了多个步骤以确保Bean能够正确地被创建并注入到应用上下文中。
Bean定义注册 首先你需要在Spring的配置文件如XML配置文件或Java配置类中定义Bean。这包括指定Bean的类名、作用域、初始化方法、销毁方法以及可能的依赖关系等。 Spring容器会读取这些配置并将Bean定义信息存储在其内部的数据结构中通常是BeanDefinition对象。
实例化前的准备 在实例化Bean之前Spring会进行一些准备工作如解析Bean定义中的属性、检查依赖关系等。 如果Bean定义中引用了其他BeanSpring会尝试先解析并实例化这些依赖Bean。
实例化 实例化是创建Bean对象的过程。Spring提供了多种实例化Bean的方式 构造器实例化通过调用Bean的构造方法来创建实例。你可以在配置文件中指定要使用的构造方法并提供相应的参数。 静态工厂方法实例化通过调用静态工厂方法来创建Bean实例。你需要在配置文件中指定工厂类的类名和工厂方法的名称。 实例工厂方法实例化首先实例化一个工厂Bean然后调用该工厂Bean的某个非静态方法来创建目标Bean实例。 默认构造器实例化如果Bean定义中没有指定其他实例化方式并且Bean类有一个无参构造器那么Spring将使用默认构造器来实例化Bean。 实例化完成后你得到的是一个原始的对象它还没有进行任何属性注入或初始化。
属性注入 在Bean实例化之后Spring会进行属性注入也称为依赖注入。这包括将Bean定义中指定的属性值或对其他Bean的引用注入到Bean的相应属性中。 Spring支持多种属性注入方式如基于字段的注入、基于setter方法的注入和基于构造器的注入等。
BeanPostProcessor处理
在Bean的属性注入完成后但Bean的初始化方法执行之前Spring会调用已注册的BeanPostProcessor接口的postProcessBeforeInitialization方法。这是一个可选的步骤你可以通过实现该接口并注册相应的BeanPostProcessor来在Bean初始化前后执行自定义的逻辑。
初始化 接下来Spring会调用Bean定义中指定的初始化方法如果有的话。这通常是在Bean类中定义的某个方法并用特定的注解如PostConstruct或XML配置中的元素的init-method属性来指定。 初始化方法是Bean在准备好接受请求之前进行必要设置或执行特定任务的地方。
BeanPostProcessor再处理
在Bean初始化方法执行之后Spring会再次调用已注册的BeanPostProcessor接口的postProcessAfterInitialization方法。这是另一个可选的步骤你可以在这里执行一些清理或后处理操作。
Bean就绪
经过上述步骤后Bean就已经被完全创建并初始化了。现在它可以被应用上下文中的其他组件使用或注入到其他Bean中。
到这里我们的实例化就说完了记下来看第二阶段。
Bean的设置属性阶段
Bean的设置属性阶段也称为属性注入或依赖注入是Bean生命周期中的一个重要环节。这个阶段发生在Spring容器创建Bean的实例之后但在Bean被实际使用之前。 当Spring容器创建一个Bean的实例后它会检查该Bean是否有需要注入的属性。这些属性可能是其他的Bean、基本数据类型、集合、Map等。 Spring会查找与这些属性对应的配置信息可能是XML中的标签、注解中的值或其他配置方式并将它们注入到Bean的相应字段或setter方法中。
注入方式 字段注入通过直接在字段上使用Autowired或其他相关注解来实现。但请注意字段注入在某些情况下可能导致测试困难或难以遵循良好的封装原则。 构造函数注入在构造函数参数上使用Autowired或其他相关注解。这是推荐的方式之一因为它确保了Bean在创建时就已经拥有所有必需的依赖项并且这些依赖项是不可变的。 setter方法注入在setter方法上使用Autowired或其他相关注解。这种方式允许Bean在创建后的某个时间点接收其依赖项。
既然我们已经把这个属性设置完毕了那么就要开始后进行初始化阶段了。
Bean 的初始化 Bean Aware接口回调 Bean初始化前操作 Bean初始化操作 Bean初始化后操作 Bean初始化完成操作
BeanAware接口回调 private void invokeAwareMethods(final String beanName, final Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());}if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}
Bean初始化前操作 Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result existingBean;for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {result beanProcessor.postProcessBeforeInitialization(result, beanName);if (result null) {return result;}}return result;
}
Bean初始化操作
调用InitializingBean接口的afterPropertiesSet方法 调用定义bean的时候指定的初始化方法。 public interface InitializingBean {/*** Invoked by the containing {code BeanFactory} after it has set all bean properties* and satisfied {link BeanFactoryAware}, {code ApplicationContextAware} etc.* pThis method allows the bean instance to perform validation of its overall* configuration and final initialization when all bean properties have been set.* throws Exception in the event of misconfiguration (such as failure to set an* essential property) or if initialization fails for any other reason*/void afterPropertiesSet() throws Exception;} Bean初始化后阶段 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current processor.postProcessAfterInitialization(result, beanName);if (current null) {return result;}result current;}return result;}Bean初始化完成操作
public interface SmartInitializingSingleton {/*** Invoked right at the end of the singleton pre-instantiation phase,* with a guarantee that all regular singleton beans have been created* already. {link ListableBeanFactory#getBeansOfType} calls within* this method wont trigger accidental side effects during bootstrap.* pbNOTE:/b This callback wont be triggered for singleton beans* lazily initialized on demand after {link BeanFactory} bootstrap,* and not for any other bean scope either. Carefully use it for beans* with the intended bootstrap semantics only.*/void afterSingletonsInstantiated();}当我们完成了初始化之后使用完成最后 Bean 就要走到销毁阶段了。
Bean 的销毁 Overridepublic void destroyBean(Object existingBean) {new DisposableBeanAdapter(existingBean, getBeanPostProcessorCache().destructionAware, getAccessControlContext()).destroy();}这里需要注意的是 当容器关闭时或者当单例 Bean 的作用域结束时Spring 会销毁 Bean 的实例。 对于非单例 Bean如 prototype 作用域的 Bean它们会在每次请求时创建并在不再需要时由 Java 的垃圾回收机制销毁。