Java核心技术面试精讲
杨晓峰
前Oracle首席工程师
立即订阅
43250 人已学习
课程目录
已完结 43 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 以面试题为切入点,有效提升你的Java内功
免费
模块一 Java基础 (14讲)
第1讲 | 谈谈你对Java平台的理解?
第2讲 | Exception和Error有什么区别?
第3讲 | 谈谈final、finally、 finalize有什么不同?
第4讲 | 强引用、软引用、弱引用、幻象引用有什么区别?
第5讲 | String、StringBuffer、StringBuilder有什么区别?
第6讲 | 动态代理是基于什么原理?
第7讲 | int和Integer有什么区别?
第8讲 | 对比Vector、ArrayList、LinkedList有何区别?
第9讲 | 对比Hashtable、HashMap、TreeMap有什么不同?
第10讲 | 如何保证集合是线程安全的? ConcurrentHashMap如何实现高效地线程安全?
第11讲 | Java提供了哪些IO方式? NIO如何实现多路复用?
第12讲 | Java有几种文件拷贝方式?哪一种最高效?
第13讲 | 谈谈接口和抽象类有什么区别?
第14讲 | 谈谈你知道的设计模式?
模块二 Java进阶 (16讲)
第15讲 | synchronized和ReentrantLock有什么区别呢?
第16讲 | synchronized底层如何实现?什么是锁的升级、降级?
第17讲 | 一个线程两次调用start()方法会出现什么情况?
第18讲 | 什么情况下Java程序会产生死锁?如何定位、修复?
第19讲 | Java并发包提供了哪些并发工具类?
第20讲 | 并发包中的ConcurrentLinkedQueue和LinkedBlockingQueue有什么区别?
第21讲 | Java并发类库提供的线程池有哪几种? 分别有什么特点?
第22讲 | AtomicInteger底层实现原理是什么?如何在自己的产品代码中应用CAS操作?
第23讲 | 请介绍类加载过程,什么是双亲委派模型?
第24讲 | 有哪些方法可以在运行时动态生成一个Java类?
第25讲 | 谈谈JVM内存区域的划分,哪些区域可能发生OutOfMemoryError?
第26讲 | 如何监控和诊断JVM堆内和堆外内存使用?
第27讲 | Java常见的垃圾收集器有哪些?
第28讲 | 谈谈你的GC调优思路?
第29讲 | Java内存模型中的happen-before是什么?
第30讲 | Java程序运行在Docker等容器环境有哪些新问题?
模块三 Java安全基础 (2讲)
第31讲 | 你了解Java应用开发中的注入攻击吗?
第32讲 | 如何写出安全的Java代码?
模块四 Java性能基础 (3讲)
第33讲 | 后台服务出现明显“变慢”,谈谈你的诊断思路?
第34讲 | 有人说“Lambda能让Java程序慢30倍”,你怎么看?
第35讲 | JVM优化Java代码时都做了什么?
模块5 Java应用开发扩展 (4讲)
第36讲 | 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?
第37讲 | 谈谈Spring Bean的生命周期和作用域?
第38讲 | 对比Java标准NIO类库,你知道Netty是如何实现更高性能的吗?
第39讲 | 谈谈常用的分布式ID的设计方案?Snowflake是否受冬令时切换影响?
周末福利 (2讲)
周末福利 | 谈谈我对Java学习和面试的看法
周末福利 | 一份Java工程师必读书单
结束语 (1讲)
结束语 | 技术没有终点
Java核心技术面试精讲
登录|注册

第37讲 | 谈谈Spring Bean的生命周期和作用域?

杨晓峰 2018-08-02
在企业应用软件开发中,Java 是毫无争议的主流语言,开放的 Java EE 规范和强大的开源框架功不可没,其中 Spring 毫无疑问已经成为企业软件开发的事实标准之一。今天这一讲,我将补充 Spring 相关的典型面试问题,并谈谈其部分设计细节。
今天我要问你的问题是,谈谈 Spring Bean 的生命周期和作用域?

典型回答

