Spring面试问题

我试图收集这些Spring面试问题,您可能会在下次技术面试中遇到这些问题。对于其他弹簧模块,我将分别分享面试问题和答案。如果您能够提出更多类似的春季面试问题,我将非常感谢您在之前的采访中所面临的问题,并且您认为这些问题是针对有经验的人提出的Spring面试问题。我将在这个列表中添加它们。这对同学也很有帮助。

Spring面试问题

1.什么是Spring Framework?它的主要模块是什么?
2.使用Spring Framework有什么好处?
3.什么是控制反转(IoC)和依赖注入?
4.在Spring Framework中解释IoC?
5. BeanFactory和ApplicationContext之间的区别?
6.在多少方面,您可以将Spring配置到我们的应用程序中?
7.什么是基于Spring XML的配置?
8.什么是基于Spring Java的配置?
9.什么是基于Spring注释的配置?
10.解释Spring Bean的生命周期?
11.什么是不同的Spring Bean范围?
12.春天的内豆是什么?
13.在Spring Framework中,Singleton bean是否安全?
14.如何在Spring中注入Java Collection?举个例子?
15.如何将java.util.Properties注入Spring Bean?
16.解释Spring Bean Autowiring?
17.解释bean自动装配的不同模式?
18.如何打开基于注释的自动装配?
19.用例子解释@Required注释?
20.用示例解释@Autowired注释?
21.用例子解释@Qualifier注释?
22.构造函数注入和setter注入之间的区别?
23.春季框架中有哪些不同类型的事件?
24. FileSystemResource和ClassPathResource之间的区别?
25.列举一些Spring Framework中使用的设计模式?

1.什么是Spring Framework?它的主要模块是什么?

Spring框架是一个Java平台,它为开发Java应用程序的全面的基础架构支持。Spring处理基础架构部分,因此您可以专注于您的应用程序部分。在内部,Spring框架将形式化的设计模式编码为一流的对象,您可以将它们集成到您自己的应用程序中,而不必过多担心它们在后端的工作方式。

目前,Spring框架由组成大约20个模块的功能组成。这些模块分为核心容器,数据访问/集成,Web,AOP(面向方面编程),仪器消息传递和测试,如下图所示。

Spring面试问题

2.使用Spring Framework有什么好处?

以下列出了使用Spring Framework的一些巨大好处 -

  • 使用依赖注入(DI)方法,依赖关系在构造函数或JavaBean属性中是显式且明显的。
  • 例如,IoC容器往往是轻量级的,尤其是与EJB容器相比时。这有利于在具有有限内存和CPU资源的计算机上开发和部署应用程序。
  • Spring并没有重新发明*,它真正利用了一些现有技术,如几个ORM框架,日志框架,JEE,Quartz和JDK计时器,以及其他视图技术。
  • Spring采用模块化方式组织。即使包和类的数量很大,你也只需要担心你需要的而忽略其余的。
  • 测试用Spring编写的应用程序很简单,因为依赖于环境的代码被移动到这个框架中。此外,通过使用JavaBean样式的POJO,使用依赖注入来注入测试数据变得更加容易。
  • Spring的Web框架是一个设计良好的Web MVC框架,它提供了一个很好的替代Web框架,如Struts或其他过度设计或不太流行的Web框架。
  • Spring提供了一致的事务管理接口,可以缩小到本地事务(例如,使用单个数据库)并扩展到全局事务(例如,使用JTA)。

3.什么是控制反转(IoC)和依赖注入?

在软件工程中,控制反转(IoC)是一种编程技术,其中对象耦合在运行时由汇编程序对象绑定,并且在编译时通常不知道使用静态分析。在传统编程中,业务逻辑的流程由静态分配给彼此的对象确定。通过控制反转,流程取决于由汇编程序实例化的对象图,并且通过抽象定义的对象交互使其成为可能。绑定过程通过“依赖注入”实现。

