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.什么是Spring内部bean?
13.在Spring Framework中,Singleton bean线程安全吗?
14.如何在Spring中注入Java Collection?举个例子?
15.如何将java.util.Properties注入Spring Bean?
16.解释Spring Bean自动装配吗?
17.解释Bean自动装配的不同模式吗?
18.如何打开基于注释的自动装配?
19.用示例解释@Required注释?
20.用示例解释@Autowired注释?
21.用示例解释@Qualifier批注?
22.构造函数注入和setter注入之间的区别?
23. Spring框架中有哪些不同类型的事件?
24. FileSystemResource和ClassPathResource之间的区别?
25.命名Spring框架中使用的一些设计模式吗?

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

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

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

弹簧模块

阅读更多:Spring Framework教程

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

以下是使用Spring Framework的一些主要好处的清单-

  • 使用Dependency Injection(DI)方法,依赖关系在构造函数或JavaBean属性中是显式的且显而易见的。
  • IoC容器趋向于轻量级,尤其是例如与EJB容器相比时。这对于在内存和CPU资源有限的计算机上开发和部署应用程序很有帮助。
  • Spring并没有彻底改变这种状况,它确实利用了一些现有技术,例如几个ORM框架,日志记录框架,JEE,Quartz和JDK计时器以及其他视图技术。
  • Spring以模块化的方式组织。即使包和类的数量很大,您也只需要担心需要的包而忽略其余的包。
  • 测试用Spring编写的应用程序很简单,因为依赖于环境的代码已移入该框架。此外,通过使用JavaBean风格的POJO,使用依赖注入来注入测试数据变得更加容易。
  • Spring的Web框架是一个经过精心设计的Web MVC框架,它为Struts之类的Web框架或其他经过精心设计或不太受欢迎的Web框架提供了绝佳的替代方案。
  • Spring提供了一个一致的事务管理接口,该接口可以扩展到本地事务(例如,使用单个数据库),并扩展到全局事务(例如,使用JTA)。

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

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

控制反转是一种设计范例,其目标是对应用程序的目标组件(实际上是在工作的组件)提供更多控制。

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

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

  1. 一个构造函数注入
  2. 一个setter注入
  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>标记开头,并包含许多Bean定义和特定于应用程序的配置选项。

Spring XML Configuration的主要目标是使用xml文件配置所有Spring组件。
这意味着将不存在任何其他类型的Spring Configuration(例如注释或通过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 config的等效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/>配置完成,就可以开始注释代码,以指示Spring应该自动将值连接到属性,方法和构造函数中。

在这种类型的配置中,很少使用的重要注释是:

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

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

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

Spring bean factory负责管理通过spring容器创建的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范围是默认的,它强制容器在每个spring容器中只有一个实例,而与您请求实例的时间无关。这种单例行为由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?

在Spring框架中,每当一个bean仅用于一个特定属性时,建议将其声明为一个内部bean。设置器注入“ property ”和构造函数注入“ constructor-arg ” 都支持内部bean 。

例如,假设我们一个Customer类具有class的引用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 clase),因此线程安全性很小。但是,如果您的bean具有可变状态(例如,视图模型对象),那么您需要确保线程安全。解决此问题最简单,最明显的方法是将可变豆的范围从“ 单例Singleton ”更改为“ 原型ProtoType ”。

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

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

<list>:这有助于接线,即注入值列表,允许重复。
<set>:这有助于接线一组值,但不能重复。
<map>:这可以用来注入名称-值对的集合,其中名称和值可以是任何类型。
<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自动装配吗?

在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自动装配的不同模式吗?

spring框架中有五种自动接线模式。让我们一一讨论。

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

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

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

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

<beans>
    <context:annotation-config />
</beans>

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

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

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

在生产规模的应用程序中,可能会在IoC容器中声明成百上千个bean,并且它们之间的依赖关系通常非常复杂。setter注入的缺点之一是,您很难检查是否已设置所有必需的属性。为了克服这个问题,您可以设置<bean>的“ dependency-check ”属性,并设置四个属性之一,即无,简单,对象或全部(无为默认选项)。

在现实生活中的应用程序中,您不会对检查上下文文件中配置的所有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后处理器进行属性检查,必须在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注释表明,即使<constructor-arg>在XML文件中配置Bean时不使用任何元素,创建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>

Spring会知道应该自动连接哪个人的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注入中,可能会部分注入依赖项,这意味着如果我们有3个依赖项(如int,string,long),那么如果使用setter注入,则不必注入所有值。如果您不注入,它将采用这些原语的默认值。在构造函数注入中,不可能部分注入依赖项,因为调用构造函数时,我们必须正确传递所有参数,否则,可能会出错。
  2. 如果我们为同一属性编写setter和构造函数注入,则Setter Injection将覆盖构造函数注入值。但是,构造函数注入不能覆盖setter注入的值。显而易见,因为首先要调用构造函数才能创建实例。
  3. 使用setter注入,您不能保证是否注入了某些依赖关系,这意味着您可能拥有不完全依赖关系的对象。另一方面,在依赖项准备就绪之前,构造函数注入不允许您构造对象。
  4. 在构造函数注入中,如果对象A和B相互依赖,即A依赖于B,反之亦然,则Spring ObjectCurrentlyInCreationException在创建A和B的对象时会抛出异常,因为在创建B之前无法创建对象,反之亦然。因此spring可以通过setter注入解决循环依赖关系,因为对象是在调用setter方法之前构造的。

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

Spring ApplicationContext提供了支持代码中的事件和侦听器的功能。我们可以创建bean来监听通过我们的发布的事件ApplicationContextApplicationContext通过ApplicationEvent类和ApplicationListener接口提供中的事件处理。因此,如果Bean实现ApplicationListener,则每次将Bean 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 Configuration)文件相对于您的项目的路径或该文件的绝对位置。

ClassPathResource春季,使用ClassPathso 查找文件spring-config.xml应包含在classpath中。如果spring-config.xml在“ src ”中,则可以仅给出其名称,因为默认情况下src在类路径路径中。

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

25.命名Spring框架中使用的一些设计模式吗?

有很多使用不同设计模式的负载,但是有一些显而易见的负载:

  • 代理 –在AOP和远程处理中大量使用。
  • 单例 –在Spring配置文件中定义的bean默认为单例。
  • 模板方法 -广泛地用来对付样板重复的代码如RestTemplateJmsTemplateJpaTemplate
  • Front Controller – Spring提供DispatcherServlet以确保传入的请求被调度到您的控制器。
  • View Helper – Spring具有许多自定义的JSP标记和Velocity宏,以帮助将代码与视图中的表示分离。
  • 依赖注入 –以整体BeanFactoryApplicationContext概念为中心。
  • 工厂模式 –用于创建对象实例的BeanFactory。
发布了933 篇原创文章 · 获赞 388 · 访问量 281万+

猜你喜欢

转载自blog.csdn.net/kingmax54212008/article/details/104119391
今日推荐