Spring常见面试题一

46次阅读

共计 3117 个字符,预计需要花费 8 分钟才能阅读完成。

一、Spring 的 AOP 理解

   OOP 面向对象,允许开发者定义纵向的关系,但并适用于定义横向的关系,导致了大量代码的重复,而不利于各个模块的重用。AOP,一般称为面向切面,作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。可用于权限认证、日志、事务处理。AOP 实现的关键在于 代理模式,AOP 代理主要分为静态代理和动态代理。静态代理的代表为 AspectJ;动态代理则以 Spring AOP 为代表。AspectJ 是静态代理的增强,所谓静态代理,就是 AOP 框架会在编译阶段生成 AOP 代理类,因此也称为编译时增强,他会在编译阶段将 AspectJ(切面) 织入到 Java 字节码中,运行的时候就是增强之后的 AOP 对象。Spring AOP 使用的动态代理,所谓的动态代理就是说 AOP 框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个 AOP 对象,这个 AOP 对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。静态代理与动态代理区别在于生成 AOP 代理对象的时机不同,相对来说 AspectJ 的静态代理方式具有更好的性能,但是 AspectJ 需要特定的编译器进行处理,而 Spring AOP 则无需特定的编译器处理。

二、Spring 的 IoC 理解

    IOC 就是控制反转,是指创建对象的控制权的转移,以前创建对象的主动权和时机是由自己把控的,而现在这种权力转移到 Spring 容器中,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复用。DI 依赖注入,和控制反转是同一个概念的不同角度的描述,即 应用程序在运行时依赖 IoC 容器来动态注入对象需要的外部资源。最直观的表达就是,IOC 让对象的创建不用去 new 了,可以由 spring 自动生产,使用 java 的反射机制,根据配置文件在运行时动态的去创建对象以及管理对象,并调用对象的方法的。

三、BeanFactory 和 ApplicationContext 有什么区别

   BeanFactory 和 ApplicationContext 是 Spring 的两大核心接口,都可以当做 Spring 的容器。其中 ApplicationContext 是 BeanFactory 的子接口。BeanFactory:是 Spring 里面最底层的接口,包含了各种 Bean 的定义,读取 bean 配置文档,管理 bean 的加载、实例化,控制 bean 的生命周期,维护 bean 之间的依赖关系。ApplicationContext 接口作 BeanFactory 的派生,除了提供 BeanFactory 所具有的功能外,还提供了更完整的框架功能:继承 MessageSource,因此支持国际化。统一的资源文件访问方式。提供在监听器中注册 bean 的事件。同时加载多个配置文件。载入多个(有继承关系)上下文,使得每一个上下文都专注于一个特定的层次,比如应用的 web 层。BeanFactroy 采用的是延迟加载形式来注入 Bean 的,即只有在使用到某个 Bean 时 (调用 getBean()),才对该 Bean 进行加载实例化。这样,我们就不能发现一些存在的 Spring 的配置问题。如果 Bean 的某一个属性没有注 BeanFacotry 加载后,直至第一次使用调用 getBean 方法才会抛出异常。ApplicationContext,它是在容器启动时,一次性创建了所有的 Bean。这样,在容器启动时,我们就可以发现 Spring 中存在的配置错误,这样有利于检查所依赖属性是否注入。ApplicationContext 启动后预载入所有的单实例 Bean,通过预载入单实例 bean , 确保当你需要的时候,你就不用等待,因为它们已经创建好了。相对于基本的 BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置 Bean 较多时,程序启动较慢。BeanFactory 通常以编程的方式被创建,ApplicationContext 还能以声明的方式创建,如使用 ContextLoader。BeanFactory 和 ApplicationContext 都支持 BeanPostProcessorBeanFactoryPostProcessor 的使用,但两者之间的区别是:BeanFactory 需要手动注册,而 ApplicationContext 则是自动注册。

四、请解释 Spring Bean 的生命周期

  首先说一下 Servlet 的生命周期:实例化,初始 init,接收请求 service,销毁 destroy;Spring 上下文中的 Bean 生命周期也类似,如下:对于 BeanFactory 容器,当客户向容器请求一个尚未初始化的 bean 时,或初始化 bean 的时候需要注入另一个尚未初始化的依赖时,容器就会调用 createBean 进行实例化。对于 ApplicationContext 容器,当容器启动结束后,通过获取 BeanDefinition 对象中的信息,实例化所有的 bean。实例化后的对象被封装在 BeanWrapper 对象中,紧接着,Spring 根据 BeanDefinition 中的信息 以及 通过 BeanWrapper 提供的设置属性的接口完成依赖注入。接着,Spring 会检测该对象是否实现了 xxxAware 接口,并将相关的 xxxAware 实例注入给 Bean, 如果想对 Bean 进行一些自定义的处理,那么可以让 Bean 实现了 BeanPostProcessor 接口,那将会调用 postProcessBeforeInitialization(Object obj, String s) 方法。如果 Bean 在 Spring 配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。如果这个 Bean 实现了 BeanPostProcessor 接口,将会调用 postProcessAfterInitialization(Object obj, String s) 方法;由于这个方法是在 Bean 初始化结束时调用的,所以可以被应用于内存或缓存技术;当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 这个接口,会调用其实现的 destroy() 方法;最后,如果这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会自动调用其配置的销毁方法。

五、解释 Spring 支持的几种 bean 的作用域。

  Spring 容器中的 bean 可以分为 5 个范围:

1,singleton:默认,每个容器中只有一个 bean 的实例,单例的模式由 BeanFactory 自身来维护。
2,prototype:为每一个 bean 请求提供一个实例。
3,request:为每一个网络请求创建一个实例,在请求完成以后,bean 会失效并被垃圾回收器回收。
4,session:与 request 范围类似,确保每个 session 中有一个 bean 的实例,在 session 过期后,bean 会随之失效。
5,global-session:全局作用域,global-session 和 Portlet 应用相关。当你的应用部署在 Portlet 容器中工作时,它包含很多 portlet。

 如果你想要声明让所有的 portlet 共用全局的存储变量的话,那么这全局变量需要存储在 global-session 中。全局作用域与 Servlet 中的 session 作用域效果相同。

想要更多资料,撩小娜哦:gzitcast

正文完
 0