Spring
Spring 原理
它是一个全面的、企业应用开发一站式的解决方案,贯穿表现层、业务层、持久层。但是 Spring 仍然可 以和其他的框架无缝整合。
Spring 特点
轻量级 控制反转 面向切面 容器 框架集合
Spring IOC 原理
概念
Spring 通过一个配置文件描述 Bean 及 Bean 之间的依赖关系,利用 Java 语言的反射功能实例化 Bean 并建立 Bean 之间的依赖关系。 Spring 的 IoC 容器在完成这些底层工作的基础上,还提供了 Bean 实例 缓存、生命周期管理、 Bean 实例代理、事件发布、资源装载等高级服务
如何自定义一个 Spring Boot Starter?
Spring IOC 是什么?优点是什么?
IoC 文英全称 Inversion of Control,即控制反转,我么可以这么理解 IoC 容器:“把某些业务对 象的的控 制权交给一个平台或者框架来同一管理,这个同一管理的平台可以称为 IoC 容器。” ioc 的思想最核心的地方在于,资源不由使用资源的双方管理,而由不使用资源的第三方管理, 这可以带 来很多好处: 1)资源集中管理,实现资源的可配置和易管理 2)降低了使用资源双方的依赖程度,也就是我们说的耦合度
spring 中用到哪些设计模式?
- 1.工厂模式,这个很明显,在各种 BeanFactory 以及 ApplicationContext 创建中都用到了;
- 2.模版模式,这个也很明显,在各种 BeanFactory 以及 ApplicationContext 实现中也都用到了;
- 3.代理模式,在 Aop 实现中用到了 JDK 的动态代理;
- 4.单例模式,这个比如在创建 bean 的时候。
- 5.Tomcat 中有很多场景都使用到了外观模式,因为 Tomcat 中有很多不同的组件,每个组件需要相互通 信,但又不能将自己内部数据过多地暴露给其他组件。用外观模式隔离数据是个很好的方法。
- 6.策略模式在 Java 中的应用,这个太明显了,因为 Comparator 这个接口简直就是为策略模式而生的。 Comparable 和 Comparator 的区别一文中,详细讲了 Comparator 的使用。比方说 Collections 里面有一 个 sort 方法,因为集合里面的元素有可能是复合对象,复合对象并不像基本数据类型,可以根据大小排 序,复合对象怎么排序呢?基于这个问题考虑,Java 要求如果定义的复合对象要有排序的功能,就自行 实现 Comparable 接口或 Comparator 接口.
- 7.原型模式:使用原型模式创建对象比直接 new 一个对象在性能上好得多,因为 Object 类的 clone()方法 是一个 native 方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。
- 8.迭代器模式:Iterable 接口和 Iterator 接口 这两个都是迭代相关的接口,可以这么认为,实现了 Iterable 接口,则表示某个对象是可被迭代的;Iterator 接口相当于是一个迭代器,实现了 Iterator 接 口,等于具体定义了这个可被迭代的对象时如何进行迭代的
Spring IOC 的理解,其初始化过程?
IoC 容器是什么? IoC 文英全称 Inversion of Control,即控制反转,我么可以这么理解 IoC 容器: “把某些业务对象的的控制权交给一个平台或者框架来同一管理,这个同一管理的平台可以称为 IoC 容器。
- Resource 定位(Bean 的定义文件定位)
- 将 Resource 定位好的资源载入到 BeanDefinition
- 将 BeanDefiniton 注册到容器中
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 容器?
控制反转即 IoC (Inversion of Control),它把传统上由程序代码直接操控的对 象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反 转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。 Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象 的整个生命周期。
ApplicationContext 通常的实现是什么?
FileSystemXmlApplicationContext :此容器从一个 XML 文件中加载 beans 的定义,XML Bean 配置文 件的全路径名必须提供给它的构造函数。 ClassPathXmlApplicationContext:此容器也从一个 XML 文件中加载 beans 的定义,这里,你需要正确 设置 classpath 因为这个容器将在 classpath 里找 bean 配置。 WebXmlApplicationContext:此容器加载一个 XML 文件,此文件定义了一个 WEB 应用的所有 bean。
什么是 Spring 的依赖注入?
控制反转 IoC 是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:依赖注入和依赖查 找依赖注入:相对于 IoC 而言,依赖注入(DI)更加准确地描述了 IoC 的设计理念。所谓依赖注入 (Dependency Injection),即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动 态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。组件不做定位查询,只 提供普通的 Java 方法让容器去决定依赖关系。
依赖注入的基本原则
依赖注入的基本原则是:应用组件不应该负责查找资源或者其他依赖的协作对象。配置对象的工作应该 由 IoC 容器负责,“查找资源”的逻辑应该从应用组件的代码中抽取出来,交给 IoC 容器负责。容器全权负 责组件的装配,它会把符合依赖关系的对象通过属性(JavaBean 中的 setter)或者是构造器传递给需要 的对象。
Spring 配置文件包含了哪些信息
Spring 配置文件是个 XML 文件,这个文件包含了类信息,描述了如何配置它们,以及如何相互调用。
Spring 基于 xml 注入 bean 的几种方式
- Set 方法注入;
- 构造器注入:① 通过 index 设置参数的位置;② 通过 type 设置参数类型;
- 静态工厂注入;
- 实例工厂;
你怎样定义类的作用域?
当定义一个 在 Spring 里,我们还能给这个 bean 声明一个作用域。它可以通过 bean 定义中的 scope 属性 来定义。如,当 Spring 要在需要的时候每次生产一个新的 bean 实例,bean 的 scope 属性被指定为 prototype。另一方面,一个 bean 每次使用的时候必须返回同一个实例,这个 bean 的 scope 属性 必须 设为 singleton。
Spring 框架中的单例 bean 是线程安全的吗?
不是,Spring 框架中的单例 bean 不是线程安全的。 spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。 实际上大部分时候 spring bean 无状态的(比如 dao 类),所有某种程度上来说 bean 也是安全的,但 如果 bean 有状态的话(比如 view model 对象),那就要开发者自己去保证线程安全了,最简单的就 是改变 bean 的作用域, 把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean() 了,所以就可以保证线程安全 了。 有状态就是有数据存储功能。 无状态就是不会保存数据。
@Autowired 和@Resource 之间的区别
@Autowired 可用于:构造函数、成员变量、Setter 方法 @Autowired 和@Resource 之间的区别 @Autowired 默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它 required 属性为 false)。 @Resource 默认是按照名称来装配注入的,只有当找不到与名称匹配的 bean 才会按照类型来装配注入。
SpringMVC 面试题
什么是 SpringMvc?
答:SpringMvc 是 spring 的一个模块,基于 MVC 的一个框架,无需中间整合层来整合。
Spring MVC 的优点:答:
- 1)它是基于组件技术的.全部的应用对象,无论控制器和视图,还是业务对象之类的都是 java 组件.并且和 Spring 提供的其他基础结构紧密集成.
- 2)不依赖于 Servlet API(目标虽是如此,但是在实现的时候确实是依赖于 Servlet 的)
- 3)可以任意使用各种视图技术,而不仅仅局限于 JSP
- 4)支持各种请求资源的映射策略
- 5)它应是易于扩展的
SpringMVC 工作原理?答:
- 1)客户端发送请求到 DispatcherServlet
- 2)DispatcherServlet 查询 handlerMapping 找到处理请求的 Controller
- 3)Controller 调用业务逻辑后,返回 ModelAndView
- 4)DispatcherServlet 查询 ModelAndView,找到指定视图
- 5)视图将结果返回到客户端
SpringMVC 流程?答:
- 1) 用户发送请求至前端控制器 DispatcherServlet。
- 2) DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。
- 3) 处理器映射器找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。
- 4) DispatcherServlet 调用 HandlerAdapter 处理器适配器。
- 5) HandlerAdapter 经过适配调用具体的处理器(Controller,也叫后端控制器)。
- 6) Controller 执行完成返回 ModelAndView。
- 7) HandlerAdapter 将 controller 执行结果 ModelAndView 返回给 DispatcherServlet。
- 8) DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器。
- 9) ViewReslover 解析后返回具体 View。
- 10)DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中)。
- 11)DispatcherServlet 响应用户。
SpringMvc 的控制器是不是单例模式,如果是,有什么问题,怎么解决?
答:是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,解决方案是在控制 器里面不能写字段。
如果你也用过 struts2.简单介绍下 springMVC 和 struts2 的区别有哪些?
答:
- 1)springmvc 的入口是一个 servlet 即前端控制器,而 struts2 入口是一个 filter 过虑器。
- 2)springmvc 是基于方法开发(一个 url 对应一个方法),请求参数传递到方法的形参,可以设计为单例 或多例(建议单例),struts2 是基于类开发,传递参数是通过类的属性,只能设计为多例。
- 3)Struts 采用值栈存储请求和响应的数据,通过 OGNL 存取数据,springmvc 通过参数解析器是将 request 请求内容解析,并给方法形参赋值,将数据和视图封装成 ModelAndView 对象,最后又将 ModelAndView 中的模型数据通过 reques 域传输到页面。Jsp 视图解析器默认使用 jstl
SpingMvc 中的控制器的注解一般用那个,有没有别的注解可以替代?
答:一般用@Conntroller 注解,表示是表现层,不能用用别的注解代替。
@RequestMapping 注解用在类上面有什么作用?
答:是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的 方法都是以该地址作为父路径。
怎么样把某个请求映射到特定的方法上面?
答:直接在方法上面加上注解@RequestMapping,并且在这个注解里面写上要拦截的路径
如果在拦截请求中,我想拦截 get 方式提交的方法,怎么配置?
答:可以在@RequestMapping 注解里面加上 method=RequestMethod.GET
怎么样在方法里面得到 Request,或者 Session?
答:直接在方法的形参中声明 request,SpringMvc 就自动把 request 对象传入
我想在拦截的方法里面得到从前台传入的参数,怎么得到?
答:直接在形参里面声明这个参数就可以,但必须名字和传过来的参数一样
如果前台有很多个参数传入,并且这些参数都是一个对象的,那么怎么样快速得到这个对象?
答:直接在方法中声明这个对象,SpringMvc 就自动会把属性赋值到这个对象里面。
SpringMvc 中函数的返回值是什么?
答:返回值可以有很多类型,有 String, ModelAndView,当一般用 String 比较好。
SpringMVC 怎么样设定重定向和转发的?
答:在返回值前面加"forward:"就可以让结果转发,譬如"forward:user.do?name=method4" 在返回值前 面加"redirect:"就可以让返回值重定向,譬如"redirect:http://www.baidu.com"
SpringMvc 用什么对象从后台向前台传递数据的?
答:通过 ModelMap 对象,可以在这个对象里面用 put 方法,把对象加到里面,前台就可以通过 el 表达式 拿到。
SpringMvc 中有个类把视图和数据都合并的一起的,叫什么?
答:叫 ModelAndView。
怎么样把 ModelMap 里面的数据放入 Session 里面?
答:可以在类上面加上@SessionAttributes 注解,里面包含的字符串就是要放入 session 里面的 key
SpringMvc 怎么和 AJAX 相互调用的?
答: 通过 Jackson 框架就可以把 Java 里面的对象直接转化成 Js 可以识别的 Json 对象。 具体步骤如下 : 1)加入 Jackson.jar 2)在配置文件中配置 json 的映射 3)在接受 Ajax 方法里面可以直接返回 Object,List 等,但方法前面要加上@ResponseBody 注解
讲下 SpringMvc 的执行流程
答:系统启动的时候根据配置文件创建 spring 的容器, 首先是发送 http 请求到核心控制器 disPatherServlet,spring 容器通过映射器去寻找业务控制器,使用适配器找到相应的业务类,在进业 务类时进行数据封装,在封装前可能会涉及到类型转换,执行完业务类后使用 ModelAndView 进行视图转发,数据放在 model 中,用 map 传递数据进行页面显示。