Spring面试题

什么是 Spring 框架?Spring 框架有哪些主要模块?

Spring是一个轻量级的JavaEE解决方案,整合众多优秀的设计模式。

spring框架主要包括7个模块:

  • Spring AOP 面向切面编程
  • Spring ORM Hibernate|mybatis|JDO
  • Spring Core 提供bean工厂 IOC
  • Spring Dao JDBC支持
  • Spring Context 提供了关于UI支持,邮件支持等
  • Spring Web 提供了web的一些工具类的支持
  • Spring MVC 提供了web mvc , webviews , jsp ,pdf ,export

使用 Spring 框架能带来哪些好处?

  1. 轻量:Spring 是轻量的,基本的版本大约 2MB
  2. 控制反转:Spring 通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们
  3. 面向切面的编程(AOP):Spring 支持面向切面的编程,并且把应用业务逻辑和系统服务分开
  4. 容器:Spring 包含并管理应用中对象的生命周期和配置
  5. MVC 框架:Spring 的 WEB 框架是个精心设计的框架,是 Web 框架的一个很好的替代品
  6. 事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)
  7. 异 常 处 理 : Spring 提 供 方 便 的 API 把 具 体 技 术 相 关 的 异 常 ( 比 如 由 JDBC ,Hibernate or JDO 抛出的)转化为一致的 unchecked 异常

 什么是控制反转(IOC)?什么是依赖注入?

将创建对象的权利由手动创建转换为Spring自动创建。将对象之间的依赖关系通过配置的方式注入到另一个对象中的过程。

请解释下 Spring 框架中的 IoC?

IOC 意为控制反转,普通javaEE创建对象是通过在程序中通过new创建,但是在Spring中,只需将设计好的类通过配置文件或注解的方式设定好,即可由Spring自动创建,对象的控制权由程序转移到了Spring,Spring通过工厂+反射生成对象,将对象放置在IOC容器中。

BeanFactory 和 ApplicationContext 有什么区别?

BeanFactory是Spring的*接口,只提供了最基础的容器功能。通过BeanFactory装载Bean是延时创建。

ApplicationContext是BeanFactory的高级实现,其中增加了许多资源加载,国际化,AOP,消息发送响应机制。通过ApplicationContext装载Bean是在Spring启动时立即创建。

Spring 有几种配置方式?

三种方式:xml,注解,java方式(配置类 @Bean)

如何用基于 XML 配置的方式配置 Spring?

<?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="userService" class="sun.service.ServiceImpl.UserServiceImpl"></bean>
</beans>

如何用基于 Java 配置的方式配置 Spring?

@Configuration
public class AppConfig{
    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}

怎样用注解的方式配置 Spring?

1、在Spring配置文件中开启注解配置。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:annotation-config/>
</beans>

2、通过@Autowired @Component 等注解进行Bean加载和注入

请解释 Spring Bean 的生命周期?

  • 首先是实例化、属性赋值、初始化、销毁这 4 个大阶段;
  • 再是初始化的具体操作,有 Aware 接口的依赖注入、BeanPostProcessor 在初始化前后的处理以及 InitializingBean 和 init-method 的初始化操作;
  • 销毁的具体操作,有注册相关销毁回调接口,最后通过DisposableBean 和 destory-method 进行销毁。

Spring面试题

 Spring Bean 的作用域之间有什么区别?

Spring的 bean有5种作用域分别是:singleton、prototype、request、session和globalSession

singleton
全局只有一个实例
prototype
每次调用产生一个新的实例
在web使用的时候还有三个作用域,但是必须在web.xml中注册一个RequestContextListener , 目的是为了设置每次请求开始和结束都可以使spring得到相应的事件。
request
每次请求产生一个bean
session
每个用户session可以产生一个新的bean,不同用户之间的bean互相不影响
globalSession
作用和session类似,只是使用portlet的时候使用。

什么是 Spring inner beans?

在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 id="CustomerBean" class="com.leon.common.Customer">
    <property name="person">
        <bean class="com.leon.common.Person">
            <property name="name" value="lokesh" />
            <property name="address" value="India" />
            <property name="age" value="34" />
        </bean>
    </property>
</bean>

Spring 框架中的单例 Beans 是线程安全的么?

prototype:每次请求都会创建新的Bean,线程之间不存在Bean的共享,因此是线程安全的。

singleton:  由于全局只有一个Bean,因此可能会出现线程安全问题。但是由于单例Bean,大都是无状态的Bean,也就是不会对Bean成员执行查询以外的操作,因此不会出现线程安全问题。

请举例说明如何在 Spring 中注入一个 Java Collection?

<?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="userService3" class="sun.service.ServiceImpl.UserServiceImpl3">
        <property name="strings">
            <array>
                <value>kelvin</value>
                <value>jack</value>
                <value>tony</value>
            </array>
        </property>

        <property name="set">
            <set>
                <value>kelvin</value>
                <value>jack</value>
                <value>tony</value>
            </set>
        </property>

        <property name="list">
            <list>
                <value>kelvin</value>
                <value>jack</value>
                <value>tony</value>
            </list>
        </property>

        <property name="map">
            <map>
                <entry key="kelvin" value="23"></entry>
                <entry key="jack" value="21"></entry>
                <entry key="tony">
                    <value>46</value>
                </entry>
            </map>
        </property>
   
    </bean>
</beans>

如何向 Spring Bean 中注入一个 Java.util.Properties?

<?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="userService3" class="sun.service.ServiceImpl.UserServiceImpl3">
    
        <property name="prop">
            <props>
                <prop key="kelvin">23</prop>
                <prop key="jack">45</prop>
                <prop key="tony">32</prop>
            </props>
        </property>
</bean> </beans>

请解释 Spring Bean 的自动装配?

