Spring框架常见面试题
1. 你对Spring框架的理解(特点)? Spring框架有哪些模块 ?
- Spring,一种用来简化企业应用级开发的一种开源框架。
- 简化开发:它对常用的API做了封装,比如对JDBC的封装,使用Spring JDBC访问数据库,就不需要考虑如何获取连接和关闭的问题。
- 解耦:Spring帮我们管理软件之间的依赖关系,这样对象之间的耦合性就降低了,这样的维护性就得到了提高。
- 集成其它框架:方便扩展和优化其功能,例如和Mybatis的集成等。
- Spring框架是按照设计模式精心打造的,这使得我们在开发环境中,能方便的使用框架,不用考虑后台是怎么进行的。
- Spring容器是Spring框架中一个核心的模块,用来管理对象的创建,销毁和初始化扥操作,以及对象之间的依赖关系等。
- 目前Spring框架已经集合成20多个模块:
2. Spring的优点 ?
- 简化开发,解耦,集成其它框架。
- 低侵入式设计,代码污染级别级别。
- Spring的DI机制降低了业务对象替换的复杂性,提高了软件之间的解耦。
- Spring AOP支持将一些通用的任务进行集中式的管理,例如:安全,事务,日志等,从而使代码能更好的复用。
3. 什么是控制反转(IOC),什么是依赖注入(DI)?
- IOC:就是对象之间的依赖关系由容器来创建,对象之间的关系本来是由我们开发者自己创建和维护的,在我们使用Spring框架后,对象之间的关系由容器来创建和维护,将开发者做的事让容器做,这就是控制反转。BeanFactory接口是Spring Ioc容器的核心接口。
- DI:我们在使用Spring容器的时候,容器通过调用set方法或者是构造器来建立对象之间的依赖关系。
- 控制反转是目标,依赖注入是我们实现控制反转的一种手段。
4. Java中实现依赖注入的三种方式?
- 构造器注入
- set方法注入
- 接口注入
5.Spring容器中如何创建对象?
无参构造创建 静态工厂创建 实例工厂创建
6. Spring有几种配置方式 ?
- 基于XML文件的配置 这种配置文件的格式常用<beans>开头,然后运用一系列的bean定义和专门的应用配置选项组成。 Spring XML配置方式是使用被Spring命名空间所支持的一些列XML的标签来实现的。
- 基于注解的配置 可以使用注解的方式来代替XML方式的bean元素的配置。这就是组件扫描,常用依赖注入的一些注解有: @Controller @Service @Autowired @RequestMapping @RequestParam @ModelAttribute @Cacheable @CacheFlush @Resource @PostConstruct @PreDestroy @Repository @Scope @SessionAttributes @InitBinder @Required @Qualifier
- 组件扫描: 容器会扫描base-package指定的包及其子包下面的所有类,如果该类有一些特定的注解,则纳入容器进行管理。
- 在类前面添加的一些特定的注解: @Component 通用注解 @Repository 持久层注解 @Service 业务层注解、 @Controller 控制层注解
- 基于Java的配置
7. Spring Bean的生命周期 ?
- 指Spring中bean元素被实例化,和被销毁的过程。我们通过init-method属性指定初始化方法; 通过destroy-method方法指定销毁方法。
- 注意:只有作用域为Singleton的时候才会有效。
8. 解释什么叫延迟加载 ?
- 默认情况下,容器启动之后会将所有作用域为单例的bean创建好;但是有的业务场景我们并不需要它提前都创建好;
- 此时,我们可以在bean中设置lzay-init=“true”,这样,当容器启动之后,作用域为单例的bean,就不在创建。
9. 解释什么是自动装配 ?
- 就是将一个Bean注入到其它的Bean的Property中,默认情况下,容器不会自动装配,需要我们手动设定。Spring 可以通过向Bean Factory中注入的方式来搞定bean之间的依赖关系,达到自动装配的目的。
- 自动装配建议少用,如果要使用,建议使用ByName
10. Spring bean元素的作用域?
- 当通过Spring容器创建一个Bean实例的时候,不仅可以完成bean实例的实力化,还可以为bean指定作用域。Spring bean元素的支持以下5种作用域:
- Singleton:单例模式,在整个spring IOC容器中,使用singleton定义的bean将只有一个实例。
- Prototype:多例模式,每次通过容器中的getBean方法获取prototype定义的beans时,都会产生一个新的bean的实例。
- Request:对于每次Http请求,使用request定义的bean都会产生一个新的实例,只有在web应用时候,该作用域才会有效。
- Session:对于每次Http Session,使用session定义的Bean都将产生一个新的实例。
- Globalsession:每个全局的Http Sesisonn,使用session定义的本都将产生一个新的实例。
11. Spring中的bean是线程安全的么?
- Spring框架并没有对单例的bean进行多线程的封装处理,线程安全问题和并发问题,需要我们开发者自己考虑。
- 但实际上,大部分的Spring bean并没有可变的状态(比如:service类和dao类),所有在某种程度上来说Spring单例bean是线程安全的。如果bean有多种状态的话(比如:View Model对象),就需要自行考虑线程安全问题。
12. 如何在Spring中注入一个Java Collection ?
- Spring提供理论四种集合类的配置元素:
- lt;List&: 该标签用来装配 有重复值的list值
- lt;set&: 该标签用来装配没有重复值的 set值
- lt;map&:该标签科以用来注入键值对
- lt;props&: 该标签用来支持注入键值对和字符串类型键值对。
13. Spring框架中都用到了哪些设计模式 ?
- 代理模式,在AOP中被使用最多。
- 单例模式,在Spring配置文件中定义bean的时候默认的是单例模式。
- 工厂模式, BeanFactory用来创建对象的实例。
- 模板方法, 用来解决重复性代码。
- 前端控制器,Spring提供了DispatcherSerclet来对请求进行分发。
- 视图帮助,Spring提供了一系列的JSP标签。
- 依赖注入,它是惯穿于BeanFactory/ApplicationContext接口的核心理念。
14. Spring中的事件处理 ?
- Spring 的核心是ApplicatonContext,它负责管理bean的完整的生命周期。Spring提供了以下内置事件: ContextRefreshedEvent ContextStartedEvent ContextStoppedEvent ContextClosedEvent RequestHandleEvent
- 由于 Spring 的事件处理是单线程的,所以如果一个事件被发布,直至并且除非所有的接收者得到的该消息,该进程被阻塞并且流程将不会继续。因此,如果事件处理被使用,在设计应用程序时应注意。
- 监听上下文事件
- 自定义事件
15. Spring AOP(面向切面)编程的原理 ?
- AOP面向切面编程,它是一种思想。它就是针对业务处理过程中的切面进行提取,以达到优化代码的目的,减少重复代码的目的。 就比如,在编写业务逻辑代码的时候,我们习惯性的都要写:日志记录,事物控制,以及权限控制等,每一个子模块都要写这些代码,代码明显存在重复。这时候,我们运用面向切面的编程思想,采用横切技术,将代码中重复的部分,不影响主业务逻辑的部分抽取出来,放在某个地方进行集中式的管理,调用。 形成日志切面,事物控制切面,权限控制切面。 这样,我们就只需要关系业务的逻辑处理,即提高了工作的效率,又使得代码变的简洁优雅。这就是面向切面的编程思想,它是面向对象编程思想的一种扩展。
- AOP的使用场景: 缓存、权限管理、内容传递、错误处理、懒加载、记录跟踪、优化、校准、调试、持久化、资源池、同步管理、事物控制等。 AOP的相关概念: 切面(Aspect) 连接点(JoinPoint) 通知(Advice) 切入点(Pointcut) 代理(Proxy): 织入(WeaVing)
- Spring AOP的编程原理? 代理机制 JDK的动态代理:只能用于实现了接口的类产生代理。 Cglib代理:针对没有实现接口的类产生代理,应用的是底层的字节码增强技术,生成当前类的子类对象。
16. 解释一下代理模式(Proxy)
- 代理模式: 代理模式就是本该我做的事,我不做,我交给代理人去完成。就比如,我生产了一些产品,我自己不卖,我委托代理商帮我卖,让代理商和顾客打交道,我自己负责主要产品的生产就可以了。 代理模式的使用,需要有本类,和代理类,本类和代理类共同实现统一的接口。然后在main中调用就可以了。本类中的业务逻辑一般是不会变动的,在我们需要的时候可以不断的添加代理对象,或者修改代理类来实现业务的变更。
- 代理模式可以分为: 静态代理 优点:可以做到在不修改目标对象功能的前提下,对目标功能扩展 缺点:因为本来和代理类要实现统一的接口,所以会产生很多的代理类,类太多,一旦接口增加方法,目标对象和代理对象都要维护。 动态代理(JDK代理/接口代理) 代理对象,不需要实现接口,代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象,需要我们指定代理对象/目标对象实现的接口的类型。 Cglib代理 特点: 在内存中构建一个子类对象,从而实现对目标对象功能的扩展。
- 使用场景: 修改代码的时候。不用随便去修改别人已经写好的代码,如果需要修改的话,可以通过代理的方式来扩展该方法。 隐藏某个类的时候,可以为其提供代理类 当我们要扩展某个类功能的时候,可以使用代理类 当一个类需要对不同的调用者提供不同的调用权限的时候,可以使用代理类来实现。 减少本类代码量的时候。 需要提升处理速度的时候。就比如我们在访问某个大型系统的时候,一次生成实例会耗费大量的时间,我们可以采用代理模式,当用来需要的时候才生成实例,这样就能提高访问的速度。