【Spring】Bean的LifeCycle(生命周期)
菜瓜:水稻,上次说Bean的LifeCycle,还没讲完
水稻:啥?说人话?
菜瓜:spring,bean,生命周期
水稻:哦哦,下次直接说人话。说正事,先从BeanFactory、ApplicationContext和FactoryBean开始说起吧
- 我们知道(你不一定知道)BeanFactory是Spring访问Bean容器的根接口,源码的注释: “The root interface for accessing a Spring bean container.”
- 而ApplicationContext继承自BeanFactory,也就是说它具有BeanFactory的属性和方法,并进一步完善(继承其他的接口)
- FactoryBean跟前两个关系就不怎么大了,它是spring提供给用户创建bean的口子,有一些bean创建过程复杂,或者依赖第三方包等(Mybatis-Spring中),可交给用户自己创建
菜瓜:嗯。。陷入沉思。。(欲言又止)
水稻:讲理论不给代码就是耍流氓
package com.vip.qc.postprocessor; import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component; /**
* @author QuCheng on 2020/6/15.
*/
@Component("fb")
public class FactoryBeanT implements FactoryBean<FactoryBeanT.CustomBean> { public FactoryBeanT() {
System.out.println("实现FactoryBean接口的类自身被放在IOC一级缓存的容器里面,getObject的对象是在另一个缓存对象中");
} @Override
public CustomBean getObject() {
return new CustomBean();
} @Override
public Class<?> getObjectType() {
return CustomBean.class;
} static class CustomBean {
public CustomBean() {
System.out.println("自定义bean");
}
}
} 测试方法
@Test
public void testTransa() {
BeanFactory context = new AnnotationConfigApplicationContext(ComponentScanD.class);
System.out.println("factoryBean : " + context.getBean("fb"));
System.out.println("&factoryBean : " + context.getBean("&fb"));
} 测试结果实现FactoryBean接口的类自身被放在IOC一级缓存的容器里面,getObject的对象是在另一个缓存对象中
自定义bean
factoryBean : com.vip.qc.postprocessor.FactoryBeanT$CustomBean@214b199c
&factoryBean : com.vip.qc.postprocessor.FactoryBeanT@20d3d15a
菜瓜:懂了,BeanFactory是Spring的核心--容器,ApplicationContext则是包裹容器的上下文,丰富容器的功能(资源加载,事件驱动等)。FactoryBean也是Spring扩展性的提现
水稻:WC,你这个总结提到了精髓。就是扩展性:如果BeanFactory是核心思想,那么其他的上下文,后置处理器,还是Aware接口等等,都是为了实现扩展
菜瓜:铺垫说完了,开始生命周期呗
水稻:这次咱们反过来先看源码,再看实验,再总结
- BeanFactory源码注释 - 定义了实现的生命周期
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
* @since 13 April 2001
* @see BeanNameAware#setBeanName
* @see BeanClassLoaderAware#setBeanClassLoader
* @see BeanFactoryAware#setBeanFactory
* @see org.springframework.context.ResourceLoaderAware#setResourceLoader
* @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher
* @see org.springframework.context.MessageSourceAware#setMessageSource
* @see org.springframework.context.ApplicationContextAware#setApplicationContext
* @see org.springframework.web.context.ServletContextAware#setServletContext
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
* @see InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
* @see DisposableBean#destroy
* @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName
*/
public interface BeanFactory {- BeanFactory源码实现类
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// BeanNameAware BeanFactoryAware ...
invokeAwareMethods(beanName, bean);
} Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor Before @PostConstruct
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
} try {
// initMethod InitializingBean接口
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor after
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
} return wrappedBean;
}- 实验代码
package com.vip.qc.postprocessor; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component; /**
* @author QuCheng on 2020/6/14.
*/
@Component
public class BeanFactoryPostProcessorT implements BeanFactoryPostProcessor { public static final String BEAN_NAME = "initializingBeanT"; @Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition initializingBeanT = beanFactory.getBeanDefinition(BEAN_NAME);
System.out.println("BeanFactoryPostProcessor bean " + initializingBeanT.getBeanClassName());
}
} package com.vip.qc.postprocessor; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component; /**
* @author QuCheng on 2020/6/14.
*/
@Component
public class BeanPostProcessorT implements BeanPostProcessor { public static final String BEAN_NAMET = "initializingBeanT"; @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (BEAN_NAMET.equals(beanName)) {
InitializingBeanT processorT = ((InitializingBeanT) bean);
System.out.println("BeanPostProcessor BeforeInitialization " + processorT);
}
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (BEAN_NAMET.equals(beanName)){
InitializingBeanT processorT = ((InitializingBeanT) bean);
System.out.println("BeanPostProcessor AfterInitialization " + processorT);
}
return bean;
} } package com.vip.qc.postprocessor; import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; /**
* @author QuCheng on 2020/6/14.
*/
@Component
public class InitializingBeanT implements BeanNameAware, InitializingBean, DisposableBean { public InitializingBeanT() {
System.out.println("init无参构造 execute");
} @PostConstruct
public void postConstruct() {
System.out.println("@PostConstruct execute");
} @PreDestroy
public void preDestroy() {
System.out.println("@PreDestroy execute");
} @Override
public void afterPropertiesSet() {
System.out.println("InitializingBean afterPropertiesSet --> " + this.toString());
} @Override
public void setBeanName(String name) {
System.out.println("BeanNameAware : " + name);
} @Override
public void destroy() {
System.out.println("destroy");
}
} 测试代码
@Test
public void testLifeCycle() {
AbstractApplicationContext applicationContext = new AnnotationConfigApplicationContext(ComponentScanD.class);
applicationContext.close();// 这里不关闭容器的话,注销bean的方法会看不到打印
} 测试结果BeanFactoryPostProcessor bean com.vip.qc.postprocessor.InitializingBeanT
init无参构造 execute
BeanNameAware : initializingBeanT
BeanPostProcessor BeforeInitialization com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
@PostConstruct execute
InitializingBean afterPropertiesSet --> com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
BeanPostProcessor AfterInitialization com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
@PreDestroy execute
destroy
菜瓜:实现什么的不重要,接口才是爸爸呀,BeanFactory定义好了生命周期,下面的实现也只是实现罢了
水稻:哈哈,你说的对,一流的公司卖标准
菜瓜:这里怎么没看到循环依赖的处理啊
水稻:是的。这里的源码我只截取了bean初始化完成之后的接口调用。循环依赖的处理在它前面。来来来,继续刚
菜瓜:刚不了刚不了,你一下子搞这么多玩意给我看,我哪看得完
水稻:您歇着,下次您什么时候想了解我再给您说
总结
- BeanFactory已经定义了整个的生命周期,子类只是负责实现,demo演示也只是为了证实。我们更应该关注更上层的东西
- ApplicationContext是对容器更精细化的包装,提供了更完善的功能
- FactoryBean是Spring扩展性的提现,可供用户自己定义创建bean。扩展性提炼的很好
【Spring】Bean的LifeCycle(生命周期)的更多相关文章
- spring bean 容器的生命周期是什么样的?
spring bean 容器的生命周期流程如下: 1.Spring 容器根据配置中的 bean 定义中实例化 bean. 2.Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置. 3 ...
- spring Bean的完整生命周期
spring 容器中的bean的完整生命周期一共分为十一步完成. 1.bean对象的实例化 2.封装属性,也就是设置properties中的属性值 3.如果bean实现了BeanNameAware,则 ...
- 一张图搞懂Spring bean的完整生命周期
一张图搞懂Spring bean的生命周期,从Spring容器启动到容器销毁bean的全过程,包括下面一系列的流程,了解这些流程对我们想在其中任何一个环节怎么操作bean的生成及修饰是非常有帮助的. ...
- Spring Bean各阶段生命周期的介绍
一.xml方式配置bean 二.Aware接口 2.1 BeanNameAware 2.2 BeanFactoryAware 2.3 ApplicationContextAware 2.4 Aware ...
- [spring] -- bean作用域跟生命周期篇
作用域 singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的. prototype : 每次请求都会创建一个新的 bean 实例. request : 每一次HT ...
- Spring中与bean有关的生命周期
前言 记得以前的时候,每次提起Spring中的bean相关的生命周期时,内心都无比的恐惧,因为好像有很多,自己又理不清楚,然后看网上的帖子,好像都是那么一套,什么beanFactory啊,aware接 ...
- Spring 了解Bean的一生(生命周期)
转载 https://blog.csdn.net/w_linux/article/details/80086950 该篇博客就来了解IoC容器下Bean的一生吧,也可以理解为bean的生命周期. ## ...
- Spring注解开发系列Ⅲ --- 生命周期
Bean的生命周期 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解. 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: S ...
- Bean 注解(Annotation)配置(2)- Bean作用域与生命周期回调方法配置
Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of ...
随机推荐
- Algorithms - Data Structure - Perfect Hashing - 完全散列
相关概念 散列表 hashtable 是一种实现字典操作的有效数据结构. 在散列表中,不是直接把关键字作为数组的下标,而是根据关键字计算出相应的下标. 散列函数 hashfunction'h' 除法散 ...
- SimpleAuthenticationInfo的参数
SimpleAuthenticationInfo的参数 仅供个人参考,以及学习记录.SimpleAuthenticationInfo authenticationInfo = new SimpleAu ...
- Android | 超简单集成HMS ML Kit实现最大脸微笑抓拍
前言 如果大家对HMS ML Kit 人脸检测功能有所了解,相信已经动手调用我们提供的接口编写自己的APP啦.目前就有小伙伴在调用接口的过程中反馈,不太清楚HMS ML Kit 文档中的MLMax ...
- 如何同时关联多个远程仓库,实现一次 push 多站提交(github + gitee)
这两天做了简陋轮子,主要想放到npm上, Github: canvas-components Gitee: canvas-components github 上一份,gitee 上一份.(走过路过,s ...
- Java IO(八) PipedInputStream 和 PipedOutputStream
Java IO(八) PipedInputStream 和 PipedOutputStream 一.介绍 PipedInputStream 和 PipedOutputStream 是管道输入流和管道输 ...
- 七个生产案例告诉你BATJ为何选择ElasticSearch!应用场景和优势!
本文来源于公众号[胖滚猪学编程],转载请注明出处. 从今天开始,想和你一起死磕ElasticSearch,学习分布式搜索引擎,跟着胖滚猪就对了! 既然是ES的第一课,那么最重要的是让你爱上它!不想说那 ...
- Vuex原理实现
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 思考问题 Vuex 只在更实例引入了,那么 ...
- Attribute (XXX) is obsolete. Its use is discouraged in HTML5 documents.
这种警告主要是因为这些属性在HTML5中过时了,并不影响代码运行,但是一些强迫症就会非常难受. 解决办法: 将程序的顶部的这句: !DOCTYPE 修改为: !DOCTYPE html PUBLIC ...
- Java实现 LeetCode 690 员工的重要性(简易递归)
690. 员工的重要性 给定一个保存员工信息的数据结构,它包含了员工唯一的id,重要度 和 直系下属的id. 比如,员工1是员工2的领导,员工2是员工3的领导.他们相应的重要度为15, 10, 5.那 ...
- Java实现 LeetCode 522 最长特殊序列 II(查找最长的非子序列的长度)
522. 最长特殊序列 II 给定字符串列表,你需要从它们中找出最长的特殊序列.最长特殊序列定义如下:该序列为某字符串独有的最长子序列(即不能是其他字符串的子序列). 子序列可以通过删去字符串中的某些 ...