美文网首页
Spring面试题

Spring面试题

作者: 一蓬蒿人 | 来源:发表于2019-12-14 12:30 被阅读0次

    IOC

    什么是依赖注入?

    在依赖注入中,您不必创建对象,但必须描述如何创建它们。您不是直接在代码中将组件和服务连接在一起,而是描述配置文件中哪些组件需要哪些服务。由 IoC 容器将它们装配在一起。

    可以通过多少种方式完成依赖注入?

    通常,依赖注入可以通过三种方式完成,即:
    构造函数注入
    setter 注入
    接口注入
    在 Spring Framework 中,仅使用构造函数和 setter 注入。

    区分构造函数注入和 setter 注入。

    构造函数注入 | setter 注入
    没有部分注入 | 有部分注入
    不会覆盖 setter 属性 | 会覆盖 setter 属性
    任意修改都会创建一个新实例 | 任意修改不会创建一个新实例
    适用于设置很多属性 | 适用于设置少量属性

    spring 中有多少种 IOC 容器?

    BeanFactory - BeanFactory 就像一个包含 bean 集合的工厂类。它会在客户端要求时实例化 bean。
    ApplicationContext - ApplicationContext 接口扩展了 BeanFactory 接口。它在 BeanFactory 基础上提供了一些额外的功能。

    区分 BeanFactory 和 ApplicationContext。

    BeanFactory | ApplicationContext
    它使用懒加载 | 它使用即时加载
    它使用语法显式提供资源对象 | 它自己创建和管理资源对象
    不支持国际化 | 支持国际化
    不支持基于依赖的注解 | 支持基于依赖的注解

    Bean

    什么是 spring bean?

    它们是构成用户应用程序主干的对象。
    Bean 由 Spring IoC 容器管理。
    它们由 Spring IoC 容器实例化,配置,装配和管理。
    Bean 是基于用户提供给容器的配置元数据创建。

    spring 提供了哪些配置方式?

    • 基于 xml 配置
      bean 所需的依赖项和服务在 XML 格式的配置文件中指定。这些配置文件通常包含许多 bean 定义和特定于应用程序的配置选项。它们通常以 bean 标签开头。
    • 基于注解配置
      您可以通过在相关的类,方法或字段声明上使用注解,将 bean 配置为组件类本身,而不是使用 XML 来描述 bean 装配。默认情况下,Spring 容器中未打开注解装配。因此,您需要在使用它之前在 Spring 配置文件中启用它。
    • 基于 Java API 配置
      Spring 的 Java 配置是通过使用 @Bean 和 @Configuration 来实现。
      @Bean 注解扮演与 <bean /> 元素相同的角色。
      @Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义 bean 间依赖关系。

    spring 支持集中 bean scope?

    Spring bean 支持 5 种 scope:

    • Singleton - 每个 Spring IoC 容器仅有一个单实例。
    • Prototype - 每次请求都会产生一个新的实例。
    • Request - 每一次 HTTP 请求都会产生一个新的实例,并且该 bean 仅在当前 HTTP 请求内有效。
    • Session - 每一次 HTTP 请求都会产生一个新的 bean,同时该 bean 仅在当前 HTTP session 内有效。
    • Global-session - 类似于标准的 HTTP Session 作用域,不过它仅仅在基于 portlet 的 web 应用中才有意义。Portlet 规范定义了全局 Session 的概念,它被所有构成某个 portlet web 应用的各种不同的 portlet 所共享。在 global session 作用域中定义的 bean 被限定于全局 portlet Session 的生命周期范围内。如果你在 web 中使用 global session 作用域来标识 bean,那么 web 会自动当成 session 类型来使用。
      仅当用户使用支持 Web 的 ApplicationContext 时,最后三个才可用。

    spring bean 容器的生命周期是什么样的?

    Spring Bean的生命周期分为四个阶段多个扩展点。扩展点又可以分为影响多个Bean和影响单个Bean。整理如下:

    • 四个阶段
      实例化 Instantiation
      属性赋值 Populate
      初始化 Initialization
      销毁 Destruction
    • 多个扩展点
    1. 影响多个Bean
      BeanPostProcessor
      InstantiationAwareBeanPostProcessor
    2. 影响单个Bean
      Aware
      Aware Group1
      BeanNameAware
      BeanClassLoaderAware
      BeanFactoryAware
      Aware Group2
      EnvironmentAware
      EmbeddedValueResolverAware
      ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware)
    • 生命周期
      InitializingBean
      DisposableBean

    自动装配有哪些方式?

    Spring 容器能够自动装配 bean。也就是说,可以通过检查 BeanFactory 的内容让 Spring 自动解析 bean 的协作者。自动装配的不同模式:

    • no - 这是默认设置,表示没有自动装配。应使用显式 bean 引用进行装配。
    • byName - 它根据 bean 的名称注入对象依赖项。它匹配并装配其属性与 XML 文件中由相同名称定义的 bean。
    • byType - 它根据类型注入对象依赖项。如果属性的类型与 XML 文件中的一个 bean 名称匹配,则匹配并装配属性。
    • 构造函数 - 它通过调用类的构造函数来注入依赖项。它有大量的参数。
    • autodetect - 首先容器尝试通过构造函数使用 autowire 装配,如果不能,则尝试通过 byType 自动装配。

    自动装配有什么局限?

    • 覆盖的可能性 - 您始终可以使用 <constructor-arg> 和 <property> 设置指定依赖项,这将覆盖自动装配。
    • 基本元数据类型 - 简单属性(如原数据类型,字符串和类)无法自动装配。
    • 令人困惑的性质 - 总是喜欢使用明确的装配,因为自动装配不太精确。

    注解

    什么是基于注解的容器配置

    不使用 XML 来描述 bean 装配,开发人员通过在相关的类,方法或字段声明上使用注解将配置移动到组件类本身。它可以作为 XML 设置的替代方案。例如:
    Spring 的 Java 配置是通过使用 @Bean 和 @Configuration 来实现。
    @Bean 注解扮演与 元素相同的角色。
    @Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义 bean 间依赖关系。

    @Configuration
    public class StudentConfig {
        @Bean
        public StudentBean myStudent() {
            return new StudentBean();
        }
    }
    

    如何在 spring 中启动注解装配?

    默认情况下,Spring 容器中未打开注解装配。因此,要使用基于注解装配,我们必须通过配置<context:annotation-config /> 元素在 Spring 配置文件中启用它。

    @Component, @Controller, @Repository, @Service 有何区别?

    • @Component:这将 java 类标记为 bean。它是任何 Spring 管理组件的通用构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。
    • @Controller:这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会自动导入到 IoC 容器中。
    • @Service:此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。您可以在服务层类中使用 @Service 而不是 @Component,因为它以更好的方式指定了意图。
    • @Repository:这个注解是具有类似用途和功能的 @Component 注解的特化。它为 DAO 提供了额外的好处。它将 DAO 导入 IoC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException。

    @Required 注解有什么用?

    @Required 应用于 bean 属性 setter 方法。此注解仅指示必须在配置时使用 bean 定义中的显式属性值或使用自动装配填充受影响的 bean 属性。如果尚未填充受影响的 bean 属性,则容器将抛出 BeanInitializationException。

    @Autowired 注解有什么用?

    @Autowired 可以更准确地控制应该在何处以及如何进行自动装配。此注解用于在 setter 方法,构造函数,具有任意名称或多个参数的属性或方法上自动装配 bean。默认情况下,它是类型驱动的注入。

    @Qualifier 注解有什么用?

    当您创建多个相同类型的 bean 并希望仅使用属性装配其中一个 bean 时,您可以使用@Qualifier 注解和 @Autowired 通过指定应该装配哪个确切的 bean 来消除歧义。

    @RequestMapping 注解有什么用?

    @RequestMapping 注解用于将特定 HTTP 请求方法映射到将处理相应请求的控制器中的特定类/方法。此注释可应用于两个级别:

    • 类级别:映射请求的 URL
    • 方法级别:映射 URL 以及 HTTP 请求方法

    @Resource和@Autowired差异

    • 相同点
      两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。
    • 不同点:
      1. @Autowired
        @Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。
        @Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。
      2. @Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。
        @Resource装配顺序:
        ①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
        ②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
        ③如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。
        ④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。
        @Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入。

    @Component和@Configuration差异

    @Configuration 注解本质上还是 @Component,因此 <context:component-scan/> 或者 @ComponentScan 都能处理@Configuration 注解的类。
    @Configuration 中所有带 @Bean 注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例。
    @Configuration 注解的 bean 都已经变成了增强的类。
    @Configuration 标记的类必须符合下面的要求:
    配置类必须以类的形式提供(不能是工厂方法返回的实例),允许通过生成子类在运行时增强(cglib 动态代理)。
    配置类不能是 final 类(没法动态代理)。
    配置注解通常为了通过 @Bean 注解生成 Spring 容器管理的类,
    配置类必须是非本地的(即不能在方法中声明,不能是 private)。
    任何嵌套配置类都必须声明为static。
    @Bean 方法可能不会反过来创建进一步的配置类(也就是返回的 bean 如果带有 @Configuration,也不会被特殊处理,只会作为普通的 bean)。

    Aop

    Spring事务

    spring 支持的事务管理类型

    Spring 支持两种类型的事务管理:

    • 编程式事务管理使用TransactionTemplate。
    • 声明式事务管理建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
      对比:
      声明式事务最大的优点就是不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明或通过@Transactional注解的方式,便可以将事务规则应用到业务逻辑中。
      声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式,使业务代码不受污染,只要加上注解就可以获得完全的事务支持。唯一不足地方是,最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。

    事务传播行为

    • PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。
    • PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。‘
    • PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
    • PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
    • PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
    • PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
    • PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。

    Spring事件

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

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

    • 上下文更新事件(ContextRefreshedEvent):在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。
    • 上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。
    • 上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
    • 上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
    • 请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。
      如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent 被发布以后,bean会自动被通知。

    Spring事件实现类

    ApplicationEvent:表示事件本身,自定义事件需要继承该类,可以用来传递数据,比如上述操作,我们需要将用户的邮箱地址传给事件监听器.
    ApplicationEventPublisherAware:事件发送器,通过实现这个接口,来触发事件.
    ApplicationListener:事件监听器接口,事件的业务逻辑封装在监听器里面.

    Spring MVC

    SpringMVC流程

    (1)用户发送请求至前端控制器DispatcherServlet;
    (2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
    (3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
    (4)DispatcherServlet 调用 HandlerAdapter处理器适配器;
    (5)HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);
    (6)Handler执行完成返回ModelAndView;
    (7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
    (8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
    (9)ViewResolver解析后返回具体View;
    (10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
    (11)DispatcherServlet响应用户。


    SpringMVC常用的注解有哪些?

    @RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。
    @RequestBody:注解实现接收http请求的json数据,将json转换为java对象。
    @ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。

    HandlerMapping类型

    • BeanNameUrlHandlerMapping (默认)根据controller的name名称来映射寻找controller,开启该映射:默认是开启的.
    • SimpleUrlHandlerMapping 根据URL来映射寻找controller, 开启该映射
    • ControllerClassNameHandlerMapping 根据controller的类名来映射寻找controller
    • DefaultAnnotationHandlerMapping 使用注解来映射寻找controller

    HandlerAdapter类型

    SimpleServletHandlerAdapter可以处理类型为Servlet的handler,对handler的处理是调用Servlet的service方法处理请求
    SimpleControllerHandlerAdapter可以处理类型为Controller的handler,对handler的处理是调用Controller的handleRequest()方法。
    HttpRequestHandlerAdapter可以处理类型为HttpRequestHandler的handler,对handler的处理是调用HttpRequestHandler的handleRequest()方法。
    RequestMappingHandlerAdapter可以处理类型为HandlerMethod的handler,对handler的处理是调用通过java反射调用HandlerMethod的方法。
    AnnotationMethodHandlerAdapter 已经被废弃了。

    相关文章

      网友评论

          本文标题:Spring面试题

          本文链接:https://www.haomeiwen.com/subject/shecnctx.html