Spring相关面试题总结

一、简介

本文将总结一些现在非常流行的开源框架Spring相关的面试题。

二、面试题

【1】什么是Spring框架?Spring框架有哪些主要模块?

Spring框架是一个轻量级的Java开发框架,为应用开发提供平台。

包含模块:

  • Spring AOP 面向切面编程
  • Spring ORM Hibernate|mybatis|JDO
  • Spring Core 提供bean工厂 IOC
  • Spring Dao JDBC支持
  • Spring Context 提供了关于UI支持,邮件支持等
  • Spring Web 提供了web的一些工具类的支持
  • Spring MVC 提供了web mvc , webviews , jsp ,pdf ,export

【2】使用Spring框架能带来哪些好处?

  • 1、Dependency Injection(DI)方法使得构造器和JavaBean properties文件中的依赖关系一目了然。
  • 2、与EJB容器相比较,Ioc容器更加趋向于轻量级。这样一来Ioc容器在邮箱的内存和CPU资源的情况下进行应用程序的开发和发布就变得十分有利。
  • 3、Spring并没有闭门造车,Spring利用了已有的技术比如ORM框架、logging框架、J2EE、Quartz和JDK Timer,以及其他视图技术。
  • 4、Spring框架是按照模块的形式来组织的。由包和类的编号就可以看出其所属的模块,开发者仅仅需要选用他们需要的模块即可。
  • 5、要测试一项用Spring开发的应用程序十分简单,因为测试相关的环境代码都已经襄括在框架中了。更加简单的是,利用javaBean形式的POJO类,可以很方便的利用依赖注入来写入测试数据。
  • 6、Spring的Web框架亦是一个精心设计的Web MVC框架,为开发者们在web框架的选择上提供了一个除了主流框架比如Struts、过度设计的、不流行Web框架的以外的有力选项。
  • 7、Spring提供了一个便捷的事务管理接口,适用于小型的本地事务处理(比如在单DB的环境下)和复杂的共同事务处理(比如利用JTA的复杂DB环境)。

【3】什么是控制反转?什么是依赖注入?

控制反转IOC:

  • 传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活(即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找)。

依赖注入DI:

  • DI—Dependency Injection,即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

依赖注入的三种实现方式:

  • 构造器注入
  • setter方法注入
  • 接口注入

【4】请解释下Spring框架中的IOC?

把对象的创建、初始化、销毁交给Spring容器来管理,而不是由开发者控制,实现了控制权的反转,这就是Spring中的IOC容器。Spring中的 org.springframework.beans包和org.springframework.context包构成了Spring框架 IOC容器的基础。BeanFactory是IOC容器的具体实现,用来包装盒管理各种Bean。

【5】BeanFactory和ApplicationContext有什么区别?

BeanFactory:可以理解为含有bean集合的工厂类,包含了各种bean的定义,以便在接收到客户端请求时将对应的bean实例化。BeanFactory还能在实例化对象的时候生成协作类之间的关系,并且包含了对Bean生命周期的控制,调用客户端的初始化方法和销毁方法。

ApplicationContext:同样具有bean定义、bean关联关系的设置,根据请求分发bean的功能,但application context 还提供了其他功能,如:

  • 支持国际化的文本消息
  • 统一的资源文件读取方式
  • 监听器事件
ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”);
ApplicationContext context = new FileSystemXmlApplicationContext(“bean.xml”);
XmlWebApplicationContext: 由web应用的XML文件读取上下文
AnnotationConfigApplicationContext

【6】Spring有哪几种配置方式?

  • 基于XML方式配置
  • 基于注解方式配置
  • 基于Java的配置

【7】如何用基于Java配置的方式配置Spring?

Spring对Java配置的支持是由@Configuration注解和޾@Bean注解来实现的。

  • @Bean:由@Bean注解的方法将会被实例化、配置和初始化一个新对象,这个对象由IOC容器来进行管理。
  • @Configuration:被 @Configuration所注解的类则表示这个类的目的是作为Bean定义的资源,被 @Configuration声明的类可以通过在同一个类的内部调用@Bean方法来设置嵌入bean的依赖关系。

【8】请解释Spring Bean的生命周期?