是什么?

spring中提供了向Bean中自动注入依赖的功能,这个过程就是自动装配,当向bean中注入的内容非常多的时候,自动注入依赖的功能将极大的节省注入程序的时间。

 

有哪些类型?

  基于xml:在<bean>标签内通过autowire=byType byName constructor 决定注入类型判断方式

<bean id="userDao“ class="com.spring.springioc.dao.impl.UserDaoImpl”/>
<!--byType根据类型自动装配userDao-->
<bean id="userService" autowire="byType" class="com.spring.springioc.service.impl.UserServiceImpl"/>
<bean id="userDao" class="com.spring.springioc.dao.impl.UserDaoImpl"/>
<!--这个bean是userDao类型的,但不是要注入的类型-->
<bean id="userDao2" autowire-candidate="false" class="com.spring.springioc.dao.impl.userDaoImpl"/>
<bean id="userService" autowire="byType" class="com.spring.springioc.service.impl.userSericeImpl"/>

  基于注解:@Autowired @Qualifier  @Resource @Value

请解释自动装配模式的区别?

  • no: 这是Spring框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在bean定义中用标签明确的设置依赖关系。
  • byName: 该选项可以根据bean名称设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的名称自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。
  • byType: 该选项可以根据bean类型设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的类型自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。
  • constructor: 造器的自动装配和byType模式类似,但是仅仅适用于与有构造器相同参数的bean,如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。
  • autodetect: 该模式自动探测使用构造器自动装配或者byType自动装配。首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在bean内部没有找到相应的构造器或者是无参构造器,容器就会自动选择byTpe的自动装配方式。

如何开启基于注解的自动装配?

  • 引入配置文件中的<bean>下引入 <context:annotation-config>
<beans>
    <context:annotation-config />
</beans>
  • 在bean配置文件中直接引入AutowiredAnnotationBeanPostProcessor
<beans>
    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
</beans>

请举例解释@Required 注解?请举例解释@Autowired 注解?请举例说明@Qualifier 注解?

@Required

检查属性是否被正确设置。

RequiredAnnotationBeanPostProcessor 是 Spring 中的后置处理用来验证被 @Required 注解的 bean 属性是否被正确的设置了。在使用 RequiredAnnotationBeanPostProcesso 来验证 bean 属性之前,首先要在 IoC 容器中对 其进行注册:

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

但是如果没有属性被用 @Required 注解过的话,后置处理器会抛出一个 BeanInitializationException 异常。

@Autowired

@Autowired 注解对自动装配何时何处被实现提供了更多细粒度的控制。@Autowired 注解可 以像@Required 注解、构造器一样被用于在 bean 的设值方法上自动装配 bean 的属性,一个参数或者带有任意名称或带有多个参数的方法。
比如,可以在设值方法上使用@Autowired 注解来替代配置文件中的 元 素。当 Spring 容器在 setter 方法上找到@Autowired 注解时,会尝试用 byType 自动装配。
当然我们也可以在构造方法上使用@Autowired 注解。带有@Autowired 注解的构造方法意味着 在创建一个 bean 时将会被自动装配,即便在配置文件中使用 元素。

@Qualifier 

@Qualifier 注解意味着可以在被标注 bean 的字段上可以自动装配。通常和@Autowired配合使用

构造方法注入和设值注入有什么区别?

设值注入的优势:

  1. 设值注入写法直观便于理解,使各种关系清晰明了。
  2. 设值注入可以避免因复杂的依赖实例化时所造成的性能问题。
  3. 设值注入的灵活性较强。

构造方法注入的优势:

  1. 构造方法注入可以决定依赖关系的注入顺序,有限依赖的优先注入。
  2. 对于依赖关系无需变化的Bean,构造方法注入使所有的依赖关系全部在构造器内设定,可避免后续代码对依赖关系的破坏。
  3. 构造方法注入中只有组建的创建者才能改变组建的依赖关系,更符合高内聚原则。

建议:

采用设值注入为主,构造注入为辅的注入策略。依赖关系无需变化时,尽量采用构造注入,而其它的依赖关系的注入,则考虑设值注入。

 

构造器参数实现强制依赖,setter 方法实现可选依赖。

Spring 框架中有哪些不同类型的事件?

  1. 上下文更新事件(ContextRefreshedEvent):该事件会在ApplicationContext被初始化或者更新时发布。也可以在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。
  2. 上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。
  3. 上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
  4. 上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
  5. 请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。

FileSystemResource 和 ClassPathResource 有何区别?

在FileSystemResource 中需要给出spring-config.xml文件在你项目中的相对路径或者绝对路径。在ClassPathResource中spring会在ClassPath中自动搜寻配置文件,所以要把ClassPathResource 文件放在ClassPath下。

如果将spring-config.xml保存在了src文件夹下的话,只需给出配置文件的名称即可,因为src文件夹是默认。

简而言之,ClassPathResource在环境变量中读取配置文件,FileSystemResource在配置文件中读取配置文件。

Spring 框架中都用到了哪些设计模式?

  1. 代理模式—在AOP和remoting中被用的比较多。
  2. 单例模式—在spring配置文件中定义的bean默认为单例模式。
  3. 模板方法—用来解决代码重复的问题。
  4. 前端控制器—Srping提供了DispatcherServlet来对请求进行分发。
  5. 视图帮助(View Helper )—Spring提供了一系列的JSP标签,高效宏来辅助将分散的代码整合在视图里。
  6. 依赖注入—贯穿于BeanFactory / ApplicationContext接口的核心理念。
  7. 工厂模式—BeanFactory用来创建对象的实例。

 

 

上一篇:Spring三级缓存解决循环依赖问题详解


下一篇:【Spring源码解读】SpringAOP源码