框架/面试:Spring

 


 

Spring

 

  • 什么是Spring?

答:spring的核心是一个轻量级的容器(Container),包含并管理应用程序对象的配置及生命周期。

它是实现IoC(Inversion of Control)容器和非侵入性(No intrusive)的框架,

并提供AOP(Aspect-oriented Programming)的实现方式,提供对持久层(Persistence)、事务(Transcation)的支持;

提供MVC Web框架的实现,并对一些常用的企业服务API提供了一致的模型封装,是一个全方位的应用程序框架,除此之外,对现存的各种框架(Struts、JSF、hibernate、Ibatis、Webwork等),Spring也提供了与他们相整合的方案。 

注:IOC(Inversion Of Control )控制反转;将对象的创建和依赖关系交给容器;简单说就是创建对象由以前的程序员自己new构造方法来调用,变成了交由Spring创建对象。

 

  • Spring有哪些优点?

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

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

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

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

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

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

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

 

  • Spring IoC容器是什么?

IoC(Inversion Of Control )控制反转;将对象的创建和依赖关系交给容器;简单说就是创建对象由以前的程序员自己new构造方法来调用,变成了交由Spring创建对象。

Spring IoC负责创建对象、管理对象(通过依赖注入)、整合对象、配置对象以及管理这些对象的生命周期。

 

  • AOP作用是什么?

 AOP——面向切面编程,把应用的业务逻辑与系统的服务分离。即解耦业务代码和公共服务代码(如日志、安全、事务等)。

 

 


 

Bean

 

  • bean配置

bean配置有三种方法:

1.基于xml配置Bean;

2.使用注解定义Bean;

Spring提供了3个功能基本和@Component等效的注解,它们分别用于对DAO、Service及Web层的Controller进行注解,所以也称这些注解为Bean的衍型注解:(类似于xml文件中定义Bean<bean id=" " class=" "/>

  • @Repository:用于对DAO实现类进行标注;
  • @Service:用于对Service实现类进行标注;
  • @Controller:用于对Controller实现类进行标注;

3.基于java类提供Bean定义信息;

Spring容器成功启动的三大要件分别是:Bean定义信息、Bean实现类以及Spring本身。采用基于XML的配置,Bean定义信息和Bean实现类本身是分离的,而采用基于注解的配置方式时,Bean定义信息即通过在Bean实现类上标注注解实现。

 

 

  • bean依赖注入方式

1.使用xml依赖注入

  • 属性注入(即设值注入;无参构造函数+set方法)

属性注入即通过setXxx()方法注入Bean的属性值或依赖对象,由于属性注入方式具有可选择性和灵活性高的优点,因此属性注入是实际应用中最常采用的注入方式。

属性注入要求Bean提供一个默认的构造函数,并为需要注入的属性提供对应的Setter方法。Spring先调用Bean的默认构造函数实例化Bean对象,然后通过反射的方式调用Setter方法注入属性值。

Set注入式一种装配Bean属性的直接方法,但Set注入的一个缺点就是它假设了所有的可变属性都可以通过set方法访问到,无法清晰地表示哪些属性是必须的,哪些属性是可选的。

  • 构造函数注入(含参构造函数)

使用构造函数注入的前提是Bean必须提供带参数的构造函数。

构造注入是在接收注入的类中定义一个构造方法,并在构造方法中定义需要注入的参数。构造注入方式的优势是通过构造方法来强制依赖关系。

  • 工厂方式注入

属性注入和构造注入区别:

1) 在设置注入需要该Bean包含这些属性的setter方法; 
2) 与传统的JavaBean的写法更相似,程序开发人员更容易理解、接收。通过setter方法设定依赖关系显得更加只管; 
3) 对于复杂的依赖关系,如果采用构造注入,会导致构造器参数列表复杂,难以阅读。Spring在创建Bean实例时,需要同时实例化其它依赖的全部实例,因而导致性能下降。而使用设值注入,则能避免这些问题; 
4) 尤其是在某些属性可选的情况况下,多参数的构造器显得更加复杂; 
但是在其他的场景,构造器注入显得更好的性能: 
1) 构造注入需要该Bean包含带有这些属性的构造器; 
2) 构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入; 
3) 对于依赖关系无需变化的Bean,构造注入更有用处。因为没有Setter方法,所有的依赖关系全部在构造器内设定。因此,无需担心后续的代码对依赖关系产生破坏 
4) 依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系。对组件的调用者而言,组件内部的依赖关系完全透明,更符合高内聚的原则.

