Spring面试题
- 一、Spring概述
- 二、Spring控制反转(IOC)
-
- 1. 什么是Spring IOC 容器?
- 2. 控制反转(IoC)有什么作用
- 3. IOC的优点是什么?
- 4. Spring IoC 的实现机制
- 5. Spring 的 IoC支持哪些功能
- 6. BeanFactory 和 ApplicationContext有什么区别?
- 7. Spring 如何设计容器的,BeanFactory和ApplicationContext的关系详解,Spring 作者 Rod Johnson 设计了两个接口用以表示容器。
- 8. ApplicationContext通常的实现是什么?
- 9. 什么是Spring的依赖注入?
- 10. 依赖注入的基本原则
- 11. 依赖注入有什么优势
- 12. 有哪些不同类型的依赖注入实现方式?
- 13. 构造器依赖注入和 Setter方法注入的区别
- 三、Spring Beans
-
- 1. 什么是Spring beans?
- 2. 一个 Spring Bean 定义 包含什么?
- 3. 如何给Spring 容器提供配置元数据?Spring有几种配置方式
- 4. Spring配置文件包含了哪些信息
- 5. Spring基于xml注入bean的几种方式
- 6. 你怎样定义类的作用域?
- 7. 解释Spring支持的几种bean的作用域
- 8. Spring框架中的单例bean是线程安全的吗?
- 9. Spring如何处理线程并发问题?
- 10. 解释Spring框架中bean的生命周期
- 11. 哪些是重要的bean生命周期方法? 你能重载它们吗?
- 12. 什么是Spring的内部bean?什么是Spring inner beans?
- 13. 在 Spring中如何注入一个java集合?
- 14. 什么是bean装配?
- 15. 什么是bean的自动装配?
- 16. 解释不同方式的自动装配,spring 自动装配 bean 有哪些方式?
- 17. 使用@Autowired注解自动装配的过程是怎样的?
- 18. 自动装配有哪些局限性?
- 19. 你可以在Spring中注入一个null 和一个空字符串吗?
- 四、Spring注解
- 五、Spring数据访问
-
- 1. 解释对象/关系映射集成模块
- 2. 在Spring框架中如何更有效地使用JDBC?
- 3. 解释JDBC抽象和DAO模块
- 4. spring DAO 有什么用?
- 5. spring JDBC API 中存在哪些类?
- 7. 使用Spring通过什么方式访问Hibernate?使用 Spring 访问 Hibernate 的方法有哪些?
- 8. 如何通过HibernateDaoSupport将Spring和Hibernate结合起来?
- 9. Spring支持的事务管理类型, spring 事务实现方式有哪些?
- 10. Spring事务的实现方式和实现原理
- 11. 说一下Spring的事务传播行为
- 12. 说一下 spring 的事务隔离?
- 13. Spring框架的事务管理有哪些优点?
- 14. 你更倾向用哪种事务管理类型?
- 六、Spring面向切面编程(AOP)
-
- 1. 什么是AOP
- 2. Spring AOP and AspectJ AOP 有什么区别?AOP 有哪些实现方式?
- 3. JDK动态代理和CGLIB动态代理的区别
- 4. 如何理解 Spring 中的代理?
- 5. 解释一下Spring AOP里面的几个名词
- 6. Spring在运行时通知对象
- 7. Spring只支持方法级别的连接点
- 8. 在Spring AOP 中,关注点和横切关注的区别是什么?在 spring aop 中 concern 和 cross-cutting concern 的不同之处
- 9. Spring通知有哪些类型?
- 10. 什么是切面 Aspect?
- 11. 解释基于XML Schema方式的切面实现
- 12. 解释基于注解的切面实现
- 13. 有几种不同类型的自动代理?
一、Spring概述
1. 什么是spring?
Spring是一个轻量级Java开发框架,最早由Rod Johnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEE full-stack(一站式)轻量级开源框架,为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构,因此Java开发者可以专注于应用程序的开发
Spring最根本的使命是解决企业级应用开发的复杂性,即简化Java开发
Spring可以做很多事情,它为企业级开发提供给了丰富的功能,但是这些功能的底层都依赖于它的两个核心特性,也就是依赖注入(dependency injection,DI)和面向切面编程(aspect-oriented programming,AOP)。
为了降低Java开发的复杂性,Spring采取了以下4种关键策略:
- 基于POJO的轻量级和最小侵入性编程;
- 通过依赖注入和面向接口实现松耦合;
- 基于切面和惯例进行声明式编程;
- 通过切面和模板减少样板式代码。
2. Spring框架的设计目标,设计理念,和核心是什么?
Spring设计目标:Spring为开发者提供一个一站式轻量级应用开发平台;
Spring设计理念:在JavaEE开发中,支持POJO和JavaBean开发方式,使应用面向接口开发,充分支持OO(面向对象)设计方法;Spring通过IoC容器实现对象耦合关系的管理,并实现依赖反转,将对象之间的依赖关系交给IoC容器,实现解耦
Spring框架的核心:IoC容器和AOP模块。通过IoC容器管理POJO对象以及他们之间的耦合关系;通过AOP以动态非侵入的方式增强服务。
IoC让相互协作的组件保持松散的耦合,而AOP编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件。
3. Spring的优缺点是什么?
优点
- ①. 方便解耦,简化开发 Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护,交给Spring管理。
- ②. AOP编程的支持 Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。
- ③. 声明式事务的支持 只需要通过配置就可以完成对事务的管理,而无需手动编程。
- ④. 方便程序的测试 Spring对Junit4支持,可以通过注解方便的测试Spring程序。
- ⑤. 方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架的直接支持(如:Struts、Hibernate、MyBatis等)。 - ⑥. 降低JavaEE API的使用难度
Spring对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。
缺点
- ①Spring明明一个很轻量级的框架,却给人感觉大而全
- ②Spring依赖反射,反射影响性能
- ③使用门槛升高,入门Spring需要较长时间
4. Spring有哪些应用场景
应用场景:JavaEE企业应用开发,包括SSH、SSM等
Spring价值:
- Spring是非侵入式的框架,目标是使应用程序代码对框架依赖最小化;
- Spring提供一个一致的编程模型,使应用直接使用POJO开发,与运行环境隔离开来;
- Spring推动应用设计风格向面向对象和面向接口开发转变,提高了代码的重用性和可测试性;
5. Spring由哪些模块组成?
Spring 总共大约有 20 个模块, 由 1300 多个不同的文件构成。 而这些组件被分别整合在核心容器(Core Container) 、 AOP(Aspect Oriented Programming)和设备支持(Instrmentation) 、数据访问与集成(Data Access/Integeration) 、 Web、 消息(Messaging) 、 Test等 6 个模块中。 以下是 Spring 5 的模块结构:
- spring core:提供了框架的基本组成部分,包括控制反转(Inversion of
Control,IOC)和依赖注入(Dependency Injection,DI)功能。 - spring beans:提供了BeanFactory,是工厂模式的一个经典实现,Spring将管理对象称为Bean。
- spring context:构建于 core 封装包基础上的 context 封装包,提供了一种框架式的对象访问方法。
- spring jdbc:提供了一个JDBC的抽象层,消除了烦琐的JDBC编码和数据库厂商特有的错误代码解析, 用于简化JDBC。
- spring aop:提供了面向切面的编程实现,让你可以自定义拦截器、切点等。
- spring Web:提供了针对 Web 开发的集成特性,例如文件上传,利用 servlet listeners 进行 ioc
容器初始化和针对 Web 的 ApplicationContext。 - spring test:主要为测试提供支持的,支持使用JUnit或TestNG对Spring组件进行单元测试和集成测试。
6. Spring 框架中都用到了哪些设计模式?
- 工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
- 单例模式:Bean默认为单例模式。
- 代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
- 模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
- 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。
7. 详细讲解一下核心容器(spring context应用上下文) 模块
这是基本的Spring模块,提供spring 框架的基础功能,BeanFactory 是 任何以spring为基础的应用的核心。Spring 框架建立在此模块之上,它使Spring成为一个容器。
Bean 工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从真正的应用代码中分离。最常用的就是org.springframework.beans.factory.xml.XmlBeanFactory ,它根据XML文件中的定义加载beans。该容器从XML 文件读取配置元数据并用它去创建一个完全配置的系统或应用。
8. Spring框架中有哪些不同类型的事件
Spring 提供了以下5种标准的事件:
- 上下文更新事件(ContextRefreshedEvent):在调用ConfigurableApplicationContext
接口中的refresh()方法时被触发。 - 上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。
- 上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
- 上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
- 请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent
被发布以后,bean会自动被通知。
9.Spring 应用程序有哪些不同组件?
Spring 应用一般有以下组件:
- 接口 - 定义功能。
- Bean 类 - 它包含属性,setter 和 getter 方法,函数等。
- Bean 配置文件 - 包含类的信息以及如何配置它们。
- Spring 面向切面编程(AOP) - 提供面向切面编程的功能。
- 用户程序 - 它使用接口。
10. 使用 Spring 有哪些方式?
使用 Spring 有以下方式:
- 作为一个成熟的 Spring Web 应用程序。
- 作为第三方 Web 框架,使用 Spring Frameworks 中间层。
- 作为企业级 Java Bean,它可以包装现有的 POJO(Plain Old Java Objects)。 用于远程使用。
二、Spring控制反转(IOC)
1. 什么是Spring IOC 容器?
控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。
Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。
2. 控制反转(IoC)有什么作用
- 管理对象的创建和依赖关系的维护。对象的创建并不是一件简单的事,在对象关系比较复杂时,如果依赖关系需要程序猿来维护的话,那是相当头疼的
- 解耦,由容器去维护具体的对象
- 托管了类的产生过程,比如我们需要在类的产生过程中做一些处理,最直接的例子就是代理,如果有容器程序可以把这部分处理交给容器,应用程序则无需去关心类是如何完成代理的
3. IOC的优点是什么?
- IOC 或 依赖注入把应用的代码量降到最低。
- 它使应用容易测试,单元测试不再需要单例和JNDI查找机制。
- 最小的代价和最小的侵入性使松散耦合得以实现。
- IOC容器支持加载服务时的饿汉式初始化和懒加载。
4. Spring IoC 的实现机制
Spring 中的 IoC 的实现原理就是工厂模式加反射机制。
实例:
interface Fruit {
public abstract void eat();
}
class Apple implements Fruit {
public void eat(){
System.out.println("Apple");
}
}
class Orange implements Fruit {
public void eat(){
System.out.println("Orange");
}
}
class Factory {
public static Fruit getInstance(String ClassName) {
Fruit f=null;
try {
f=