控制反转是一种设计范例,其目标是为应用程序的目标组件提供更多控制,即实际执行工作的组件。

依赖注入是一种模式,用于创建其他对象依赖的对象实例,而无需在编译时知道将使用哪个类来提供该功能。控制反转依赖于依赖注入,因为需要一种机制来**提供特定功能的组件。否则,如果框架不再受控制,框架将如何知道要创建哪些组件?

在Java中,依赖注入可能通过3种方式发生:

  1. 一个构造函数注入
  2. 一个二传手注射
  3. 一个接口注入

4.在Spring Framework中解释IoC?

org.springframework.beansorg.springframework.context软件包提供了对Spring框架的IoC容器的基础。该BeanFactory接口提供了一种能够管理任何性质的对象的高级配置机制。该ApplicationContext接口构建于BeanFactory(它是一个子接口)之上,并添加了其他功能,例如更容易与Spring的AOP功能集成,消息资源处理(用于国际化),事件传播和特定于应用程序层的上下文,如WebApplicationContext用于Web应用程序。

org.springframework.beans.factory.BeanFactory是Spring IoC容器的实际表示,负责包含和管理上述bean。该Bean工厂接口是Spring IoC容器的核心接口。

5. BeanFactory和ApplicationContext之间的区别?

BeanFactory就像一个包含bean集合的工厂类。在BeanFactory 拥有自身内部多个bean的bean定义,然后实例化豆每当客户端请求。BeanFactory能够在实例化协作对象时创建协作对象。这消除了bean本身和bean客户端的配置负担。BeanFactory还参与bean的生命周期,调用自定义初始化和销毁​​方法。

表面上,应用程序上下文与bean工厂相同。加载bean定义,连接bean,并根据请求分配bean。但它还提供:

  1. 解决短信的手段,包括对国际化的支持。
  2. 加载文件资源的通用方法。
  3. 注册为侦听器的Bean事件。

三种常用的实现ApplicationContext是:

  1. ClassPathXmlApplicationContext:它从位于类路径中的XML文件加载上下文定义,将上下文定义视为类路径资源。应用程序上下文通过使用代码从应用程序的类路径加载。

    ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”);

  2. FileSystemXmlApplicationContext:它从文件系统中的XML文件加载上下文定义。使用代码从文件系统加载应用程序上下文。

    ApplicationContext context = new FileSystemXmlApplicationContext(“bean.xml”);

  3. XmlWebApplicationContext :它从Web应用程序中包含的XML文件加载上下文定义。

6.在多少方面,您可以将Spring配置到我们的应用程序中?

您可以通过3种方式为应用程序配置spring:

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

7.什么是基于Spring XML的配置?

在Spring框架中,bean所需的依赖项和服务在配置文件中指定,配置文件通常采用XML格式。这些配置文件通常以<beans>tag 开头,包含许多bean定义和特定于应用程序的配置选项。

Spring XML Configuration的主要目标是使用xml文件配置所有Spring组件。
这意味着不会出现任何其他类型的Spring配置(如注释或通过Java类配置)。

一个Spring XML配置使用Spring命名空间,使可用套配置中使用XML标记的; 主要的Spring命名空间是:context,beans,jdbc,tx,aop,mvc,aso

<beans>

 

    <!-- JSON Support -->

    <bean name="viewResolver"class="org.springframework.web.servlet.view.BeanNameViewResolver"/>

    <bean name="jsonTemplate"class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>

     

    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/>

 

</beans>

最简单的web.xml文件使您的应用程序加载配置文件并为您配置运行时组件位于仅配置DispatcherServlet的位置

<web-app>

  <display-name>Archetype Created Web Application</display-name>

   

  <servlet>

        <servlet-name>spring</servlet-name>

            <servlet-class>

                org.springframework.web.servlet.DispatcherServlet

            </servlet-class>

        <load-on-startup>1</load-on-startup>

    </servlet>

 

    <servlet-mapping>

        <servlet-name>spring</servlet-name>

        <url-pattern>/</url-pattern>

    </servlet-mapping>

     