在一个bean实例被初始化时,需要执行一系列的初始化操作以达到可用的状态。同样的,当一个bean不再被调用的时候,就需要从Spring容器中移除掉。Spring bean factory负责管理spring容器中被创建的bean的生命周期,bean的生命周期由两组回调方法组成:

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

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

  • InitializingBean和DisposableBean回调接口
  • 针对特殊行为的其他Aware接口
  • Bean配置文件中的custom init()和destroy()方法
  • @PostConstruct、@PreDestroy 注解方式

【9】Spring Bean的作用域之间有什么区别?

Bean的作用域主要有下面五种:

  • singleton:默认作用域范围,不管接收到多少个请求,容器中只会存在一个bean实例对象,单例的模式由baen factory自身来维护
  • prototype:原型作用域范围,为每一个请求生成一个bean实例对象
  • request:在请求bean范围内会每一个来自客户端的请求创建一个实例,在请求完成之后,bean就会失效并被容器移除
  •  Session:每个session范围内只会有一个bean的实例,在session过期后,bean也会跟着失效。
  •  global- session:全局作用域

【10】请谈谈Spring有哪些自动装配模式以及各自的区别?

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

【11】构造方法注入和设值注入有什么区别?

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

【12】Spring框架中有哪些不同类型的事件?

ApplicationContext提供了支持事件和代码中监听器的功能。如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent被发布以后,bean会自动被通知。

【13】FileSystemResource和ClassPathResource有何区别?

在FileSystemResource 中需要给出spring-config.xml文件在你项目中的相对路径或者绝对路径。

在ClassPathResource中spring会在ClassPath中自动搜寻配置文件,所以要把ClassPathResource 文件放在ClassPath下。如果将spring-config.xml保存在了src文件夹下的话,只需给出配置文件的名称即可,因为src文件夹是默认。

简而言之,ClassPathResource在环境变量中读取配置文件,FileSystemResource在配置文件中读取配置文件。

【14】Spring框架中使用到了哪些设计模式?

  • 代理模式—在AOP和remoting中被用的比较多
  • 单例模式—在spring配置文件中定义的bean默认为单例模式
  • 模板方法—用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate
  • 工厂模式—BeanFactory用来创建对象的实例

【15】开发中主要使用Spring的什么技术?

  • IOC容器统一管理Bean
  • @Transactional声明式事务
  • AOP切面
  • 整合其他框架方便开发

【16】在Spring中如何配置Bean?

  • 通过全限定名(反射)
  • 通过工厂方法(静态工厂方法、实例工厂方法)
  • FactoryBean工厂

【17】请简述一下IOC容器对Bean的生命周期?

  • 通过构造器或工厂方法创建bean实例;
  • 为bean的属性设置值和对其他bean的引用;
  • 将bean实例传递给bean后置处理器的postProcessBeforeInitialization方法;
  • 调用bean的初始方法(init-method);
  • 将bean实例传递给bean后置处理器的postProcessAfterInitialization方法;
  • 使用bean对象;
  • 当容器关闭时,调用bean的销毁方法(destroy-method);

【18】请说说常用的几个Spring注解及其作用?

  • @Required:应用于设值方法;
  • @Autowired:应用于有值设置方法、非设置方法、构造方法和变量;
  • @Qualifier:和@Autowired注解搭配使用,用于消除特定bean自动装配的歧义,告诉Spring容器要装配哪一个Bean;
  • @Resource:也是用于注入Bean对象;
  • @PostConstruct:初始化之后执行的方法
  • @PreDestroy: 销毁之前执行的方法
  • @Bean:主要被用在方法上,来显式声明要用生成的类
  • @Configuration:声明某个类是一个配置类
  • @Component :注册Bean对象,把普通pojo实例化到spring容器中
  • @Repository、@Service、@Controller
  • @WebListener:注册监听器
  • @WebFilter:注册监听器

【19】Spring AOP 实现原理?

  • Spring AOP 中的动态代理主要有两种方式,JDK 动态代理和 CGLIB 动态代理。
  • JDK 动态代 理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK 动态代理的核心是 InvocationHandler 接口和 Proxy 类。
  • 如果目标类没有实现接口,那么 Spring AOP 会选择使用 CGLIB 来动态代理目标类。CGLIB (Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为 final, 那么它是无法使用 CGLIB 做动态代理的。

【20】Spring 的单例实现原理?

Spring 对 Bean 实例的创建是采用单例注册表的方式进行实现的,而这个注册表的缓存是 ConcurrentHashMap 对象。

三、总结

下面分享脑图总结:

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付 19.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值