Spring Bean 生命周期比较复杂,可以分为创建和销毁两个过程。
首先,创建 Bean 会经过一系列的步骤,主要包括:
实例化 Bean 对象。
设置 Bean 属性。
如果我们通过各种 Aware 接口声明了依赖关系,则会注入 Bean 对容器基础设施层面的依赖。具体包括 BeanNameAware、BeanFactoryAware 和 ApplicationContextAware,分别会注入 Bean ID、Bean Factory 或者 ApplicationContext。
调用 BeanPostProcessor 的前置初始化方法 postProcessBeforeInitialization。
如果实现了 InitializingBean 接口,则会调用 afterPropertiesSet 方法。
调用 Bean 自身定义的 init 方法。
调用 BeanPostProcessor 的后置初始化方法 postProcessAfterInitialization。
创建过程完毕。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Java核心技术面试精讲》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(22)

  • 代码狂徒
    感觉本篇文章跑题了呢,关于生命周期,只讨论了初始化过程和销毁过程,那么什么时候引发的初始化呢?什么时候触发销毁操作呢?spring容器管理的bean是在容器运行过程中不会被销毁吧?
    2018-08-24
    71
  • Meteor
    Spring容器初始化开始:
    1.[BeanFactoryPostProcessor]接口实现类的构造器2.[BeanFactoryPostProcessor]的postProcessorBeanFactory方法
    3.[BeanPostProcessor]接口实现类的构造器
    4.[InstantiationAwareBeanPostProcessorAdapter]构造器
    5.[InstantiationAwareBeanPostProcessorAdapter]的postProcessBeforeInstantiation方法(从这里开始初始化bean)
    6.[Bean]的构造器
    7.[InstantiationAwareBeanPostProcessorAdapter]的postProcessAfterInstantiation
    8.[InstantiationAwareBeanPostProcessorAdapter]的postProcessPropertyValues方法
    9.[Bean]属性注入,setter方
    方法
    10.[Bean]如果实现了各种XXXaware接口,依次调用各个setXXX(如BeanNameAware.setBeanName(),BeanFactoryAware.setBeanFactory())
    11.[BeanPostProcessor]的postProcessBeforeInitialization方法
    12.[InstantiationAwareBeanPostProcessorAdapter]的postProcessBeforeInitialization方法
    13.[Bean]自定义的init-method
    14.[Bean]如果实现了InitializingBean接口,此时会调用它的afterPropertiesSet方法
    15.[BeanPostProcessor]的postProcessAfterInitialization方法(此时bean初始化完成)
    16.[InstantiationAwareBeanPostProcessorAdapter]的postProcessInitialization方法(到这里容器初始化完成)
    17.业务逻辑bean的使用

    Bean的销毁过程:
    1.[DisposableBean]的destory方法
    2.[Bean]自定义的destory-method方法

    说明:如果有多个bean需要初始化,会循环执行5--15。

    重要说明:欢迎拍砖,欢迎拍,欢迎,欢,……
    2018-08-05
    22
  • coco
    @代码狂徒
    感觉本篇文章跑题了呢,关于生命周期,只讨论了初始化过程和销毁过程,那么什么时候引发的初始化呢?什么时候触发销毁操作呢?spring容器管理的bean是在容器运行过程中不会被销毁吧?

    我来讲讲吧:
    首先理解scope:
    1. Singleton(单例) 在整个应用中,只创建bean的一个实例
    2. Propotype(原型) 每次注入或者通过Spring应用上下文获取的时候,都会创建一个新
    的bean实例。
    3. Session(会话) 在Web应用中,为每个会话创建一个bean实例。
    4. Request(请求) 在Web应用中,为每个请求创建一个bean实例。

    他们是什么时候创建的:
    1一个单例的bean,而且lazy-init属性为false(默认),在Application Context创建的时候构造
    2一个单例的bean,lazy-init属性设置为true,那么,它在第一次需要的时候被构造.
    3 其他scope的bean,都是在第一次需要使用的时候创建

    他们是什么时候销毁的:
    1 单例的bean始终 存在与application context中, 只有当 application 终结的时候,才会销毁
    2 和其他scope相比,Spring并没有管理prototype实例完整的生命周期,在实例化,配置,组装对象交给应用后,spring不再管理.只要bean本身不持有对另一个资源(如数据库连接或会话对象)的引用,只要删除了对该对象的所有引用或对象超出范围,就会立即收集垃圾.
    3 Request: 每次客户端请求都会创建一个新的bean实例,一旦这个请求结束,实例就会离开scope,被垃圾回收.
    4 Session: 如果用户结束了他的会话,那么这个bean实例会被GC.

    作者回复: 谢谢反馈,每篇有3K左右的限制,有些细节就不面面俱到了,尽量让有限的内容起到抛砖引玉的作用

    2019-01-09
    1
    18
  • 爪哇夜未眠
    Advice 的时序图的before,after画反了吗
    2018-08-02
    12
  • 虞飞
    声明式事务其实说白了是一种特殊的aop应用,它其实包括两种advice,一种是around,另外一种是after-throwing。利用around advice在方法执行前,先关闭数据库的自动提交功能,然后设定一个标志符。根据业务代码实际的情况,对标志符赋不同的值,如果数据更新成功赋true,否则false。在业务方法执行完之后的部分对标志符进行处理。如为true,则提交数据库操作,否则就进行回滚。
    另外还会使用after-throwing,对出错的信息进行记录。然后再将错误抛出至上层。
    2018-08-06
    9
  • 铁拳阿牛
    可以按照课程丢些demo到一个github项目里,配合章节理论,这样有理论有代码可能对课程,和对学员更有帮助!不过对老师的成本也提高了。
    2018-08-02
    6
  • null
    老师,IOC 为什么可以实现解耦吖?

    在引入 IOC 容器之前,对象 A 依赖于对象 B,则需要 A 主动去创建对象 B,控制权都在 A。

    在引入 IOC 容器之后,当对象 A 运行到需要对象 B 的时候,IOC 容器会主动创建一个对象 B 注入到对象 A,控制权在容器。

    控制权发生了反转,为什么能降价系统耦合,或者说降低什么之间的耦合?(自己的理解:应该不是降低对象间的耦合,因为不管由 A 还是容器创建 B 对象,A 都是耦合 B 的。感觉自己理解的方向偏了。)

    谢谢!

    作者回复: IOC容器负责打理这些事情。同样的依赖关系,一个是a自己负责,一个是ioc容器负责,相当于ab之间的直接联系,变成了间接的。再配合OO,更换实现只需要修改配置

    2018-08-02
    5
  • arebya
    加上jdk本身的@PostConstruct 和@PreDestroy分析整个生命周期会更好
    2018-12-26
    4
  • yao_jn
    读老师的文章收益很大,希望老师再对框架多讲一些,还有底层原理,毕竟很多时候看源码很费力,提点下会好很多!

    作者回复: 坦白说,真的要提高还是要靠自己,建议你看看别人的思路而不只是他的观点,源码就和上学读英文一样,看多了就不犯困,尽量让自己有输出

    2018-08-02
    4
  • 拟梦
    讲springbean的生命周期,不介绍spring后置处理器的文章都是没有灵魂的
    2019-06-13
    2
  • 李峰
    能否分享下你看spring源码的技巧,和方法,我也读了一些其他的源码,感觉spring太全复杂度就很高,看着看着就迷失了

    作者回复: 个人的建议:
    明确目的、目标,尽量让自己有个清晰的体系;
    如果有实际任务驱动更好,毕竟大多数情况是随便看看,没有收获感,也就浅尝辄止了;
    有输出,能表达出来,才好验证

    2018-08-20
    2
  • 汉斯·冯·拉特
    想不到博主对spring也有深入了解。声明式事务是通过beanPostProcessor来实现的,springioc会用beanPostProcessor的某个方法(具体方法名忘记了,这里假设为方法A)返回结果作为getBean的结果。所以spring的事务模块在方法A中,用代理的方式,在目标方法前后加入一些与事务有关的代码,方法A的返回值就是这个代理类。欢迎拍砖!

    作者回复: 喜欢读读源码而已,不敢说有多深入,因为实际踩坑经验不足;补充本文是因为虽然已经36篇,但是Java开发者不会只用Java se自身,开源项目必不可少

    2018-08-03
    2
  • 孟老师
    一直没明白为什么spring和springMVC有父子容器的关系?这么设计的目的是什么?求老师解答
    2018-11-03
    1
  • 拜读第二遍。
    2018-09-12
    1
  • 李峰
    老师,请教下,因为我也读了几次spring的源码,相比其他我读过的源码个人觉得spring复杂度很复杂,很多细节看着看着就迷失在他的代码里面了能否分享下你看spring源码的方法,感谢

    作者回复: 已回复

    2018-08-20
    1
  • 涛哥迷妹
    这么给力多讲了老师一共多少讲啊
    2018-08-07
    1
  • sars
    能否介绍一下热加载,还有目前第三方软件,class,jar都可以热加载。
    2018-08-02
    1
  • hi兵哥
    请教老师一个实际使用中的问题解决方案,多个jar包中有相同路径的相同class,如何让jvm加载制定包下的class?springcloud中有时引入了多个依赖,譬如引入的包使用@bean 生成了 restTemplate,而我自己项目中同样有要生restTemplate的需求,两个处理逻辑有区别,而我想基于robbin去实现负载均衡。基于上面我大致知道可以通过类加载,classScan方式去做一些处理,请问老师能否给出一些具体的可操作的解决方案,谢谢。
    2019-10-26
  • Mr_Tree
    我来替作者回答下下面提出的问题吧
    什么时候引发初始化呢?初始化就是项目启动时就开始初始化了,将xml配置信息解析成BeanDefanition,存放在IOC容器中(所谓IOC容器就是一个Map集合),上面老师讲的是Bean创建阶段了,不是Bean的初始化阶段。
    不管是单例Bean还是原型Bean,都会被解析成BeanDefanition存放在IOC容器中,只不过Spring不处理原型Bean的循环依赖
    2019-09-17
  • static
    老师好,在学习spring的过程中我遇到了一个ioc的一个疑问,刚好看到老师这篇文章又想起之前没有解决的疑惑,希望老师可以帮我解惑,感谢!背景:在ioc容器refresh方法的末尾会初始化所有单例bean,之后会在实例化bean之前先寻找bean的所有依赖bean并循环对依赖的bean调用getBean方法。问题:如果此时依赖的bean是原型的作用域,是否此时的getBean此原型bean是没有用浪费时间的一个过程呢?在我目前的理解感觉如果bean是单例才会将实例存放在ioc容器中,如果是原型就不会存下来,因为我一直找不到原型bean存放在哪里,所以对这个过程产生疑惑,觉得这样轮询依赖bean的过程如果bean为原型是在浪费时间去getBean。感谢老师抽空看完!
    2018-11-23
    1
收起评论
22
返回
顶部