</web-app>

8.什么是基于Spring Java的配置?

Spring的新Java配置支持中的中心工件是带@Configuration注释的类和带@Bean注释的方法。

@Bean注释被用于指示一个方法实例,配置和初始化为通过Spring IoC容器进行管理的新对象。@Bean注释与<bean/>元素扮演相同的角色。

对类进行注释@Configuration表明其主要目的是作为bean定义的来源。此外,@Configuration类允许通过简单地调用@Bean同一类中的其他方法来定义bean间依赖关系。最简单的@Configuration类如下:

@Configuration

public class AppConfig

{

    @Bean

    public MyService myService() {

        return new MyServiceImpl();

    }

}

上面java配置的等效XML配置是:

<beans>

    <bean id="myService" class="com.howtodoinjava.services.MyServiceImpl"/>

</beans>

要实例化此类配置,您将需要AnnotationConfigApplicationContext类的帮助。

public static void main(String[] args) {

    ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

    MyService myService = ctx.getBean(MyService.class);

    myService.doStuff();

}

要启用组件扫描,只需@Configuration按如下方式注释您的类:

@Configuration

@ComponentScan(basePackages = "com.howtodoinjava")

public class AppConfig  {

    ...

}

在上面的示例中,将扫描com.acme包,查找任何带@Component注释的类,这些类将在容器中注册为Spring bean定义。

如果您在Web应用程序中使用上述配置,那么您将使用AnnotationConfigWebApplicationContext类。配置Spring ContextLoaderListenerservlet侦听器,Spring MVC DispatcherServlet等时可以使用此实现。

