Spring 框架现在是 Java 后端框架家族里面最强大的一个,其拥有 IOC 和 AOP 两大利器,大大简化了软件开发复杂性。并且,Spring 现在能与所有主流开发框架集成,可谓是一个万能框架,Spring 让 JAVA 开发变得更多简单。
面试真题:
(1)什么是控制反转(IOC)?什么是依赖注入?
- 控制反转就是我们说的IOC,它是一种思想,就是 将原本在程序中手动创建对象的控制权,交由Spring框架来管理。 IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个Map(key,value),Map 中存放的是各种对象。 IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。
- 依赖注入是同一个概念。含义是:当一个java实例需要另一个java实例时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者 实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。在java中依赖注入有三种实现方式:
1、构造器注入
2、Setter注入
3、接口注入
(2)请解释下Spring中的IOC?
IOC中最基本的技术就是“反射(Reflection)”编程。BeanFactory接口是Spring IoC 容器的核心接口。我们可以把IOC容器的工作模式看做是工厂模式的升华,可以把IOC容器看作是一个工厂,这个工厂里要生产的对象都在配置文件中给出定义,然后利用编程语言的的反射编程,根据配置文件中给出的类名生成相应的对象。从实现来看,IOC是把以前在工厂方法里写死的对象生成代码,改变为由配置文件来定义,也就是把工厂和对象生成这两者独立分隔开来,目的就是提高灵活性和可维护性。
IOC(DI)两种注入方式
构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。
Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入。
(3)将Spring配置到你的应用中共有几种方法?
将Spring配置到应用开发中有以下三种方式:
基于XML的配置
首先是命名空间的定义,然后就是Bean的定义和命名。
1 <!-- 切点的bean -->
2 <bean class="com.aop.xmltype.CalculatorImplxml" id="calImplxml"></bean>
3 <!-- 切面的bean -->
4 <bean class="com.aop.xmltype.MyAspectxml" id="myaspxml"></bean>
5 <!-- aop xmlType,用xml的形式配置AOP前置通知 -->
6 <aop:config>
7 <!--aop:pointcut 其实放在这儿也可以 -->
8 <!-- <aop:pointcut expression="execution (* com.aop.xmltype.CalculatorImplxml.*(..))"
9 id="pointcut1" /> -->
10
11 <!-- 配置切面和通知 ,aop:aspect标签需要通过ref指定配置好的bean,id随便配置或者不配置,id的值可以随意起 -->
12 <aop:aspect id="myaspxml" ref="myaspxml" order="2">
13 <!-- 配置切点,即 要被记日记的对象, aop:pointcut 放在这儿也可以 ,切点不需要根对应的bean相关联,
14 只要expression指定的方法所在的类被Spring扫描得到就行,即只要所在的类配置了bean就可以 -->
15 <aop:pointcut expression="execution (* com.aop.xmltype.CalculatorImplxml.*(..))"
16 id="pointcut1" />
17 <!-- 切面里的具体的用于记录的方法就是一个通知,需要用通过pointcut-ref来指定具体的切点, -->
18 <aop:before method="logBefore" pointcut-ref="pointcut1" />
19 <aop:after method="logAfter" pointcut-ref="pointcut1" />
20
21 </aop:aspect>
22
23 </aop:config>
基于注解的配置
在<context:annnotation-config />标签配置完成之后,就可以使用注解的方式在spring中向属性、方法和构造方法中自动装配变量。自动装配主要用到@Autowired和@Qualifier。
基于Java的配置
spring对java配置的支持是由@configuration和@Bean注解来实现的。由@Bean所注解的方法将会实例化、配置和初始化一个新对象,这个对象将交给IOC容器来进行管理。被@Configuration注解的类表示这个类主要目的是作为Bean定义的资源。被@Configuration所注解的类可以通过在同一个类的内部调用@Bean方法来设置嵌入bean的依赖关系。
(5)描述Spring Bean的生命周期?
Bean的生命周期是由两组回调函数组成。在一个bean实例化初始时,需要进行一系列的初始化操作以达到可用的状态。同样,当一个bean不在被调用的时候,也需要进行一些操作,然后从bean容器中移除。spring bean factory 负责管理在spring容器中被创建的bean的生命周期。
(6)描述Spring中各种Bean的范围?(作用域)
- singleton:bean在每个Spring IOC容器中只有一个实例
- prototype:一个bean的定义可以有多个实例
- request:每次http请求都会创建一个bean 作用仅在当前请求有效
- session:每次会话都会创建一个bean,作用只在当前会话有效
- global-session:
(7)什么是Spring的嵌入beans?
Spring bean 表示受到Spring管理的对象。具体说来,它是被Spring框架容器初始化、配置和管理的对象。Spring bean是在Spring的配置文件中定义,在Spring容器中初始化,然后注入到应用程序中的。
(8)Spring框架中的单例bean是否是线程安全的?
单例bean存在线程问题,主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写会存在安全问题。常见的解决办法: - 在Bean对象中尽量避免定义可变的成员变量
- 在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中。
(9)请举例说明如何用Spring注入一个Java的集合类?
list类型用于注入一列值,允许有相同的值。
set类型用于注入一组值,不允许有相同的值。
map类型用于注入一组键值对,键和值都可以为任意类型。
props类型用于注入一组键值对,键和值都只能为String类型
(10)请举例说明如何在Spring的Bean中注入一个java.util.Properties?
用”util:”命名空间来从properties文件中创建出一个propertiesbean,然后利用setter方法注入bean的引用。
(11)请解释Spring的Bean的自动生成原理?
简单来说就是springBean的自动装配,有两种自动装配的方法:一个是xml配置方式,另一个是使用@Autowired方式。两种方式都可以构造器注入和setter注入。
(12)请辨析自动生成Bean之间模块的区别?
(13)如何开启基于基于注解的自动写入?
@Resource注解方式进行装配,默认按名称装配,当找不到与名称匹配的bean才会按类型装配
@Autowired自动装配具有兼容类型的单个bean属性。可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。通过@Autowied的使用来代替set方法。(property属性通过调用setter进行赋值)required属性(是否是必须的)
@Qualifier 当同类型的bean不唯一时,使用此注解可以按名称自动装配
(17)请说明构造器注入和setter方法注入之间的区别?
setter方法注入即是创建一个普通的JavaBean类,为需要注入的属性通过对应的setter方法即可
采用setter注入为主,构造注入为辅的注入策略。对于依赖关系无需变化的注入,尽量采用构造注入;而其它的依赖关系的注入,则考虑setter注入。
(18)Spring框架中有哪些不同类型的事件?
Spring的ApplicationContext 提供了支持事件和代码中监听器的功能。
(19)FileSystemResource和ClassPathResource有何区别?
在FileSystemResource 中需要给出spring-config.xml文件在你项目中的相对路径或者绝对路径。在ClassPathResource中spring会在ClassPath中自动搜寻配置文件,所以要把ClassPathResource 文件放在ClassPath下。
如果将spring-config.xml保存在了src文件夹下的话,只需给出配置文件的名称即可,因为src文件夹是默认。
简而言之,ClassPathResource在环境变量中读取配置文件,FileSystemResource在配置文件中读取配置文件。
(20)请列举Spring框架中用了哪些设计模式?
1.工厂模式,在各种BeanFactory以及ApplicationContext创建中都用到了;
2.模版模式,在各种BeanFactory以及ApplicationContext实现中也都用到了例如:RestTemplate, JmsTemplate, JpaTemplate;
3.代理模式,在Aop实现中用到了JDK的动态代理;
4.单例模式,这个比如在创建bean的时候。