一、基础概念
Q:Spring是什么?
定义:Spring是一个轻量级的IoC(控制反转)和AOP容器框架。
目的:用于简化企业应用程序的开发,使得开发者只需要关心业务需求。
常见的配置方式:
- 基于XML的配置
- 基于注解的配置
- 基于Java的配置
组成:
- Spring Core :核心类库,提供IOC服务
- Spring Context :提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等)
- Spring AOP :AOP服务
- Spring DAO :对JDBC的抽象,简化了数据访问异常的处理
- Spring ORM :对现有的ORM框架的支持
- Spring Web :提供了基本的面向Web的综合特性,例如多方文件上传
- Spring MVC :提供面向Web应用的Model-View-Controller实现
- Spring Test:提供了对JUnit和TestNG测试的支持。
Q:使用Spring框架的好处是什么?
- 轻量:Spring 是轻量的,基本的版本大约2MB。
- 低侵入性:低侵入式设计,代码的污染极低
- 控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。
- 面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。
- 容器:Spring 包含并管理应用中对象的生命周期和配置。
- MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
- 事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
- 异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。
Q:Spring配置文件是什么?
Spring配置文件是个XML 文件,一般命名为applicationContext.xml,这个文件包含了类信息,描述了如何配置它们,以及如何相互调用。
Q:ApplicationContext通常的实现是什么?
- FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。
- ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。
- WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。
Q:BeanFactory和ApplicationContext有什么区别?
概述:都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。
区别:
BeanFactory:
- 是Spring里面最底层的接口。
- 以延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。
- 如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。(运行时异常)
ApplicationContext:
- 是BeanFactory的子接口。
- 在容器启动时,一次性创建了所有的Bean。
- 在容器启动时,一次性创建了所有的Bean,我们就可以发现Spring中存在的配置错误。(启动时异常)
Q:Spring 框架中都用到了哪些设计模式?
- 工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例
- 单例模式:Bean默认为单例模式
- 代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术
- 模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate
- 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现 :ApplicationListener
- 适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式、Spring MVC中也是用到了适配器模式适配Controller。
- 包装器设计模式:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
二、IOC/DI
Q:什么是Spring IOC 容器?
Spring IOC 负责创建对象,管理对象,通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。
Q:如何理解IOC和DI?
- IOC: 控制反转
- DI:依赖注入
两个名词是以不同角度来描述Spring的工作,控制反转指的是把创建对象的控制权交由Spring进行处理,从“主动”变成“被动”;依赖注入指的是把配置在Spring容器中,由Spring组装好的对象引入到你自己的对象之中去。
Q:IOC的优点是什么?
IOC 或 DI把应用的代码量降到最低。最小的代价和最小的侵入性实现松耦合。
Q:有哪些不同类型的IOC(依赖注入)方式?
- 构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。
- Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入。
- 根据注解注入:如用@Autowired、@Resource等注解来进行Bean的注入。
三、Spring Beans
Q:什么是Spring beans?
被Spring IOC容器初始化,装配,和管理的,形成Spring应用主干的java对象。(默认为单例 tag="singleton")
Q:Spring容器中Bean的生命周期?
- 实例化Bean并填充属性
- 注入依赖关系
- 初始化
- bean交给应用开发人员处理(进行业务逻辑使用)
- 销毁
Q:创建Spring beans的方式?
- 构造函数:SpringContext利用无参的构造函数创建一个对象,然后利用setter方法赋值。也可以直接通过有参构造函数直接赋值。
- 静态方法创建对象:在类中定义一个返回值为需要获取的对象的构造方法,然后在xml中配置“factory-method”属性指向构造方法。
- 工厂方法创建对象:实例工程方法需要先创建工厂实例,然后在创建所需对象的时候,将其赋值为“factory-bean”
PS:详解见Spring创建对象的三种方式
Q:Spring Bean 定义 包含什么?
一个Spring Bean 的定义包含容器必知的所有配置元数据,包括如何创建一个bean,它的生命周期详情及它的依赖。
PS:元数据主要是描述数据属性(property)的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等。
Q:如何给Spring 容器提供配置元数据?
- XML配置文件。
- 基于注解的配置。
- 基于java的配置。(建立一个SpringConfig的java类用于配置,用@Configuration来注解该类)
PS:详解见Spring中基于java的配置
Q:如何定义Bean的作用域?
可以通过bean 定义中的scope属性来定义。
Spring框架支持以下五种bean的作用域:
- singleton : bean在每个Spring ioc 容器中只有一个实例。(非线程安全!!!)
- prototype:一个bean的定义可以有多个实例。
- request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
- session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
- global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
Q:什么是Spring的内部bean?
当一个bean仅被用作另一个bean的属性时,它能被声明为一个内部bean,为了定义inner bean,在Spring 的 基于XML的 配置元数据中,可以在 <property/>或 <constructor-arg/> 元素内使用<bean/> 元素,内部bean通常是匿名的,它们的Scope一般是prototype。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="person2" class="com.itdjx.spring.dependency.injection.Person"> <property name="name" value="ZH"/> <property name="age" value="25"/> <property name="sex" value="男"/> <property name="car" > <bean class="com.itdjx.spring.dependency.injection.Car"> <constructor-arg value="Audi" index="0"/> <constructor-arg value="德国" index="1"/> <constructor-arg value="300000" type="double"/> </bean> </property> </bean> </beans>