spring面试题(1)

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

  • spring目标是简化企业级开发的技术框架
  • 主要模块有:核心容器,数据访问/集成,Web,AOP,工具,消息和测试模块

2、使用Spring框架有什么好处?

下面列举了一些使用Spring框架带来的主要好处

  • Dependency Injection(DI) 方法使得构造器和JavaBean properties文件中的依赖关系一目了然。
  • 与EJB容器相比较,IoC容器更加趋向于轻量级。这样一来IoC容器在有限的内存和CPU资源的情况下进行应用程序的开发和发布就变得十分有利。
  • Spring并没有闭门造车,Spring利用了已有的技术比如ORM框架、logging框架、J2EE、Quartz和JDK Timer,以及其他视图技术。
  • Spring框架是按照模块的形式来组织的。由包和类的编号就可以看出其所属的模块,开发者仅仅需要选用他们需要的模块即可。
  • 要测试一项用Spring开发的应用程序十分简单,因为测试相关的环境代码都已经囊括在框架中了。更加简单的是,利用JavaBean形式的POJO类,可以很方便的利用依赖注入来写入测试数据。
  • Spring的Web框架亦是一个精心设计的Web MVC框架,为开发者们在web框架的选择上提供了一个除了主流框架比如Struts、过度设计的、不流行web框架的以外的有力选项。
  • Spring提供了一个便捷的事务管理接口,适用于小型的本地事物处理(比如在单DB的环境下)和复杂的共同事物处理(比如利用JTA的复杂DB环境)。

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

IOC是一种编程思想,用于指导我们如何设计出一个松耦程序。在spring框架中,有了IOC容器后,把__创建和查找依赖对象的控制权交给容器__,容器进行注入组合对象,所以对象和对象之间是松耦合的,这样也__方便测试,利于功能复用__,更重要的是使得程序的整个体系结构变得非常灵活

DI:Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。,

4、请解释下Spring中的IOC?

IOC是一种编程思想,用于指导我们如何设计出一个松耦程序。在spring框架中,有了IOC容器后,把__创建和查找依赖对象的控制权交给容器__,容器进行注入组合对象,所以对象和对象之间是松耦合的,这样也__方便测试,利于功能复用__,更重要的是使得程序的整个体系结构变得非常灵活

5、BeanFactory和ApplicationContext有什么区别?

BeanFactory

BeanFactory是spring的原始接口,针对原始结构的实现类功能比较单一,BeanFactory接口实现的容器,特点是在每次获取对象时才会创建对象。

ApplicationContext

继承了BeanFactory接口,拥有BeanFactory的全部功能,并且扩展了很多高级特性,每次容器启动时就会创建所有的对象。

创建ApplicationContext的方法:
  1. 丛类路径下加载配置文件:ClassPathXmlApplicationContext (“applicationContext.xml”);
  2. 从硬盘绝对路径下加载配置文件: FileSystemXmlApplicationContext(“d:/xxx/yyy/xxx”);

6、将Spring配置到你的应用中共有几种方法?

将Spring配置到应用开发中有以下三种方式:

  1. 基于XML的配置
  2. 基于注解的配置
  3. 基于Java的配置

7、什么基于XML的配置?

在Spring框架中,依赖和服务需要在专门的配置文件来实现,我常用的XML格式的配置文件。这些配置文件的格式通常用开头,然后一系列的bean定义和专门的应用配置选项组成。 SpringXML配置的主要目的时候是使所有的Spring组件都可以用xml文件的形式来进行配置。这意味着不会出现其他的Spring配置类型(比如声明的方式或基于Java Class的配置方式) Spring的XML配置方式是使用被Spring命名空间的所支持的一系列的XML标签来实现的。Spring有以下主要的命名空间:context、beans、jdbc、tx、aop、mvc和aso。

8、什么基Java的配置?

Spring对Java配置的支持是__由@Configuration注解和@Bean注解来实现__的。由__@Bean注解的方法将会实例化、配置和初始化一个新对象__,这个对象将由Spring的IoC容器来管理。被@Configuration所注解的类则表示这个类的主要目的是作为bean定义的资源。被@Configuration声明的类可以通过在同一个类的内部调用@bean方法来设置嵌入bean的依赖关系。

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

Spring在2.5版本以后开始支持用注解的方式来配置依赖注入。可以用注解的方式来替代XML方式的bean描述,可以将bean描述转移到组件类的内部,只需要在相关类上、方法上或者字段声明上使用注解即可。注解注入将会被容器在XML注入之前被处理,所以后者会覆盖掉前者对于同一个属性的处理结果。 注解装配在Spring中是默认关闭的。所以需要在Spring文件中配置一下才能使用基于注解的装配模式。如果你想要在你的应用程序中使用关于注解的方法的话,请参考如下的配置。

