java框架-spring面试题 丨【奔跑吧!JAVA】

举报
菜鸟级攻城狮 发表于 2021/06/30 22:00:58 2021/06/30
【摘要】 java框架-spring面试题

Spring概述

什么是Spring?

Spring是一个轻量级Java开发框架,最早有Rod Johnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEE full-stack (一站式)轻量级开源框架,为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构,因此Java开发者可以专注于应用程序的开发。

Spring最根本的使命是解决企业级应用开发的复杂性,即简化Java开发。

Spring可以做很多事情,它为企业级开发提供给了丰富的功能,但是这些功能的底层都依赖于它的两个核心特性,也就是依赖注入(dependency injection,DlI)*和*面向切面编程(aspect-orientedprogramming,AOP)。

为了降低Java开发的复杂性,Spring采取了以下4种关键策略·

基于POJO的轻量级和最小侵入性编程;

通过依赖注入和面向接口实现松耦合;

基于切面和惯例进行声明式编程;

通过切面和模板减少样板式代码。

Spring框架的设计目标,设计理念,和核心是什么?

Spring设计目标: Spring为开发者提供一个一站式轻量级应用开发平台;

Spring设计理念:在JavaEE开发中,支持POJO和JavaBean开发方式,使应用面向接口开发,充分支持00(面向对象)设计方法;Spring通过loC容器实现对象耦合关系的管理,并实现依赖反转,将对象之间的依赖关系交给loC容器,实现解耦;

Spring框架的核心: loC容器和AOP模块。通过loC容器管理POJO对象以及他们之间的耦合关系;通过AOP以动态非侵入的方式增强服务。

Spring的主要核心是:

(1)控制反转(OC):传统的java 开发模式中,当需要一个对象时,我们会自己使用new或者getInstance等直接或者间接调用构造方法创建一个对象,而在Spring 开发模式中,Spring容器使用了工厂模式为我们创建了所需要的对象,我们使用时不需要自己去创建,直接调用Spring为我们提供的对象即可,这就是控制反转的思想。实例化一个java对象有三种方式:使用类构造器,使用静态工厂方法,使用实例工厂方法,当使用spring时我们就不需要关心通过何种方式实例化一个对象, spring通过控制反转机制自动为我们实例化一个对象。(底层原理是反射)

(2)依赖注入(DI): Spring使用Java Bean对象的Set 方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程就是依赖注入的基本思想。

(3)面向切面编程(AOP):在面向对象编程(OOP)思想中,我们将事物纵向抽象成一个个的对象。而在面向切面编程中,我们将一个个对象某些类似的方面横向抽象成一个切面,对这个切面进行一些如权限验证,事物管理记录日志等公用操作处理的过程就是面向切面编程的思想。(底层原理是动态代理)

IoC 和 DI 的区别
IoC 控制反转,指将对象的创建权,反转到 Spring 容器 , DI 依赖注入,指 Spring 创建对象的过程中,将对象
依赖属性通过配置进行注入

spring 支持构造器注入和 setter 方法注入构造器注入,通过 <constructor-arg> 元素完成注入setter 方法注入, 通过<property> 元素完成注入【开发中常用方式】
在 Spring 中,所有管理的对象都是 JavaBean 对象,而 BeanFactory 和 ApplicationContext 就是 spring 框架的两个 IOC 容器,现在般使用 ApplicationContext,其不但包含了 BeanFactory 的作用,同时还进行更多的扩展。
Spring Bean 生命周期
1.Spring 容器 从 XML 文件中读取 Bean 的定义,并实例化 Bean。
2.Spring 根据 Bean 的定义填充所有的属性。
3.如果 Bean 实现了 BeanNameAware 接口,Spring 传递 bean 的 ID 到 setBeanName 方法。
4.如果 Bean 实现了 BeanFactoryAware 接口, Spring 传递 beanfactory 给 setBeanFactory 方法。
5.如果有任何与 bean 相关联的 BeanPostProcessors,Spring 会在 postProcesserBeforeInitialization()方法内调用
它们。
6.如果 bean 实现 IntializingBean 了,调用它的 afterPropertySet 方法,如果 bean 声明了初始化方法,调用此初始化方法。
7.如果有 BeanPostProcessors 和 bean 关联,这些 bean 的 postProcessAfterInitialization() 方法将被调用。
8.如果 bean 实现了 DisposableBean,它将调用 destroy()方法。
注意:
有两个重要的 bean 生命周期方法,第个是 setup() , 它是在容器加载 bean 的时候被调用。第二个方法是 teardown() 它是在容器卸载类的时候被调用。 The bean 标签有两个重要的属性 init-method 和 destroy-method。使用它们你可以自己定制初始化和注销方法。它们也有相应的注解@PostConstruct 和@PreDestroy。

