关于Spring的经典高频面试题

以下题目来自书本《Spring5核心原理与30个类手写实战》,这是本好书,有能力的可以买书看。

 

1.什么是控制反转(IOC),什么是依赖注入(DI)

IOC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。

IoC(控制反转)

  首先想说说IoC(Inversion of Control,控制反转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。这是什么意思呢,举个简单的例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,然后嘿嘿……这个过程是复杂深奥的,我们必须自己设计和面对每个环节。传统的程序开发也是如此,在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比如Connection等),对象始终会和其他的接口或类藕合起来。
  那么IoC是如何做的呢?有点像通过婚介找女朋友,在我和女朋友之间引入了一个第三者:婚姻介绍所。婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友,比如长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,然后婚介就会按照我们的要求,提供一个mm,我们只需要去和她谈恋爱、结婚就行了。简单明了,如果婚介给我们的人选不符合要求,我们就会抛出异常。整个过程不再由我自己控制,而是有婚介这样一个类似容器的机构来控制。Spring所倡导的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。

DI(依赖注入)

  IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

 

2.依赖注入有那些方式?

构造器注入。Setter方法注入。接口注入

 

3.BeanFactory和ApplicationContext有什么区别

Bean工厂包含Bean的定义,以便接收客户端请求时将对应的Bean实例化,还能在实例化对象时生成协作类之间的关系。此举将Bean从Bean客户端的配置中解放出来。Bean工厂还包含Bean生命周期的控制,调用客户端的初始化方法和销毁方法。

从表面看,ApplicationContext如同Bean工厂一样具有Bean定义,Bean关联关系的设置以及根据请求分发Bean的功能,但ApplicationContext还在此此处上提供其他功能。1:提供了支持国际化的文本消息。2:统一的资源读取方式。3:已在监听器中注册的Bean的事件。

以下是三种较常见的ApplicationContext实现方式。1从ClassPath的XML配置文件中读取上下文。2由文件系统的XML配置读取。3从Web应用的XML读取上下文。

(1)ApplicationContext context = new ClassPathXmlApplicationContext(“application.xml”)

(2)ApplicationContext context = new ClassPathXmlApplicationContext(“application.xml”)

 

4.Spring提供几种配置方式来设置元数据

1基于XML,2基于注解,3基于Java配置

 

5.Spring Bean的生命周期

Spring Bean Factory 负责管理在Spring容器中被创建的Bean的生命周期。Bean的生命周期由两组回调方法组成。

1初始化后调用的回调方法

2销毁前调用的回调方法

Springtigong一下4种方法管理Bean的生命周期事件

1InitializingBean和DisposableBean回调接口

2针对特殊行为的其他Aware接口

3Bean配置文件中的customInit()方法和customDestory()方法

4@PostConstruct和@PreDestory注解方法

//使用customInit和customDestory管理Bean生命周期的代码样例
<beans>
    <bean id="demoBean" class="com.gupaodu.task.DemoBean"
        init-Method="customInit" destory-Method="customDestory>
    </bean>
</beans>

 

6.SpringBean作用域的区别是什么

(1)singleton:这种Bean作用域是默认的,这种作用域确保不管接收多少个请求,每个容器只有一个Bean实例,单例模式由Bean工厂自身来维护

(2)prototype:为每一个Bean请求提供一个实例。

(3)request:在请求Bean作用域内为每一个来自客户端的网络请求创建实例,在请求完成以后,Bean会失效并被垃圾回收器回收

(4)Session:与request相反,确保每一个Session中有一个Bean实例,在Session过期后,Bean会随之失效

(5)global-session:与Portlet应用相关。当应用部署Portlet容器时,想让所有的Portlet共用全局存储变量,那么这个全局存储变量需要存储在global-session。全局作用域yuServlet的Session作用域效果相同。

 

7.什么是Spriing Inner Bean

在Spring中,无论何时,当Bean仅调用一个属性时,一个明智的做法是将这个Bean声明为内部Bean。内部Bean可以用setter注入“属性”和构造方法注入“构造参数”的房是来实现。

//比如在应用程序中一个Customer类引用了一个Person类,我们要创建一个Person类的实例,然后再Customer内部使用。

public class Customer{
    private Person person;
}
public class Person{
    private String name;
    private String address;
    private int age;
}
//内部Bean的声明方式如下

<bean id="CustomerBean" class="co.common.Customer">
    <property name="person">
        <bean class="common.Person">
            <property name="name" value="lokesh" />
            <property name="address" value="india" />
            <property name="age" value="43" />
        </bean>
    </property>
</bean>

 

8.Spring中的单例Bean是线程安全的吗

如果你的Bean有多种状态,比如ViewModel对象,就需要自行保证线程安全。

 

9.如何在Spring诸如一个JAVA集合

<list>可重复

<set>无重复 

<map>键值对

<props>只能是字符串类型的键值对

 

10.请解释 Spring Bean 的自动装配? 

  在 Spring 框架中,在配置文件中设定 bean 的依赖关系是一个很好的机制,Spring 容器还可以自动装配合作关系 bean 之间的关联关系。这意味着 Spring 可以通过向 Bean Factory 中注入的方式自动搞定 bean 之间的依赖关系。自动装配可以设置在每个 bean 上,也可以设定在特定的 bean 上。 

  下面的 XML 配置文件表明了如何根据名称将一个 bean 设置为自动装配: 

<bean id="employeeDAO class="com.howtodoinjava.EmployeeDAOImpl" autowire="byName" />

  除了 bean 配置文件中提供的自动装配模式,还可以使用

  @Autowired 注解来自动装配指定的 bean。

  在使用@Autowired 注解之前需要在按照如下的配置方式在 Spring配置文件进行配置才可以使用 

<context:annotation-config />

  也可以通过在配置文件中配置AutowiredAnnotationBeanPostProcessor 达到相同的效果。 

 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

  配置好以后就可以使用@Autowired 来标注了

    @Autowired
    public EmployeeDAOImpl ( EmployeeManager manager ) {
        this.manager = manager;
    }

 

11.自动装配有哪些局限性

重写:你仍然需要使用<property>设置指明依赖,这意味总要重写自动装配

原生数据类型:你不能自动装配简单的属性,如原生类型,字符串和类

模糊特性:没用自定义装配精确

 

12.请解释各种自动装配模式的区别

在 Spring 框架中共有 5 种自动装配,让我们逐一分析。 

  1. no:这是 Spring 框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在 bean 定义中用标签明确的设置依赖关系。

  2. byName:该选项可以根据 bean 名称设置依赖关系。当向一个 bean 中自动装配一个属性时,容器将根据 bean 的名称自动在在配置文件中查询一个匹配的 bean。如果找到的话,就装配这个属性,如果没找到的话就报错。

  3. byType:该选项可以根据 bean 类型设置依赖关系。当向一个bean 中自动装配一个属性时,容器将根据 bean 的类型自动在在配置文件中查询一个匹配的 bean。如果找到的话,就装配这个属性,如果没找到的话就报错。

  4. constructor:造器的自动装配和 byType 模式类似,但是仅仅适用于与有构造器相同参数的 bean,如果在容器中没有找到与构造器参数类型一致的 bean,那么将会抛出异常。

  5. autodetect:该模式自动探测使用构造器自动装配或者byType 自动装配。首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在 bean 内部没有找到相应的构造器或者是无参构造器,容器就会自动选择byTpe 的自动装配方式。 

 

13.Spring中可以注入null或空字符串吗

可以

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值