在 标签配置完成以后,就可以用注解的方式在Spring中向属性、方法和构造方法中自动装配变量。 下面是几种比较重要的注解类型:

  1. @Required:该注解应用于设值方法。
  2. @Autowired:该注解应用于有值设值方法、非设值方法、构造方法和变
  3. @Qualifier:该注解和@Autowired注解搭配使用,用于消除特定bean自动装配的歧义。
  4. JSR-250 Annotations:Spring支持基于JSR-250 注解的以下注解,@Resource、@PostConstruct 和 @PreDestroy。

10、描述Spring Bean的生命周期?

Spring Bean的生命周期简单易懂。在一个bean实例被初始化时,需要执行一系列的初始化操作以达到可用的状态。同样的,当一个bean不在被调用时需要进行相关的析构操作,并从bean容器中移除。 Spring bean factory 负责管理在spring容器中被创建的bean的生命周期。Bean的生命周期由两组回调(call back)方法组成。

  1. 初始化之后调用的回调方法。

  2. 销毁之前调用的回调方法。

    • Spring框架提供了以下四种方式来管理bean的生命周期事件:
    • InitializingBean和DisposableBean回调接口
    • 针对特殊行为的其他Aware接口
    • Bean配置文件中的Custom init()方法和destroy()方法
    • @PostConstruct和@PreDestroy注解方式 使用customInit()和 customDestroy()方法管理bean生命周期的代码样例如下

11、描述Spring中各种Bean的范围?

1,singleton Spring ioc 容器中仅有一个 Bean 实例,Bean 以单例的方式存在;(默认)

2,prototype 每次从容器中调用 Bean 时,都返回一个新的实例;

3,request 每次 HTTP 请求都会创建一个新的 Bean;

4,session 同一个 HTTP Session 共享一个 Bean;

5,global session 同一个全局 Session 共享一个 Bean,一般用于 Portlet 应用环境;

6,application 同一个 Application 共享一个 Bean

12、什么是Spring的嵌入beans?

在spring的配置文件中,命名空间, 对于嵌入式的beans标签,想信大家很少使用过,或者接触过,起码,我本人就没用过. 它非常类似于Import标签所提供的功能;

13、Spring框架中的单例bean是否是线程安全的?

线程安全这个问题,要从单例与原型Bean分别进行说明。

原型Bean 对于原型Bean,每次创建一个新对象,也就是线程之间并不存在Bean共享,自然是不会有线程安全的问题。

单例Bean 对于单例Bean,所有线程都共享一个单例实例Bean,因此是存在资源的竞争。

无状态Bean,也就是线程中的操作不会对Bean的成员执行查询以外的操作,那么这个单例Bean是线程安全的。比如Spring mvc 的 Controller、Service、Dao等,这些Bean大多是无状态的,只关注于方法本身。

有状态对象(Stateful Bean) :就是有实例变量的对象,可以保存数据,是非线程安全的

  • 在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的一种方式)。

14、请举例说明如何用Spring注入一个Java的集合类?

<beans>

   <!-- Definition for javaCollection -->
   <bean id="javaCollection" class="com.howtodoinjava.JavaCollection">

      <!-- java.util.List -->
      <property name="customList">
        <list>
           <value>INDIA</value>
           <value>Pakistan</value>
           <value>USA</value>
           <value>UK</value>
        </list>
      </property>

     <!-- java.util.Set -->
     <property name="customSet">
        <set>
           <value>INDIA</value>
           <value>Pakistan</value>
           <value>USA</value>
           <value>UK</value>
        </set>
      </property>

     <!-- java.util.Map -->
     <property name="customMap">
        <map>
           <entry key="1" value="INDIA"/>
           <entry key="2" value="Pakistan"/>
           <entry key="3" value="USA"/>
           <entry key="4" value="UK"/>
        </map>
      </property>

      <!-- java.util.Properties -->
    <property name="customProperies">
        <props>
            <prop key="admin">admin@nospam.com</prop>
            <prop key="support">support@nospam.com</prop>
        </props>
    </property>

   </bean>

</beans>

15、请举例说明如何在Spring的Bean中注入一个java.util.Properties?

<bean id="adminUser" class="com.howtodoinjava.common.Customer">

    <!-- java.util.Properties -->
    <property name="emails">
        <props>
            <prop key="admin">admin@nospam.com</prop>
            <prop key="support">support@nospam.com</prop>
        </props>
    </property>

</bean>

16、请解释Spring的Bean的自动生成原理?

第一步:解析XML

第二步:获取每个Bean的Class

第三步:利用反射对Bean的私有属性赋值

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

在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的自动装配方式。

18、如何开启基于基于注解的自动写入?

@Resource注解方式进行装配,默认按名称装配,当找不到与名称匹配的bean才会按类型装配 @Autowired自动装配具有兼容类型的单个bean属性。可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。通过@Autowied的使用来代替set方法。(property属性通过调用setter进行赋值)