springbean 的作用域
四种,singleton(默认值),prototype,request,session

SpringMVC
1. SpringMVC 的工作原理
a. 用户向服务器发送请求,请求被 springMVC 前端控制器 DispatchServlet 捕获;
b. DispatcherServle 对请求 URL 进行解析,得到请求资源标识符(URL),然后根据该 URL 调用 HandlerMapping
将请求映射到处理器 HandlerExcutionChain;
c. DispatchServlet 根据获得 Handler 选择个合适的 HandlerAdapter 适配器处理;
d. Handler 对数据处理完成以后将返回个 ModelAndView()对象给 DisPatchServlet;
e. Handler 返回的 ModelAndView()只是个逻辑视图并不是个正式的视图,DispatcherSevlet 通过 ViewResolver 试图解析器将逻辑视图转化为真正的视图 View;
h. DispatcherServle 通过 model 解析出 ModelAndView()中的参数进行解析最终展现出完整的 view 并返回给 客户端
SpringMVC 常用注解都有哪些?

@requestMapping 用于请求 url 映射。
@RequestBody 注解实现接收 http 请求的 json 数据,将 json 数据转换为 java 对象。
@ResponseBody 注解实现将 controller 方法返回对象转化为 json 响应给客户。

Spring 中的设计模式
1.代理模式Spring 中两种代理方式,若目标对象实现了若干接口,spring 使用 JDK 的 java.lang.reflect.Proxy 类代理若目标对象没有实现任何接口,spring 使用 CGLIB 库生成目标对象的子类。Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术。
2.单例模式在 spring 配置文件中定义的 bean 默认为单例模式。
3.模板方法模式用来解决代码重复的问题。
比如: RestTemplate, JmsTemplate, JpaTemplate,redistemplate
4.前端控制器模式Srping 提供了 DispatcherServlet 来对请求进行分发。
5.视图帮助(View Helper )Spring 提供了系列的 JSP 标签,高效宏来辅助将分散的代码整合在视图里。
6.依赖注入贯穿于 BeanFactory/ApplicationContext 接口的核心理念。
7.工厂模式在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用个共同的接口 来指向新创建的对象。Spring 中使用 BeanFactory 用来创建对象的实例。BeanFactory就是简单工厂模式的体现,用来创建对象的实例;

Spring 注解
Spring 在 2.5 版本以后开始支持用注解的方式来配置依赖注入。可以用注解的方式来替代 XML 方式的 bean 描 述,可以将 bean 描述转移到组件类的内部,只需要在相关类上、方法上或者字段声明上使用注解即可。注解 注入将会被容器在 XML 注入之前被处理,所以后者会覆盖掉前者对于同个属性的处理结果。
注解装配在 Spring 中是默认关闭的。所以需要在 Spring 文件中配置下才能使用基于注解的装配模式。如果 你想要在你的应用程序中使用关于注解的方法的话,请参考如下的配置。
<beans> <context:annotation-config/> <!-- bean definitions go here --> </beans> <context:annotation-config/>标签配置完成以后,就可以用注解的方式在 Spring 中向属性、方法和构造方法中 自动装配变量。
几种比较重要的注解类型:
@Component :标识了个受 Spring 管理的组件,泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注
@Respository: 标识持久层,数据访问组件,即 DAO 组件
@Service: 标识业务层组件
@Controller :标识表现层,控制层组件
(1)@RequestMapping
@RequestMapping 是用来处理请求地址映射的注解,可用于类或方法上。用在类上,表示类中所有的响应的
方法都是以该地址作为父路径来访问,用在方法上表示该方法的访问的路径;两者结合起来的访问的路径为完
整的访问某个方法的路径。
@RequestMapping 注解的属性:
value:指定请求的实际的地址,指定的地址可以是 URI Template 模式;method:指定访问的方法
consumes:指定处理请求的内容类型,比如 aplication/json;text/html
produces:指定返回的内容的类型
params:指定 request 中必须包含某些参数值时,才让该方法处理请求
headers:指定 request 中必须包含指定的 header 值,才能让该方法处理请求
@Resource 和@Autowired
@Resource 和@Autowired 都是做 bean 的注入时使用,都可以写在字段上,或者是 setter 方法上
@Autowired 注解是按照类型(byType)装配依赖对象(由 Spring 提供)
如果在此基础上想通过 byName 来装配,可以结合@Qualifier 注解来起使用。
@Resource 默认按照 byName 自动注入
@Resource 有两个重要的属性,name 和 type
@Resource 如果写属性 name,则按照 byName 来装配,如果属性为 type,则按照 byType 来装配,不写按照 默认的方式来装配(byName)

