Spring常见面试题整理

作者: Moonsmile | 来源:发表于2017-02-25 14:04 被阅读3349次

    1.什么是Spring?

    Spring是一个开源的Java EE开发框架。Spring框架的核心功能可以应用在任何Java应用程序中,但对Java EE平台上的Web应用程序有更好的扩展性。

    Spring框架的目标是使得Java EE应用程序的开发更加简捷,通过使用POJO(简单java对象,也就是javabean)为基础的编程模型促进良好的编程风格。

    2.Spring有哪些优点?

    轻量级,Spring在大小和透明性方面绝对属于轻量级的,基础版本的Spring框架大约只有2MB。

    控制反转(IOC),Spring使用控制反转技术实现了松耦合。依赖被注入到对象,而不是创建或寻找依赖对象。

    面向切面编程(AOP),Spring支持面向切面编程,同时把应用的###业务逻辑与系统的服务###分离开来。

    容器,Spring包含并管理应用程序对象的配置及生命周期。

    MVC框架,Spring的web框架是一个设计优良的web MVC框架,很好的取代了一些web框架。

    事务管理,Spring对下至本地业务上至全局业务(JAT)提供了统一的事务管理接口。

    异常处理,Spring提供一个方便的API将特定技术的异常(由JDBC, Hibernate, 或JDO抛出)转化为一致的、Unchecked异常。

    3.解释核心容器(应用上下文)模块

    这是Spring的基本模块,它提供了Spring框架的基本功能。BeanFactory 是所有Spring应用的核心。Spring框架是建立在这个模块之上的,这也使得Spring成为一个容器。

    4.Spring应用程序看起来像什么?

    一个定义功能的接口
    实现包括属性,setter和getter方法,功能等
    Spring AOP
    Spring的XML配置文件
    使用该功能的客户端编程
    依赖注入

    5.BeanFactory – BeanFactory 实例

    BeanFactory是工厂模式的一种实现,它使用控制反转将应用的配置和依赖与实际的应用代码分离开来。

    最常用的BeanFactory实现是XmlBeanFactory类。

    6.XmlBeanFactory

    org.springframework.beans.factory.xml.XmlBeanFactory,它根据XML文件中定义的内容加载beans。该容器从XML文件中读取配置元数据,并用它来创建一个完备的系统或应用。

    7.解释AOP模块

    AOP模块用来开发Spring应用程序中具有切面性质的部分。该模块的大部分服务由AOP Aliance提供,这就保证了Spring框架和其他AOP框架之间的互操作性。另外,该模块将元数据编程引入到了Spring。

    8.控制反转依赖注入

    反转是相对于正向而言的,那么什么算是正向的呢?考虑一下常规情况下的应用程序,如果要在A里面使用C,你会怎么做呢?当然是直接去创建C的对象,也就是说,是在A类中主动去获取所需要的外部资源C,这种情况被称为正向的。那么什么是反向呢?就是A类不再主动去获取C,而是被动等待,等待IoC/DI的容器获取一个C的实例,然后反向的注入到A类中。

    谁控制谁,控制什么,传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。

    为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

    IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。

    9、java中依赖注入有以下三种实现方式:

    构造器注入
    Setter方法注入
    接口注
    

    10.BeanFactory和ApplicationContext有什么区别?

    BeanFactory 可以理解为含有bean集合的工厂类。BeanFactory 包含了种bean的定义,以便在接收到客户端请求时将对应的bean实例化。

    BeanFactory还能在实例化对象的时生成协作类之间的关系。此举将bean自身与bean客户端的配置中解放出来。BeanFactory还包含了###bean生命周期###的控制,调用客户端的初始化方法(initialization methods)和销毁方法(destruction methods)。

    从表面上看,applicationcontext如同beanfactory一样具有bean定义、bean关联关系的设置,根据请求分发bean的功能。但applicationcontext在此基础上还提供了其他的功能。

    1、提供了支持国际化的文本消息
    2、统一的资源文件读取方式
    3、已在监听器中注册的bean的事件
    

    以下是三种较常见的 ApplicationContext 实现方式:

    1、ClassPathXmlApplicationContext:从classpath的XML配置文件中读取上下文,并生成上下文定义。应用程序上下文从程序环境变量中取得。

    ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”);

    2、FileSystemXmlApplicationContext :由文件系统中的XML配置文件读取上下文。

    ApplicationContext context = new FileSystemXmlApplicationContext(“bean.xml”);

    3、XmlWebApplicationContext:由Web应用的XML文件读取上下文。

    10.将Spring配置到应用开发中有以下三种方式:

    基于XML的配置
    基于注解的配置
    基于Java的配置
    

    11.请解释Spring Bean的生命周期?

    Spring Bean的生命周期简单易懂。在一个bean实例被初始化时,需要执行一系列的初始化操作以达到可用的状态。同样的,当一个bean不在被调用时需要进行相关的析构操作,并从bean容器中移除。

    Spring bean factory 负责管理在spring容器中被创建的bean的生命周期。Bean的生命周期由两组回调(call back)方法组成。

    初始化之后调用的回调方法。
    销毁之前调用的回调方法。
    

    Spring框架提供了以下四种方式来管理bean的生命周期事件:

    InitializingBean和DisposableBean回调接口
    针对特殊行为的其他Aware接口
    Bean配置文件中的Custom init()方法和destroy()方法
    @PostConstruct和@PreDestroy注解方式
    
    <beans>
        <bean id="demoBean" class="com.howtodoinjava.task.DemoBean"
                init-method="customInit" destroy-method="customDestroy"></bean>
    </beans>
    

    12.Spring Bean的作用域之间有什么区别?

    Spring容器中的bean可以分为5个范围。所有范围的名称都是自说明的,但是为了避免混淆,还是让我们来解释一下:
    singleton:这种bean范围是默认的,这种范围确保不管接受到多少个请求,每个容器中只有一个bean的实例,单例的模式由bean factory自身来维护。
    prototype:原形范围与单例范围相反,为每一个bean请求提供一个实例。
    request:在请求bean范围内会每一个来自客户端的网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。
    Session:与请求范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。
    global-session:global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。

    全局作用域与Servlet中的session作用域效果相同。

    13.Spring框架中的单例Beans是线程安全的么?

    Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。但实际上,大部分的Spring bean并没有可变的状态(比如Serview类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话(比如 View Model 对象),就需要自行保证线程安全。

    14.请举例说明如何在Spring中注入一个Java Collection?

    Spring提供了以下四种集合类的配置元素:

    <list> :   该标签用来装配可重复的list值。
    <set> :    该标签用来装配没有重复的set值。
    <map>:   该标签可用来注入键和值可以为任何类型的键值对。
    <props> : 该标签支持注入键和值都是字符串类型的键值对。
    

    15、请解释自动装配模式的区别?

    在Spring框架中共有5种自动装配,让我们逐一分析。

    no:这是Spring框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在bean定义中用标签明确的设置依赖关系。
    byName:该选项可以根据bean名称设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的名称自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。
    byType:该选项可以根据bean类型设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的类型自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。
    constructor:造器的自动装配和byType模式类似,但是仅仅适用于与有构造器相同参数的bean,如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。
    autodetect:该模式自动探测使用构造器自动装配或者byType自动装配。首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在bean内部没有找到相应的构造器或者是无参构造器,容器就会自动选择byTpe的自动装配方式。
    

    15.Spring 框架中都用到了哪些设计模式?

    Spring框架中使用到了大量的设计模式,下面列举了比较有代表性的:

    代理模式—在AOP和remoting中被用的比较多。
    单例模式—在spring配置文件中定义的bean默认为单例模式。
    模板方法—用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
    前端控制器—Spring提供了DispatcherServlet来对请求进行分发。
    视图帮助(View Helper )—Spring提供了一系列的JSP标签,高效宏来辅助将分散的代码整合在视图里。
    依赖注入—贯穿于BeanFactory / ApplicationContext接口的核心理念。
    工厂模式—BeanFactory用来创建对象的实例。
    

    16.构造方法注入和设值注入有什么区别?

    请注意以下明显的区别:

    在设值注入方法支持大部分的依赖注入,如果我们仅需要注入int、string和long型的变量,我们不要用设值的方法注入。对于基本类型,如果我们没有注入的话,可以为基本类型设置默认值。在构造方法注入不支持大部分的依赖注入,因为在调用构造方法中必须传入正确的构造参数,否则的话为报错。
    
    设值注入不会重写构造方法的值。如果我们对同一个变量同时使用了构造方法注入又使用了设置方法注入的话,那么构造方法将不能覆盖由设值方法注入的值。很明显,因为构造方法尽在对象被创建时调用。
    
    在使用设值注入时有可能还不能保证某种依赖是否已经被注入,也就是说这时对象的依赖关系有可能是不完整的。而在另一种情况下,构造器注入则不允许生成依赖关系不完整的对象。
    
    在设值注入时如果对象A和对象B互相依赖,在创建对象A时Spring会抛出sObjectCurrentlyInCreationException异常,因为在B对象被创建之前A对象是不能被创建的,反之亦然。所以Spring用设值注入的方法解决了循环依赖的问题,因对象的设值方法是在对象被创建之前被调用的。
    

    17.Spring支持的事务管理类型

    Spring支持如下两种方式的事务管理:

    编程式事务管理:这意味着你可以通过编程的方式管理事务,这种方式带来了很大的灵活性,但很难维护。

    声明式事务管理:这种方式意味着你可以将事务管理和业务代码分离。你只需要通过注解或者XML配置管理事务。

    18.Spring框架的事务管理有哪些优点?

    它为不同的事务API(如JTA, JDBC, Hibernate, JPA, 和JDO)提供了统一的编程模型。

    它为编程式事务管理提供了一个简单的API而非一系列复杂的事务API(如JTA).

    它支持声明式事务管理。

    它可以和Spring 的多种数据访问技术很好的融合。

    19.你更推荐那种类型的事务管理?

    许多Spring框架的用户选择声明式事务管理,因为这种方式和应用程序的关联较少,因此更加符合轻量级容器的概念。声明式事务管理要优于编程式事务管理,尽管在灵活性方面它弱于编程式事务管理(这种方式允许你通过代码控制业务)。

    20.@Required 注解

    @Required表明bean的属性必须在配置时设置,可以在bean的定义中明确指定也可通过自动装配设置。如果bean的属性未设置,则抛出BeanInitializationException异常。

    21.@Autowired 注解

    @Autowired 注解提供更加精细的控制,包括自动装配在何处完成以及如何完成。它可以像@Required一样自动装配setter方法、构造器、属性或者具有任意名称和/或多个参数的PN方法。

    1. @Qualifier 注解

    当有多个相同类型的bean而只有其中的一个需要自动装配时,将@Qualifier 注解和@Autowire 注解结合使用消除这种混淆,指明需要装配的bean。

    23.AOP

    AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

    AOP技术恰恰相反,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

    使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

    24.AOP核心概念

    1、横切关注点

    对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点

    2、切面(aspect)

    类是对物体特征的抽象,切面就是对横切关注点的抽象

    3、连接点(joinpoint)

    被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器

    4、切入点(pointcut)

    对连接点进行拦截的定义

    5、通知(advice)

    所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类

    6、目标对象

    代理的目标对象

    7、织入(weave)

    将切面应用到目标对象并导致代理对象创建的过程

    8、引入(introduction)

    在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段

    Spring对AOP的支持

    Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则为:

    1、默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了

    2、当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB

    AOP编程其实是很简单的事情,纵观AOP编程,程序员只需要参与三个部分:

    1、定义普通业务组件

    2、定义切入点,一个切入点可能横切多个业务组件

    3、定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作

    所以进行AOP编程的关键就是定义切入点和定义增强处理,一旦定义了合适的切入点和增强处理,AOP框架将自动生成AOP代理,即:代理对象的方法=增强处理+被代理对象的方法。

    [参考AOP详解](http://www.cnblogs.com/hongwz/p/5764917.html
    [这篇AOP详解讲的最清楚](http://www.cnblogs.com/xrq730/p/4919025.html

    相关文章

      网友评论

        本文标题:Spring常见面试题整理

        本文链接:https://www.haomeiwen.com/subject/xdogwttx.html