19、请举例说明@Required注解?

@Required注解应用于bean属性的setter方法,它表明影响的bean属性在配置时必须放在XML配置文件中。

当被@Required的set方法,在xml中没有被设置,活抛出 BeanInitializationException 的异常

20、请举例说明@Autowired注解?

使用 @Autowired 注解进行装配,

  • 只能是根据类型进行匹配
  • @Autowired 注解可以用于 Setter 方法、构造函数、字段,甚至普通方法,前提是方法必须有至少一个参数
  • @Autowired 可以用于数组和使用泛型的集合类型。然后 Spring 会将容器中所有类型符合的 Bean 注入进来。@Autowired 标注作用于 Map 类型时,如果 Map 的 key 为 String 类型,则 Spring 会将容器中所有类型符合 Map 的 value 对应的类型的 Bean 增加进来,用 Bean 的 id 或 name 作为 Map 的 key

21、请举例说明@Qualifier注解?

当同一个Class被在bean初始化多次时,我们需要明确的注入我们想要的bean,可以通过一下两个方法

1.@Qualifier(name=”????”) 和@Autowired 配合使用

2.通过@Resource 的方式,因为 @Resource可通过beanID示例化

22、请说明构造器注入和setter方法注入之间的区别?

set设值注入有如下优点
  • 设值注入需要该Bean包含这些属性的setter方法
  • 与传统的JavaBean的写法更相似,程序开发人员更容易理解、接收。通过setter方法设定依赖关系显得更加只管。
  • 对于复杂的依赖关系,如果采用构造注入,会导致构造器国语臃肿,难以阅读。Spring在创建Bean实例时,需要同时实例化器依赖的全部实例,因而导致性能下降。而使用设值注入,则能避免这些问题
  • 尤其是在某些属性可选的情况况下,多参数的构造器显得更加笨重
构造注入有以下优势
  • 构造注入需要该Bean包含带有这些属性的构造器
  • 构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。例如,组件中其他依赖关系的注入,常常要依赖于DataSrouce的注入。采用构造注入,可以在代码中清晰的决定注入顺序。
  • 对于依赖关系无需变化的Bean,构造注入更有用处。因为没有Setter方法,所有的依赖关系全部在构造器内设定。因此,无需担心后续的代码对依赖关系产生破坏。
  • 依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系。对组件的调用者而言,组件内部的依赖关系完全透明,更符合高内聚的原则。

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

Spring的ApplicationContext 提供了__支持事件__和__代码中监听器__的功能。

我们可以创建bean用来监听在ApplicationContext 中发布的事件。ApplicationEvent类和在ApplicationContext接口中处理的事件,如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent 被发布以后,bean会自动被通知。

public class AllApplicationEventListener implements ApplicationListener < ApplicationEvent >
{
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent)
    {
        //process event
    }
}

Spring 提供了以下5中标准的事件:

  1. 上下文更新事件(ContextRefreshedEvent):该事件会在ApplicationContext被初始化或者更新时发布。也可以在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。

  2. 上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。

  3. 上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。

  4. 上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。

  5. 请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。

除了上面介绍的事件以外,还可以通过扩展ApplicationEvent 类来开发自定义的事件。

public class CustomApplicationEvent extends ApplicationEvent
{
    public CustomApplicationEvent ( Object source, final String msg )
    {
        super(source);
        System.out.println("Created a Custom event");
    }
}

为了监听这个事件,还需要创建一个监听器:

public class CustomEventListener implements ApplicationListener < CustomApplicationEvent >
{
    @Override
    public void onApplicationEvent(CustomApplicationEvent applicationEvent) {
        //handle event
    }
}

之后通过applicationContext接口的publishEvent()方法来发布自定义事件。

CustomApplicationEvent customEvent = new CustomApplicationEvent(applicationContext, “Test message”);

applicationContext.publishEvent(customEvent);

24、FileSystemResource和ClassPathResource有何区别?

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

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

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

25、请列举Spring框架中用了哪些设计模式

Spring框架中使用到了大量的设计模式,下面列举了比较有代表性的:

  • 代理模式—在AOP和remoting中被用的比较多。

  • 单例模式—在spring配置文件中定义的bean默认为单例模式。

  • 模板方法—用来解决代码重复的问题。

  • 比如. RestTemplate, JmsTemplate, JpaTemplate。

  • 前端控制器—Srping提供了DispatcherServlet来对请求进行分发。

  • 视图帮助(View Helper )—Spring提供了一系列的JSP标签,高效宏来辅助将分散的代码整合在视图里。

  • 依赖注入—贯穿于BeanFactory / ApplicationContext接口的核心理念。

  • 工厂模式—BeanFactory用来创建对象的实例。