<web-app>

    <!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext instead of the default XmlWebApplicationContext -->

    <context-param>

        <param-name>contextClass</param-name>

        <param-value>

            org.springframework.web.context.support.AnnotationConfigWebApplicationContext

        </param-value>

    </context-param>

 

    <!-- Configuration locations must consist of one or more comma- or space-delimited fully-qualified @Configuration classes. Fully-qualified packages may also be specified for component-scanning -->

    <context-param>

        <param-name>contextConfigLocation</param-name>

        <param-value>com.howtodoinjava.AppConfig</param-value>

    </context-param>

 

    <!-- Bootstrap the root application context as usual using ContextLoaderListener -->

    <listener>

        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

    </listener>

 

    <!-- Declare a Spring MVC DispatcherServlet as usual -->

    <servlet>

        <servlet-name>dispatcher</servlet-name>

        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext instead of the default XmlWebApplicationContext -->

        <init-param>

            <param-name>contextClass</param-name>

            <param-value>

                org.springframework.web.context.support.AnnotationConfigWebApplicationContext

            </param-value>

        </init-param>

        <!-- Again, config locations must consist of one or more comma- or space-delimited and fully-qualified @Configuration classes -->

        <init-param>

            <param-name>contextConfigLocation</param-name>

            <param-value>com.howtodoinjava.web.MvcConfig</param-value>

        </init-param>

    </servlet>

 

    <!-- map all requests for /app/* to the dispatcher servlet -->

    <servlet-mapping>

        <servlet-name>dispatcher</servlet-name>

        <url-pattern>/app/*</url-pattern>

    </servlet-mapping>

</web-app>

9.什么是基于Spring注释的配置?

从Spring 2.5开始,可以使用注释配置依赖注入。因此,不是使用XML来描述bean连接,而是可以通过在相关的类,方法或字段声明上使用注释将bean配置移动到组件类本身。注释注入在XML注入之前执行,因此后一种配置将覆盖通过两种方法连接的属性的前者。

默认情况下,Spring容器中未打开注释接线。因此,在我们使用基于注释的布线之前,我们需要在Spring配置文件中启用它。因此,如果要在Spring应用程序中使用任何注释,请考虑使用以下配置文件。

<beans>

 

   <context:annotation-config/>

   <!-- bean definitions go here -->

 

</beans>

一旦<context:annotation-config/>配置,你就可以开始你的注释代码,表明春季应自动线的值到属性,方法和构造函数。

您将在此类配置中使用的几个重要注释是:

  1. @Required:@Required注释适用于bean属性setter方法。
  2. @Autowired:@Autowired注释可以应用于bean属性setter方法,非setter方法,构造函数和属性。
  3. @Qualifier:@Qualifier注释和@Autowired可用于通过指定将连接哪个确切的bean来消除混淆。
  4. JSR-250注释:Spring支持基于JSR-250的注释,包括@ Resource,@ PostConstruct和@PreDestroy注释。

10.解释Spring Bean的生命周期?

Spring bean生命周期很容易理解。当bean被实例化时,可能需要执行一些初始化以使其进入可用状态。类似地,当不再需要bean并从容器中移除bean时,可能需要进行一些清理。

Spring bean工厂负责管理通过弹簧容器创建的bean的生命周期。bean的生命周期包括回调方法,可以分为两类

  1. 发布初始化回调方法
  2. 预破坏回叫方法

Spring框架提供了以下4种控制 bean 生命周期事件的方法:

  • InitializingBean和DisposableBean回调接口
  • 用于特定行为的其他Aware接口
  • bean配置文件中的自定义init()和destroy()方法
  • @PostConstruct和@PreDestroy注释

例如,customInit()customDestroy()方法是示例的生命周期方法。

<beans>

    <bean id="demoBean" class="com.howtodoinjava.task.DemoBean" init-method="customInit"destroy-method="customDestroy"></bean>

</beans>

阅读更多:Spring Bean生命周期

11.什么是不同的Spring Bean范围?

spring容器中的bean可以在五个bean范围内创建。所有范围名称都是不言自明的,但让它们清楚,以便毫无疑问。

  1. singleton:这个bean作用域是默认的,它强制容器每个弹簧容器只有一个实例,而不管你请求它的实例多少时间。这个单例行为由bean工厂本身维护。
  2. prototype:这个bean作用域只是反转单例作用域的行为,并且每次请求bean时都会生成一个新实例。
  3. request:使用此bean作用域,将为客户端发出的每个Web请求创建一个新的bean实例。请求完成后,bean将超出范围并收集垃圾。
  4. session:就像请求范围一样,这确保了每个用户会话的一个bean实例。一旦用户结束其会话,bean就超出了范围。
  5. global-session:global-session是连接到Portlet应用程序的东西。当您的应用程序在Portlet容器中工作时,它由一些portlet构建。每个portlet都有自己的会话,但是如果你想为应用程序中的所有portlet存储全局变量,那么你应该将它们存储在global-session中。此范围与基于Servlet的应用程序中的会话范围没有任何特殊效果。

阅读更多:Spring Bean Scopes

12.春天的内豆是什么?

在Spring框架中,只要bean只用于一个特定的属性,就建议将它声明为内部bean。内部bean在setter注入' property '和构造函数注入' constructor-arg '中都受支持。

例如,假设我们有一个Customer类引用了Person类。在我们的应用程序中,我们将只创建一个Person类实例,并在其中使用它Customer

public class Customer

{

    private Person person;

     

    //Setters and Getters

}

public class Person

{

    private String name;

    private String address;

    private int age;

     

    //Setters and Getters

}

现在内部bean声明将如下所示:

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

    <property name="person">

        <!-- This is inner bean -->

        <bean class="com.howtodoinjava.common.Person">

            <property name="name" value="adminis"></property>

            <property name="address" value="India"></property>

            <property name="age" value="34"></property>

        </bean>

    </property>

</bean>

13.在Spring Framework中,Singleton bean是否安全?

关于单例 bean 的多线程行为,Spring框架没有做任何事情。开发人员有责任处理单例bean的并发问题和线程安全问题。

实际上,大多数spring bean没有可变状态(例如Service和DAO clases),因此非常简单的线程安全。但是如果你的bean具有可变状态(例如View Model Objects),那么你需要确保线程安全。解决此问题最简单明了的方法是将可变bean的bean范围从“ singleton ”更改为“ prototype ”。

14.如何在Spring中注入Java Collection?举个例子?

Spring提供了四种类型的集合配置元素,如下所示:

<list>:这有助于布线,即注入值列表,允许重复。
<set>:这有助于连接一组值但没有任何重复。
<map>:这可以用于注入一组名称 - 值对,其中name和value可以是任何类型。
<props>:这可以用于注入一组名称 - 值对,其中名称和值都是字符串。

让我们看看每种类型的例子。

<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">[email protected]</prop>

            <prop key="support">[email protected]</prop>

        </props>

    </property>

 

   </bean>

 

</beans>

15.如何将java.util.Properties注入Spring Bean?

第一种方法是使用<props>标签,如下所示。

<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>

您也可以使用“ util: ”命名空间从属性文件创建属性bean,并使用bean引用进行setter注入。

<util:properties id="emails" location="classpath:com/foo/emails.properties" />

16.解释Spring Bean Autowiring?

在spring框架中,在配置文件中设置bean依赖关系是一个很好的做法,但spring容器也能够自动连接协作bean之间的关系。这意味着可以通过检查BeanFactory的内容自动让Spring解析bean的协作者(其他bean)。每个bean都指定了自动装配,因此可以为某些bean启用自动装配,而其他bean不会自动装配。

以下摘自XML配置文件显示了按名称自动装配的bean。

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

除了bean配置文件中提供的自动装配模式之外,还可以使用@Autowired注释在bean类中指定自动装配。要@Autowired在bean类中使用注释,必须首先使用以下配置在spring应用程序中启用注释。

<context:annotation-config />

AutowiredAnnotationBeanPostProcessor在配置文件中使用bean定义可以实现相同。

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

现在,当启用了注释配置时,您可以*地使用@Autowired您喜欢的方式自动装配bean依赖项。

@Autowired

public EmployeeDAOImpl ( EmployeeManager manager ) {

    this.manager = manager;

}

17.解释bean自动装配的不同模式?

弹簧框架中有五种自动接线模式。让我们逐一讨论它们。

  1. no:此选项是spring框架的默认选项,它表示自动装配为OFF。您必须使用bean定义中的标记显式设置依赖项。
  2. byName:此选项启用基于bean名称的依赖项注入。在bean中自动装配属性时,属性名称用于在配置文件中搜索匹配的bean定义。如果找到这样的豆,则将其注入财产。如果没有找到这样的bean,则会引发错误。
  3. byType:此选项启用基于bean类型的依赖项注入。在bean中自动装配属性时,属性的类类型用于在配置文件中搜索匹配的bean定义。如果找到这样的豆,则将其注入财产。如果没有找到这样的bean,则会引发错误。
  4. 构造函数构造函数的自动装配类似于byType,但适用于构造函数参数。在启用autowire的bean中,它将查找构造函数参数的类类型,然后在所有构造函数参数上按类型执行autowire。请注意,如果容器中没有构造函数参数类型的一个bean,则会引发致命错误。
  5. autodetect:自动检测自动装配使用两种模式中的任何一种,即构造函数或byType模式。首先,它将尝试查找带参数的有效构造函数,如果找到,则选择构造函数模式。如果bean中没有定义构造函数,或者存在显式默认的no-args构造函数,则选择autowire byType模式。

18.如何打开基于注释的自动装配?

要启用@Autowired,您必须注册AutowiredAnnotationBeanPostProcessor,并且您可以通过两种方式执行此操作。

1.包含<context:annotation-config >在bean配置文件中。

<beans>

    <context:annotation-config />

</beans>

2. AutowiredAnnotationBeanPostProcessor直接包含在bean配置文件中。

<beans>

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

</beans>

19.用例子解释@Required注释?

在生产规模的应用程序中,IoC容器中可能会有数百或数千个bean,并且它们之间的依赖关系通常非常复杂。setter注入的一个缺点是你很难检查是否已经设置了所有必需的属性。要解决此问题,可以设置<bean>的“ dependency-check ”属性,并设置四个属性之一,即none,simple,objects或all(none是默认选项)。

在实际应用程序中,您不会对检查上下文文件中配置的所有bean属性感兴趣。相反,您想检查是否仅在某些特定bean中设置了特定的属性集。Spring的依赖性检查功能使用“ dependency-check ”属性,在这种情况下无法帮助您。所以解决这个问题,你可以使用@Required注释。

@Required在类文件中使用bean属性的setter方法的注释,如下所示:

public class EmployeeFactoryBean extends AbstractFactoryBean<Object>

{

    private String designation;

      

    public String getDesignation() {

        return designation;

    }

  

    @Required

    public void setDesignation(String designation) {

        this.designation = designation;

    }

      

    //more code here

}

RequiredAnnotationBeanPostProcessor是一个spring bean post处理器,它检查是否@Required已设置带有注释的所有bean属性。要启用此Bean post处理器以进行属性检查,必须在Spring IoC容器中注册它。

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

如果@Required尚未设置任何属性,则BeanInitializationException此bean后处理器将抛出a 。

20.用示例解释@Autowired注释?

@Autowired注释提供了在哪里以及如何自动装配应实现更细粒度的控制。该@Autowired注解可以用于在setter方法,就像自动装配bean的@Required注释,构造函数,属性或方法具有任意名称和/或多个参数。

例如,您可以@Autowired在setter方法上使用注释来删除<property>XML配置文件中的元素。当Spring找到@Autowired与setter方法一起使用的注释时,它会尝试对该方法执行byType自动装配。

您也可以申请@Autowired构造函数。构造函数@Autowired注释指示在创建bean时应该自动装配构造函数,即使<constructor-arg>在XML文件中配置bean时没有使用任何元素。

public class TextEditor {

   private SpellChecker spellChecker;

 

   @Autowired

   public TextEditor(SpellChecker spellChecker){

      System.out.println("Inside TextEditor constructor." );

      this.spellChecker = spellChecker;

   }

 

   public void spellCheck(){

      spellChecker.checkSpelling();

   }

}

它没有构造函数参数的配置。

<beans>

 

   <context:annotation-config/>

 

   <!-- Definition for textEditor bean without constructor-arg -->

   <bean id="textEditor" class="com.howtodoinjava.TextEditor">

   </bean>

 

   <!-- Definition for spellChecker bean -->

   <bean id="spellChecker" class="com.howtodoinjava.SpellChecker">

   </bean>

 

</beans>

21.用例子解释@Qualifier注释?

@Qualifier意味着哪个bean有资格在一个字段上自动装配。当Spring不能这样做时,限定符注释有助于消除bean引用的歧义。

请参见下面的示例,它会将“ person ”bean自动装入客户的person属性中。

public class Customer

{

    @Autowired

    private Person person;

}

我们有两个Person类的bean定义。

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

 

<bean id="personA" class="com.howtodoinjava.common.Person" >

    <property name="name" value="lokesh" />

</bean>

 

<bean id="personB" class="com.howtodoinjava.common.Person" >

    <property name="name" value="alex" />

</bean>

春天会知道哪个人应该自动装豆子吗?没有。当您运行上面的示例时,它会遇到以下异常:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:

    No unique bean of type [com.howtodoinjava.common.Person] is defined:

        expected single matching bean but found 2: [personA, personB]

要解决上述问题,您需要@Quanlifier告诉Spring应该自动连接哪个bean。

public class Customer

{

    @Autowired

    @Qualifier("personA")

    private Person person;

}

22.构造函数注入和setter注入之间的区别?

请在下面找到明显的差异:

  1. 在Setter Injection中,部分注入依赖关系是可能的,意味着如果我们有3个依赖关系,如int,string,long,那么如果我们使用setter注入则不需要注入所有值。如果您没有注入,它将采用这些基元的默认值。在构造函数注入中,不可能部分注入依赖项,因为对于调用构造函数,我们必须正确传递所有参数,否则我们可能会得到错误。
  2. 如果我们为同一属性编写setter和constructor注入,Setter Injection将覆盖构造函数注入值。但是,构造函数注入不能覆盖setter注入的值。很明显,因为构造函数首先被调用来创建实例。
  3. 使用setter注入不能保证注入某些依赖项,这意味着您可能拥有一个不完整依赖项的对象。另一方面,构造函数注入不允许构造对象,直到您的依赖项准备就绪。
  4. 在构造函数注入中,如果对象A和B彼此依赖,即A依赖于B,反之亦然,则Spring ObjectCurrentlyInCreationException在创建A和B的对象时抛出,因为在创建B之前无法创建对象,反之亦然。因此Spring可以通过setter-injection来解决循环依赖关系,因为在调用setter方法之前构造了Objects。

23.春季框架中有哪些不同类型的事件?

Spring ApplicationContext提供了在代码中支持事件和侦听器的功能。我们可以创建bean来监听通过我们发布的事件ApplicationContextApplicationContext通过ApplicationEvent类和ApplicationListener接口提供事件处理。因此,如果bean实现了ApplicationListener,那么每次ApplicationEvent发布时ApplicationContext,都会通知该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()方法启动ApplicationContext时,将发布此事件。您可以轮询数据库,也可以在收到此事件后重新启动任何已停止的应用程序。
  3. ContextStoppedEvent:使用ConfigurableApplicationContext接口上的stop()方法停止ApplicationContext时发布此事件。收到此活动后,您可以进行必要的家务管理工作。
  4. ContextClosedEvent:使用ConfigurableApplicationContext接口上的close()方法关闭ApplicationContext时发布此事件。封闭的环境达到其生命的终点; 它无法刷新或重新启动。
  5. RequestHandledEvent:这是一个特定于Web的事件,告诉所有bean已经为HTTP请求提供服务。

除此之外,您还可以通过扩展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实例的帮助。

CustomApplicationEvent customEvent = new CustomApplicationEvent( applicationContext, "Test message" );

applicationContext.publishEvent ( customEvent );

24. FileSystemResource和ClassPathResource之间的区别?

FileSystemResource您需要提供spring-config.xml相对于您的项目的(Spring配置)文件的路径或文件的绝对位置。

ClassPathResourceSpring中查找文件使用,ClassPath所以spring-config.xml应该包含在classpath中。如果spring-config.xml在“ src ”中,那么我们可以给出它的名字,因为默认情况下src在classpath路径中。

在一个句子中,ClassPathResource在类路径中查找,FileSystemResource在文件系统中查找。

25.列举一些Spring Framework中使用的设计模式?

使用了大量不同的设计模式,但有一些明显的设计模式:

  • 代理 - 在AOP和远程使用中大量使用。
  • 单例 - 弹簧配置文件中定义的bean默认为单例。
  • 模板方法 -广泛地用来对付样板重复的代码如RestTemplateJmsTemplateJpaTemplate
  • 前端控制器 - Spring提供DispatcherServlet确保传入请求被分派到您的控制器。
  • View Helper - Spring有许多自定义JSP标记和速度宏,以帮助将代码与视图中的表示分离。
  • 依赖注入 - 整体BeanFactoryApplicationContext概念的中心。
  • 工厂模式 - 用于创建对象实例的BeanFactory。