- Spring核心基础
- Spring - 首页
- Spring - 概述
- Spring - 架构
- Spring - 环境搭建
- Spring - Hello World示例
- Spring - IoC容器
- Spring - Bean定义
- Spring - Bean作用域
- Spring - Bean生命周期
- Spring - Bean后置处理器
- Spring - Bean定义继承
- Spring - 依赖注入
- Spring - 注入内部Bean
- Spring - 注入集合
- Spring - Bean自动装配
- 基于注解的配置
- Spring - 基于Java的配置
- Spring - Spring中的事件处理
- Spring - Spring中的自定义事件
- Spring - Spring框架中的AOP
- Spring - JDBC框架
- Spring - 事务管理
- Spring - Web MVC框架
- Spring - 使用Log4J进行日志记录
- Spring问题及解答
- Spring - 问题及解答
- Spring有用资源
- Spring - 快速指南
- Spring - 有用资源
- Spring - 讨论
Spring面试题
亲爱的读者,这些Spring面试题特别设计,旨在帮助您熟悉在Spring主题面试中可能遇到的问题类型。根据我的经验,优秀的面试官在面试过程中很少会计划要问什么特定问题,通常会从主题的一些基本概念开始,然后根据进一步的讨论以及您的回答继续提问。
Spring是一个用于企业级Java的开源开发框架。Spring框架的核心功能可用于开发任何Java应用程序,但它也提供了扩展功能,可以在Java EE平台上构建Web应用程序。Spring框架的目标是简化J2EE开发,并通过启用基于POJO的编程模型来促进良好的编程实践。
以下是使用Spring框架的一些主要好处:
轻量级− Spring在大小和透明度方面都很轻量级。Spring框架的基本版本大约为2MB。
控制反转(IOC)− Spring使用控制反转技术实现松耦合。对象提供它们的依赖项,而不是创建或查找依赖对象。
面向方面(AOP)− Spring支持面向方面编程,并通过将应用程序业务逻辑与系统服务分离,从而实现内聚式开发。
容器− Spring包含并管理应用程序对象的整个生命周期和配置。
MVC框架− Spring的Web框架是一个设计良好的Web MVC框架,它为Struts或其他过度设计或不太流行的Web框架提供了一个很好的替代方案。
事务管理− Spring提供了一个一致的事务管理接口,可以缩减到本地事务(例如,使用单个数据库)并扩展到全局事务(例如,使用JTA)。
异常处理− Spring提供了一个方便的API,用于将特定于技术的异常(例如,由JDBC,Hibernate或JDO抛出)转换为一致的未检查异常。
以下是Spring框架的模块:
- 核心模块
- Bean模块
- 上下文模块
- 表达式语言模块
- JDBC模块
- ORM模块
- OXM模块
- Java消息服务(JMS)模块
- 事务模块
- Web模块
- Web-Servlet模块
- Web-Struts模块
- Web-Portlet模块
Spring配置文件是一个XML文件。该文件包含类信息,并描述了如何配置这些类以及如何将它们引入彼此。
控制反转(IoC)是一个通用概念,它可以通过多种不同的方式表达,而依赖注入仅仅是控制反转的一个具体示例。
这个概念说的是,您不创建对象,而是描述它们应该如何创建。您不会在代码中直接将组件和服务连接在一起,而是在配置文件中描述哪些组件需要哪些服务。然后,容器(IoC容器)负责将它们全部连接起来。
IoC的类型包括:
基于构造函数的依赖注入− 当容器调用一个具有多个参数的类构造函数时,每个参数都表示对其他类的依赖,就会实现基于构造函数的DI。
基于Setter的依赖注入− 通过在调用无参数构造函数或无参数静态工厂方法来实例化Bean之后,容器调用Bean上的Setter方法来实现基于Setter的DI。
由于您可以混合使用基于构造函数和基于Setter的DI,因此一个好的经验法则是:对于强制依赖项使用构造函数参数,对于可选依赖项使用Setter。请注意,在Setter上使用@Required注解可以用来将Setter设为强制依赖项。
IoC或依赖注入的主要好处是:
它最大限度地减少了应用程序中的代码量。
它使您的应用程序易于测试,因为它不需要在单元测试用例中使用任何单例或JNDI查找机制。
以最少的努力和最不具侵入性的机制来促进松耦合。
IoC容器支持服务的急切实例化和延迟加载。
面向方面编程(AOP)是一种编程技术,它允许程序员将横切关注点(或跨越典型责任划分的行为,例如日志记录和事务管理)模块化。AOP的核心结构是方面,它将影响多个类的行为封装到可重用的模块中。
Spring IoC创建对象,将它们连接在一起,配置它们,并管理它们从创建到销毁的整个生命周期。Spring容器使用依赖注入(DI)来管理构成应用程序的组件。
IoC容器有两种类型:
BeanFactory容器− 这是最简单的容器,提供对DI的基本支持。在资源有限的情况下(例如移动设备或基于Applet的应用程序),通常首选BeanFactory。
Spring ApplicationContext容器− 该容器添加了更多特定于企业的功能,例如能够从属性文件解析文本消息以及能够将应用程序事件发布到感兴趣的事件侦听器。
最常用的BeanFactory实现是XmlBeanFactory类。该容器从XML文件读取配置元数据,并使用它来创建一个完全配置的系统或应用程序。
'Application Context'的三个常用实现是:
FileSystemXmlApplicationContext− 该容器从XML文件加载Bean的定义。在这里,您需要向构造函数提供XML Bean配置文件的完整路径。
ClassPathXmlApplicationContext− 该容器从XML文件加载Bean的定义。在这里,您不需要提供XML文件的完整路径,但需要正确设置CLASSPATH,因为该容器将在CLASSPATH中查找Bean配置XML文件。
WebXmlApplicationContext− 该容器从Web应用程序内部加载包含所有Bean定义的XML文件。
以下是一些区别:
Application Context提供了一种解析文本消息的方法,包括对这些消息的i18n支持。
Application Context提供了一种通用的方式来加载文件资源,例如图像。
Application Context可以将事件发布到注册为侦听器的Bean。
某些对容器或容器中Bean的操作(必须使用BeanFactory以编程方式处理)可以在Application Context中以声明方式处理。
Application Context实现了MessageSource,这是一个用于获取本地化消息的接口,其实际实现是可插拔的。
构成应用程序主干并由Spring IoC容器管理的对象称为Bean。Bean是由Spring IoC容器实例化、组装和管理的对象。这些Bean是使用您提供给容器的配置元数据创建的,例如,以XML <bean/>定义的形式。
Bean定义包含称为配置元数据的信息,容器需要这些信息来了解以下内容:
- 如何创建Bean
- Bean的生命周期细节
- Bean的依赖项
有以下三种重要方法可以向Spring容器提供配置元数据:
- 基于XML的配置文件。
- 基于注解的配置
- 基于Java的配置
查看以下示例:
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld"> <property name = "message" value = "Hello World!"/> </bean> </beans>
在Spring中定义<bean>时,可以选择为该Bean声明一个作用域。例如,要强制Spring在每次需要时都生成一个新的Bean实例,应将Bean的scope属性声明为prototype。类似地,如果希望Spring每次需要时都返回相同的Bean实例,应将Bean的scope属性声明为singleton。
Spring框架支持以下五种作用域,其中三种只有在使用web感知的ApplicationContext时才可用。
singleton − 将bean定义的作用域限定为每个Spring IoC容器一个实例。
prototype − 将单个bean定义的作用域限定为可以拥有任意数量的对象实例。
request − 将bean定义的作用域限定为一个HTTP请求。仅在web感知的Spring ApplicationContext上下文中有效。
session − 将bean定义的作用域限定为一个HTTP会话。仅在web感知的Spring ApplicationContext上下文中有效。
global-session − 将bean定义的作用域限定为一个全局HTTP会话。仅在web感知的Spring ApplicationContext上下文中有效。
Spring框架中bean的默认作用域是Singleton。
否,Spring框架中的singleton bean不是线程安全的。
以下是Spring中bean生命周期的顺序:
实例化 − 首先,Spring容器从XML文件中找到bean的定义并实例化bean。
填充属性 − 使用依赖注入,Spring根据bean定义中指定的属性填充所有属性。
设置Bean名称 − 如果bean实现了BeanNameAware接口,Spring会将bean的id传递给setBeanName()方法。
设置Bean工厂 − 如果Bean实现了BeanFactoryAware接口,Spring会将beanfactory传递给setBeanFactory()方法。
初始化前 − 也称为bean的后处理。如果任何BeanPostProcessors与bean相关联,Spring会调用postProcesserBeforeInitialization()方法。
初始化bean − 如果bean实现了IntializingBean,则调用其afterPropertySet()方法。如果bean具有init方法声明,则调用指定的初始化方法。
初始化后 − 如果任何BeanPostProcessors与bean相关联,则会调用其postProcessAfterInitialization()方法。
准备使用 − 现在bean可以被应用程序使用了。
销毁 − 如果bean实现了DisposableBean,它将调用destroy()方法。
在<property/>或<constructor-arg/>元素内部的<bean/>元素定义了一个所谓的内部bean。内部bean定义不需要定义的id或名称;容器会忽略这些值。它还会忽略scope标志。内部bean始终是匿名的,并且始终作用域为原型。
Spring提供了四种类型的集合配置元素,如下所示:
<list> − 这有助于连接,即注入值列表,允许重复。
<set> − 这有助于连接值集,但不允许重复。
<map> − 这可以用来注入名称-值对的集合,其中名称和值可以是任何类型。
<props> − 这可以用来注入名称-值对的集合,其中名称和值都是字符串。
Spring容器能够自动装配协作bean之间的关系。这意味着可以通过检查BeanFactory的内容自动让Spring解析bean的协作者(其他bean),而无需使用<constructor-arg>和<property>元素。
自动装配功能有五种模式,可用于指示Spring容器对依赖注入使用自动装配:
no − 这是默认设置,表示不进行自动装配,应使用显式bean引用进行连接。对于这种连接,您无需执行任何特殊操作。这正是您在依赖注入章节中已经看到的。
byName − 按属性名称自动装配。Spring容器查看在XML配置文件中autowire属性设置为byName的bean的属性。然后,它尝试将其属性与配置文件中定义的相同名称的bean进行匹配和连接。
byType − 按属性数据类型自动装配。Spring容器查看在XML配置文件中autowire属性设置为byType的bean的属性。然后,如果其类型与配置文件中bean名称完全匹配,它会尝试匹配和连接属性。如果存在多个此类bean,则会抛出致命异常。
constructor − 类似于byType,但类型适用于构造函数参数。如果容器中构造函数参数类型的bean不只有一个,则会引发致命错误。
autodetect − Spring首先尝试使用autowire by constructor进行连接,如果失败,Spring尝试使用autowire by byType进行连接。
自动装配的局限性有:
覆盖可能性 − 您仍然可以使用<constructor-arg>和<property>设置指定依赖项,这将始终覆盖自动装配。
原始数据类型 − 您无法自动装配所谓的简单属性,例如基本类型、字符串和类。
混乱的本质 − 自动装配不如显式连接精确,因此,如果可能,请优先使用显式连接。
是的。
基于注解的配置提供了XML设置的替代方案,它依赖于字节码元数据来连接组件,而不是角括号声明。开发人员无需使用XML来描述bean连接,而是通过在相关类、方法或字段声明上使用注解将配置移动到组件类本身。
默认情况下,Spring容器中不会开启注解连接。因此,在我们可以使用基于注解的连接之前,需要在Spring配置文件中通过配置<context:annotation-config/>来启用它。
此注解简单地表明受影响的bean属性必须在配置时填充,方法是在bean定义中使用显式属性值或通过自动装配。如果受影响的bean属性未填充,则容器会抛出BeanInitializationException。
此注解提供了更细粒度的控制,用于控制自动装配在哪里以及如何完成。@Autowired注解可用于在setter方法上自动装配bean,就像@Required注解、构造函数、属性或具有任意名称和/或多个参数的方法一样。
可能存在您创建多个相同类型的bean并希望只将其中一个与属性连接的情况,在这种情况下,您可以将@Qualifier注解与@Autowired一起使用,通过指定将连接哪个确切的bean来消除混淆。
Spring具有基于JSR-250的注解,其中包括@PostConstruct、@PreDestroy和@Resource注解。
@PostConstruct − 此注解可用作初始化回调的替代方案。
@PreDestroy − 此注解可用作销毁回调的替代方案。
@Resource − 此注解可用于字段或setter方法。@Resource注解采用“name”属性,该属性将被解释为要注入的bean名称。您可以说,它遵循按名称自动装配语义。
基于Java的配置选项使您能够在没有XML的情况下编写大部分Spring配置,而是借助一些基于Java的注解。
例如:注解@Configuration表示该类可以被Spring IoC容器用作bean定义的来源。@Bean注解告诉Spring,用@Bean注解的方法将返回一个对象,该对象应在Spring应用程序上下文中注册为bean。
ApplicationContext中的事件处理是通过ApplicationEvent类和ApplicationListener接口提供的。因此,如果一个bean实现了ApplicationListener,那么每次将ApplicationEvent发布到ApplicationContext时,都会通知该bean。
Spring提供以下标准事件:
ContextRefreshedEvent − 当ApplicationContext初始化或刷新时,发布此事件。这也可以通过在ConfigurableApplicationContext接口上使用refresh()方法来引发。
ContextStartedEvent − 当使用ConfigurableApplicationContext接口上的start()方法启动ApplicationContext时,发布此事件。在收到此事件后,您可以轮询数据库,或者重新/启动任何已停止的应用程序。
ContextStoppedEvent − 当使用ConfigurableApplicationContext接口上的stop()方法停止ApplicationContext时,发布此事件。在收到此事件后,您可以执行所需的清理工作。
ContextClosedEvent − 当使用ConfigurableApplicationContext接口上的close()方法关闭ApplicationContext时,发布此事件。关闭的上下文将达到其生命周期结束;它无法刷新或重新启动。
RequestHandledEvent − 这是一个特定于web的事件,告诉所有bean已服务于HTTP请求。
一个模块,它具有一组提供横切需求的API。例如,日志记录模块将被称为日志记录的AOP切面。应用程序可以根据需要拥有任意数量的切面。在Spring AOP中,切面是使用常规类(基于模式的方法)或使用@Aspect注解的常规类(@AspectJ风格)实现的。
关注点 − 关注点是我们希望在应用程序模块中具有的行为。关注点可以定义为我们想要实现的功能。我们感兴趣的问题定义了我们的关注点。
横切关注点 − 它是适用于整个应用程序并影响整个应用程序的关注点。例如,日志记录、安全性和数据传输是在应用程序的几乎每个模块中都需要关注的点,因此是横切关注点。
这表示应用程序中您可以插入AOP切面的一个点。您也可以说,它是应用程序中使用Spring AOP框架采取操作的实际位置。
这是在方法执行之前或之后要采取的实际操作。这是Spring AOP框架在程序执行期间调用的实际代码段。
这是一组一个或多个连接点,在这些连接点上应执行通知。您可以使用表达式或模式指定切点,就像我们在AOP示例中看到的那样。
简介允许您向现有类添加新的方法或属性。
被一个或多个方面建议的对象,此对象始终为代理对象。也称为被建议对象。
织入是将方面与其他应用程序类型或对象链接以创建被建议对象的流程。
织入可以在编译时、加载时或运行时进行。
Spring 方面可以使用以下五种通知类型:
before - 在方法执行之前运行通知。
after - 无论方法执行结果如何,都在方法执行之后运行通知。
after-returning - 仅当方法成功完成时,才在方法执行之后运行通知。
after-throwing - 仅当方法通过抛出异常退出时,才在方法执行之后运行通知。
around - 在调用被建议方法之前和之后运行通知。
方面是使用常规类以及基于 XML 的配置来实现的。
@AspectJ 指的是将方面声明为使用 Java 5 注解进行注释的常规 Java 类的一种风格。
借助 Spring 框架提供的名为 JdbcTemplate 的模板类,可以更有效地使用 JDBC。
使用 Spring JDBC 框架,资源管理和错误处理的负担大大减少。因此,它让开发人员编写语句和查询以获取数据库中的数据。JdbcTemplate 提供了许多便利方法来执行诸如将数据库数据转换为基本类型或对象、执行准备好的和可调用的语句以及提供自定义数据库错误处理等操作。
Spring 支持两种类型的交易管理:
编程事务管理 - 这意味着您已在编程的帮助下管理了事务。这为您提供了极大的灵活性,但难以维护。
声明式事务管理 - 这意味着您将事务管理与业务代码分离。您只需使用注释或基于 XML 的配置来管理事务。
尽管声明式事务管理不如编程事务管理灵活,但它允许您通过代码控制事务,因此它比编程事务管理更可取。
Spring Web MVC 框架提供模型-视图-控制器架构以及可用于开发灵活且松耦合 Web 应用程序的现成组件。MVC 模式导致分离应用程序的不同方面(输入逻辑、业务逻辑和 UI 逻辑),同时在这些元素之间提供松耦合。
Spring Web MVC 框架围绕一个 DispatcherServlet 设计,它处理所有 HTTP 请求和响应。
WebApplicationContext 是普通 ApplicationContext 的扩展,它具有一些 Web 应用程序所需的额外功能。它与普通 ApplicationContext 的区别在于它能够解析主题,并且它知道它与哪个 servlet 相关联。
以下是 Spring MVC 相比于 Struts MVC 的一些优势:
Spring 的 MVC 基于接口,非常通用和灵活,但 Struts 强制将 Action 和 Form 对象继承为具体类。
Spring 提供拦截器和控制器,从而有助于将常见行为分解到多个请求的处理中。
Spring 可以配置不同的视图技术,如 Freemarker、JSP、Tiles、Velocity、XLST 等,还可以通过实现 Spring View 接口创建自己的自定义视图机制。
在 Spring MVC 中,可以使用 DI(IOC)配置控制器,这使得它的测试和集成变得容易。
Spring MVC 的 Web 层比 Struts Web 层更容易测试,因为避免了强制具体继承和控制器对分派 servlet 的显式依赖。
Struts 强制您的控制器扩展 Struts 类,但 Spring 没有,您可以选择扩展许多便捷的控制器实现。
在 Struts 中,Action 通过在 ActionMapping 中或全局定义 ActionForwards 来耦合到视图。SpringMVC 具有 HandlerMapping 接口来支持此功能。
使用 Struts,验证通常在 ActionForm 的 validate 方法中执行(实现)。在 SpringMVC 中,验证器是业务对象,不依赖于 Servlet API,这使得这些验证器可以在将域对象持久化到数据库之前在您的业务逻辑中重用。
控制器提供对应用程序行为的访问,您通常通过服务接口定义这些行为。控制器解释用户输入并将其转换为由视图呈现给用户的模型。Spring 以非常抽象的方式实现控制器,这使您可以创建各种控制器。
@Controller 注解表示特定类充当控制器的角色。Spring 不要求您扩展任何控制器基类或引用 Servlet API。
@RequestMapping 注解用于将 URL 映射到整个类或特定的处理程序方法。
使用 Spring 访问 Hibernate 有两种方法:
使用 Hibernate 模板和回调进行控制反转。
扩展 HibernateDAOSupport 并应用 AOP 拦截器节点。
Spring 支持以下 ORM:
- Hibernate
- iBatis
- JPA(Java 持久性 API)
- TopLink
- JDO(Java 数据对象)
- OJB
接下来是什么?
您可以进一步回顾您之前完成的与该主题相关的作业,并确保您能够自信地谈论它们。如果您是应届毕业生,面试官不会期望您回答非常复杂的问题,而是您必须使自己的基础概念非常牢固。
其次,如果您无法回答一些问题,其实并不重要,重要的是无论您回答了什么,都必须充满自信。所以在面试时要自信。我们在 tutorialspoint 祝您面试顺利,并祝您未来的工作一切顺利。欢呼 :-)