(个人疑问:构造注入是否需要些set方法?看的所有博客的代码都是有写的……应该是不用写的吧~)

(参考一种说法:set注入和构造注入

 

2.注解方式依赖注入

使用注解的方式注入 @Autowired,@Resource,@Required。

关于@Autowired和@Resource

1.@Autowired注入是按照类型注入的,只要配置文件中的bean类型和需要的bean类型是一致的,这时候注入就没问题。但是如果相同类型的bean不止一个,此时注入就会出现问题,Spring容器无法启动。 
2.@Resourced标签是按照bean的名字来进行注入的,如果我们没有在使用@Resource时指定bean的名字,同时Spring容器中又没有该名字的bean,这时候@Resource就会退化为@Autowired即按照类型注入,这样就有可能违背了使用@Resource的初衷。所以建议在使用@Resource时都显示指定一下bean的名字@Resource(name="xxx") 

参考:bean配置和注入 (写得很好,推荐)

 

  • 如何定义bean的作用域?

在Spring中创建一个bean的时候,我们可以声明它的作用域。只需要在bean定义的时候通过’scope’属性定义即可。例如,当Spring需要产生每次一个新的bean实例时,应该声明bean的scope属性为prototype。如果每次你希望Spring返回一个实例,应该声明bean的scope属性为singleton。

 

  • Spring中支持的bean作用域

Spring框架支持如下五种不同的作用域:

singleton:在Spring IOC容器中仅存在一个Bean实例,Bean以单实例的方式存在。

prototype:一个bean可以定义多个实例。 

request:每次HTTP请求都会创建一个新的Bean。该作用域仅适用于WebApplicationContext环境。

session:一个HTTP Session定义一个Bean。该作用域仅适用于WebApplicationContext环境. 

globalSession:同一个全局HTTP Session定义一个Bean。该作用域同样仅适用于WebApplicationContext环境.

bean默认的scope属性是’singleton‘。

 

  • bean的生命周期

 

Spring容器读取XML文件中bean的定义并实例化bean。

Spring根据bean的定义设置属性值。

如果该Bean实现了BeanNameAware接口,Spring将bean的id传递给setBeanName()方法。

如果该Bean实现了BeanFactoryAware接口,Spring将beanfactory传递给setBeanFactory()方法。

如果任何bean BeanPostProcessors 和该bean相关,Spring调用postProcessBeforeInitialization()方法。

如果该Bean实现了InitializingBean接口,调用Bean中的afterPropertiesSet方法。如果bean有初始化函数声明,调用相应的初始化方法。

如果任何bean BeanPostProcessors 和该bean相关,调用postProcessAfterInitialization()方法。

如果该bean实现了DisposableBean,调用destroy()方法。

 

 

 

参考:bean生命周期

 

 


 

 

模块

 

  • Spring有哪些模块?

七大模块,如下: 

1. Spring Core: Core封装包是框架的最基础部分,提供IOC和依赖注入特性。这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。 

2.Spring Context: 构建于Core封装包基础上的 Context封装包,提供了一种框架式的对象访问方法,有些象JNDI注册器。Context封装包的特性得自于Beans封装包,并添加了对国际化(I18N)的支持(例如资源绑定),事件传播,资源装载的方式和Context的透明创建,比如说通过Servlet容器。 

3.Spring DAO: DAO (Data Access Object)提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码。 并且,JDBC封装包还提供了一种比编程性更好的声明性事务管理方法,不仅仅是实现了特定接口,而且对所有的POJOs(plain old Java objects)都适用。 

4.Spring ORM: ORM 封装包提供了常用的“对象/关系”映射APIs的集成层。 其中包括JPA、JDO、Hibernate 和 iBatis 。利用ORM封装包,可以混合使用所有Spring提供的特性进行“对象/关系”映射,如前边提到的简单声明性事务管理。 

5.Spring AOP: Spring的 AOP 封装包提供了符合AOP Alliance规范的面向方面的编程实现,让你可以定义,例如方法拦截器(method-interceptors)和切点(pointcuts),从逻辑上讲,从而减弱代码的功能耦合,清晰的被分离开。而且,利用source-level的元数据功能,还可以将各种行为信息合并到你的代码中。 

6.Spring Web: Spring中的 Web 包提供了基础的针对Web开发的集成特性,例如多方文件上传,利用Servlet listeners进行IOC容器初始化和针对Web的ApplicationContext。当与WebWork或Struts一起使用Spring时,这个包使Spring可与其他框架结合。 

7.Spring Web MVC: Spring中的MVC封装包提供了Web应用的Model-View-Controller(MVC)实现。Spring的MVC框架并不是仅仅提供一种传统的实现,它提供了一种清晰的分离模型,在领域模型代码和Web Form之间。并且,还可以借助Spring框架的其他特性。

 

  • 解释抽象JDBC和DAO模块

通过使用抽象JDBC和DAO模块保证了与数据库连接代码的整洁与简单,同时避免了由于未能关闭数据库资源引起的问题。它在多种数据库服务器的错误信息之上提供了一个很重要的异常层。它还利用Spring的AOP模块为Spring应用程序中的对象提供事务管理服务。

 

  • 解释对象/关系映射集成(ORM)模块

Spring通过提供ORM模块在JDBC的基础上支持对象关系映射工具。这样的支持使得Spring可以集成主流的ORM框架,包括Hibernate, JDO, 及iBATIS SQL Maps。Spring的事务管理可以同时支持以上某种框架和JDBC。

 

  • 解释web模块

Spring的web模块建立在应用上下文(application context)模块之上,提供了一个适合基于web应用程序的上下文环境。该模块还支持了几个面向web的任务,如透明的处理多文件上传请求及将请求参数同业务对象绑定起来。

 

  • 解释Spring MVC模块

Spring提供MVC框架构建web应用程序。Spring可以很轻松的同其他MVC框架结合,但Spring的MVC是个更好的选择,因为它通过控制反转将控制逻辑和业务对象完全分离开来。

 

 


 

 

5.BeanFactory – BeanFactory 实例

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

最常用的BeanFactory实现是XmlBeanFactory类。

6.XmlBeanFactory

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

33.解释自动装配的各种模式?

自动装配提供五种不同的模式供Spring容器用来自动装配beans之间的依赖注入:

  • no:默认的方式是不进行自动装配,通过手工设置ref 属性来进行装配bean。

  • byName:通过参数名自动装配,Spring容器查找beans的属性,这些beans在XML配置文件中被设置为byName。之后容器试图匹配、装配和该bean的属性具有相同名字的bean。

  • byType:通过参数的数据类型自动自动装配,Spring容器查找beans的属性,这些beans在XML配置文件中被设置为byType。之后容器试图匹配和装配和该bean的属性类型一样的bean。如果有多个bean符合条件,则抛出错误。

  • constructor:这个同byType类似,不过是应用于构造函数的参数。如果在BeanFactory中不是恰好有一个bean与构造函数参数相同类型,则抛出一个严重的错误。

  • autodetect:如果有默认的构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。

参考:Spring面试题

 


 

posted @ 2017-03-06 21:09  不闻余物  阅读(174)  评论(0编辑  收藏  举报