Spring 事务
Spring 支持两种类型的事务管理:
1.编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
2.声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和 XML 配置来管理事务


Spring 事务配置示例(使用 tx 标签配置的拦截器)
<!-- 定义事务管理器(声明式的事务) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean> <!- 配置 Advice 通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes> <tx:method name="*" propagation="REQUIRED" />
</tx:attributes> </tx:advice>
<!-- 配置切点切面 -->
<aop:config>
<aop:pointcut id="interceptorPointCuts" expression="execution(*com.bluesky.spring.dao.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" />
</aop:config>

spring 的事务传播行为
spring 事务的传播行为说的是,当多个事务同时存在的时候,spring 如何处理这些事务的行为。
① PROPAGATION_REQUIRED:如果当前没有事务,就创建个新事务,如果当前存在事务,就加入该事务, 该设置是最常用的设置。
② PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就 以非事务执行。
③ PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务, 就抛出异常。
④ PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
⑤ PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
⑥ PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
⑦ PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按 REQUIRED 属性执行。

Spring 如何处理线程并发问题
般情况下,只有无状态的 Bean 才可以在多线程环境下共享,在 Spring 中,绝大部分 Bean 都可以声明为 singleton 作用域,因为 Spring 对些 Bean 中非线程安全状态采用 ThreadLocal 进行处理,解决线程安全问

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

使用Spring有哪些方式?

作为一个成熟的Spring Web应用程序。
作为第三方Web框架,使用Spring Frameworks 中间层。
作为企业级Java Bean,它可以包装现有的POJO(Plain Old Java Objects)。·用于远程使用。
Spring能帮我们做什么?
Spring 能帮我们根据配置文件创建及组装对象之间的依赖关系。
Spring根据配置文件来进行创建及组装对象间依赖关系,只需要改配置文件即可Spring面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制。
Spring面向切面编程能提供一种更好的方式来完成,一般通过配置方式,而且不需要在现有代码中添加任何额外代码,现有代码专注业务逻辑。
Spring能非常简单的帮我们管理数据库事务。
采用Spring,我们只需获取连接,执行SQL,其他事物相关的都交给Spring来管理了。Spring还能与第三方数据库访问框架(如Hibernate、JPA)无缝集成,而且自己也提供了一套JDBC
Spring 如何设计容器的,BeanFactory和ApplicationContext的关系详解
Spring作者Rod Johnson设计了两个接口用以表示容器。
BeanFactory      ApplicationContext
BeanFactory简单粗暴,可以理解为就是个HashMap,Key是BeanName,Value是Bean实例。通常只提供注册(put),获取(get)这两个功能。我们可以称之为“低级容器"。
ApplicationContext可以称之为“高级容器"。因为他比BeanFactory 多了更多的功能。他继承了多个接口。因此具备了更多的功能。例如资源的获取,支持多种消息(例如JSP tag的支持),对BeanFactory多了工具级别的支持等待。所以你看他的名字,已经不是BeanFactory之类的工厂了,而是"应用上下文",代表着整个大容器的所有功能。该接口定义了一个refresh方法,此方法是所有阅读Spring 源码的人的最熟悉的方法,用于刷新整个容器,即重新加载/刷新所有的bean。
当然,除了这两个大接口,还有其他的辅助接口,这里就不介绍他们了。
BeanFactory和ApplicationContext的关系
为了更直观的展示“低级容器"和“高级容器"的关系,这里通过常用的ClassPathXmlApplicationContext类来展示整个容器的层级UML关系。
【奔跑吧!JAVA】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/265241
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。