Spring面试中应该是必问的,所以,废话不多说,我们来看看Spring有哪些高频面试题。
1、Spring框架能给我们带来哪些好处?
Spring的初衷:简化开放、解放双手。
DI:直接从配置文件中看类的依赖,依赖关系一目了然。
IOC:在有限的内存和计算机资源的情况下,它能很好的管理好我们的Bean。
万能胶:可以兼容成熟的框架,Hibernate、Mybatis、struts、Quzrtz、Timer、Shiro等。
模块化设计:即插即用,按需分配。
自带测试组件:JUnit,不需要切换环境就能测试用例。
Web MVC:完美分离了Servlet和普通的Bean,完全解耦合,再看看之前的struts,一个Form必须配套一个Action,有过度设计的嫌疑。
声明式事务:将非功能性代码和功能性代码分离,提出了事务管理提前声明。
2、BeanFactory和ApplicationContext有什么区别。
ApplicationContext是BeanFactory的子接口。
*ApplicationContext中增加了对IOC容器中的Bean监控,Bean的生命周期都有回调函数,PostProcessor。
*ApplicationContext支持国际化il8n。
*ApplicationContext扩展了统一资源文件读取方式URL,可以是一个本地的URL,也可以是一个网络上的URL。对应的实现子类分别是ClassPathXmlApplicationContext,FileSystemXmlApplicationContext,XmlWebApplicationContext,AnnotationConfigApplicationContext。
3、请解释Spring Bean的生命周期。
解释:是Bean初始化到销毁的所经历的时间。
怎么监控呢?
*InitializingBean和DisposableBean用来回调,监控Bean的生命周期。
*Aware接口
*init()和destory()方法。
*或者用@PostContruct和@PreDestory注解的方式来监控。
各作用域之间的区别(生命周期的特征),对象什么时候创建,什么时候销毁?
*总共有5个范围,Spring Bean生命各有长短。
最顶层
a、什么时候用,就什么时候出生,用完就死了(prototype)。
b、容器启动就就出生,容器毁灭才死亡(singleton)。
web层
c、request出生的时候就出生(用户发生请求),request销毁的时候就销毁(请求得到回应)。
d、session出生的时候就出生,session销毁的时候就销毁。
e、global-session也可以当作是上下文,可以和容器关联在一起。
总结:单例singleton肯定是时间最长的,和容器共存亡,而global-session(仅仅在基于portlet的web应用中才有意义,spring5中已经舍弃)也类似上面,等待有上下文产生的时候就出生,那Session就是有用户开启一段会话就出生,等待会话关闭才销毁,而request层次是每次用户请求得出生销毁,再到这次请求里面可能会生成一些额外得辅助对象,比如实时new出来的,用完就死,当然也是最短的。
4、Spring中的Bean是线程安全的吗?
分析:Spring中Bean并不存在安全不安全,所以面试官是考察你对Spring的理解。
Spring Bean是由IOC容器来创建的,而创建的对象是我们自己写的,首先读取BeanDefinition,然后通过BeanWarpper,instance,class.newInstance()反射生成了bean并且放到Map<String,BeanWarpper>中,最多就是做了个代理,用一个增强的类代替了原来的类,那这样可以看出,这个bean安全不安全和Spring并没有关系。
所以,Spring帮我们管理的Bean安不安全,只和我们写这个Bean是否安全有关,和Spring无关。
5、请问Spring中用到了哪些设计模式。
分析:这是一道自由发挥的题目,考察你对Spring的整体理解。
*工厂模式,beanFactory,applicationContext等,大部分生成bean的地方都用到了工厂模式。
*单例模式,创建类的时候做选择,singleTon或者prototype,默认是单例的。
*代理模式,整个spring AOP功能的实现,事务等。
*模板模式,IOC创建的时候有一套默认流程,非常典型的模板模式,refresh()方法。
*装饰器模式,BeanWarpper等bean的装饰。
*观察者模式,spring的事件驱动模型。
*委派模式,AbstractApplicationContext生成bean的时候委派给子类生成对应的子类工厂,区分xml方式还是注解方式注册bean;MVC中分发请求等。
*适配器模式,AOP中的增强方法和通知等。
*策略模式,IOC生成对象的选择方法,选择单例或者protoType。
6、Spring是怎么样处理循环依赖的。
场景:class A引用了class B,而B也引用了A,此时要怎么解决呢?
BeanWrapper,用缓存机制来解决循环依赖的问题,做两次循环,第一次把能创建的传进好,创建不了的再标记,等待第二次再来创建。
7、在Service层中如何获取到applicationContext?
实现ApplicationContextAware接口。
8、Spring事务怎么实现的。
应用层面:把非功能性代码拆分出来,放到一个TransactionManager里面统一管理。
代码层面:TransactionManager切面,植入到PointCut。
9、Spring Aop中对已经被代理过的对象是怎么处理的?
原生对象:没有做任何处理。
代理对象:被封装到了BeanWrapper里面,存的是代理对象的引用。