Spring常见面试题

Spring中的Bean的作用域
  • singleton:唯一bean实例,Spring中的bean默认都是单例的。
  • prototype:每次请求都会创建一个新的bean实例。
  • request:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
  • session:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP session内有效。
Spring中 单例Bean的线程安全问题

大部分时候我们并没有在系统中使用多线程,所以很少有人会关注这个问题。单例bean存在线程问题,主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写操作会存在线程安全问题。
有两种常见的解决方案:

  • 1.在bean对象中尽量避免定义可变的成员变量(不太现实)。
  • 2.在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中(推荐的一种方式)。
Spring中的Bean生命周期

实例化–>属性赋值–>初始化–>销毁

  1. 实例化Bean。从Bean工厂中获取Bean,容器调用方法通过反射的方式创建出一个Bean对象进行实例化。
  2. 属性赋值。Bean创建好后对Bean进行属性填充,注入这个Bean依赖的其他bean对象。
  3. 初始化。首先判断是否执行Aware接口的方法,然后执行前置处理方法,判断是否实现了InitializingBean接口而调用afterPropertiesSet()方法,判断是否存在用户自定义的初始化方法,最后执行后置处理方法。
  4. 初始化完成。如果为singleon则Bean的对象会放入IOC的缓存池中,由Spring对Bean的生命周期管理,如果为prototype则将该Bean对象的生命周期交给调用者管理。
  5. 销毁,调用destroy()方法。
依赖注入

依赖注入(Dependency Injection,简称DI)是一种软件设计模式,用于实现对象之间的依赖关系。 在依赖注入中,一个对象的依赖关系不是在对象内部实现的,而是在容器外部实现的。换句话说,当一个对象需要其他对象的某些服务时,它不会自己创建所需要的对象,而是通过容器来注入所需要的对象。Spring Boot框架提供了依赖注入的实现,并且通过使用注解,可以非常方便地实现依赖注入。你可以通过使用@Autowired注解,来实现对象间的依赖关系,也可以通过配置文件,实现依赖关系。

循环依赖问题

循环依赖是指两个或多个Bean之间存在相互依赖的关系,导致容器无法初始化这些Bean。比如说,如果一个Bean A依赖于Bean B,同时Bean B也依赖于Bean A,那么就存在一个循环依赖的关系。 循环依赖是一个严重的问题,因为它会导致容器无法初始化,并且会抛出一个异常,因为。因此,在设计应用程序时,需要注意避免循环依赖。在实际开发中,一般通过设计模式、依赖注入等手段,来避免循环依赖的出现。

Spring中的设计模式
  1. 工厂模式:Spring使用工厂模式通过BeanFactory和ApplicationContext创建bean对象。
  2. 代理模式:Spring AOP功能的实现。
  3. 单例模式:Spring中Bean对象默认都是单例的。
  4. 包装器模式:项目需要连接多个数据库,不同的客户在每次访问中根据需要去访问不同的数据库。这种模式可以根据客户的需求能够动态切换不同的数据库。
  5. 观察者模式:Spring事件驱动模型就是观察者模式。
  6. 适配器模式:SpringAOP的增强或通知使用了适配器模式、SpringMVC中也使用适配器进行适配Controller。
@Component和@Bean的区别
  1. 作用对象不同。@Component注解作用于类,而@Bean注解作用于方法。
  2. @Component注解通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中。@Bean注解通常是在标有该注解的方法中定义产生这个bean,告诉Spring这是某个类的实例。
  3. @Bean注解比@Component注解的自定义性更强,而且很多地方只能通过@Bean注解来注册bean。
Spring的事务管理

1.编程式事务:在代码中硬编码(不推荐使用)。
2.声明式事务:在配置文件中配置(推荐使用),分为基于XML的声明式事务和基于注解的声明式事务。
隔离级别:
ISOLATION_DEFAULT:使用后端数据库默认的隔离级别
ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从ACID的隔离级别。

Spring事务中的事务传播行为
  1. PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  2. PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  3. PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)。
  4. PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起。
  5. PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  6. PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。
  7. PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于PROPAGATION_REQUIRED
SpringMVC

MVC是一种设计模式,SpringMVC是一款优秀的MVC框架,可以帮助我们进行方便的Web层的开发,并且与Spring集成。

Spring的工作原理
  1. 客户端发送请求后直接请求到DispatcherServlet
  2. DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler(Controller处理器)
  3. 解析到对应的处理器后,HandlerAdapter会根据Handler来调用真正的处理器来处理请求和相关业务逻辑
  4. 处理完成后悔返回一个ModelAndView对象
  5. ViewResolver进行view的解析
  6. DispatcherServlet把返回的Mode进行视图渲染,并返回给客户端
Spring、SpringMVC、SpringBoot的区别
  • Spring
    • Spring最重要的特征就是依赖注入,所有的SpringModules不是依赖注入就是IOC控制反转,使用DI和IOC可以开发低耦合的应用。 针对于开发的WEB层(springMvc)、业务层(Ioc)、持久层(jdbcTemplate)等都提供了多种配置解决方案;
  • SpringMVC
    • springMvc是spring基础之上的一个MVC框架,主要处理web开发的路径映射和视图渲染,属于spring框架中WEB层开发的一部分;
  • SpringBoot
    • 更专注于开发微服务后台接口,不开发前端视图,同时遵循默认优于配置,简化了插件配置流程,不需要配置xml,相对springmvc,大大简化了配置流程;
SpringBoot自动配置的原理

在Spring程序main方法中,添加@SpringBootApplication或者@EnableAutoConfiguration会自动去maven中读取每个starter中的spring.factories文件,该文件里配置了所有需要被创建的Spring容器中的bean,然后将这些bean注册到IOC容器中进行管理。

SpringBoot的启动流程
  1. 加载配置文件: Spring Boot支持多种配置文件的方式,包括application.properties、application.yml、以及其他配置文件,例如通过命令行参数指定的配置文件。Spring Boot会读取配置文件中的内容,并将其加载到应用程序的环境变量中,以便在整个应用程序的生命周期内使用。
  2. 创建上下文: 创建上下文是整个应用程序的核心。在创建上下文的过程中,Spring Boot会初始化所有的Bean,并且按照它们的依赖关系进行实例化。上下文还负责管理整个应用程序的生命周期,并且提供了管理Bean的能力。
  3. 扫描包:在创建上下文之后,Spring Boot会扫描配置文件中指定的包,并且根据配置文件的信息加载相应的组件。例如,如果配置文件中指定了某个包是一个Spring组件扫描的起点,那么Spring Boot会扫描这个包以及这个包下的所有子包,并且加载所有的组件。
  4. 初始化Bean:在扫描包之后,Spring Boot会初始化所有的Bean。这一步骤包括解析Bean的依赖关系,并且按照依赖关系进行实例化。在初始化Bean的过程中,Spring Boot会调用每个Bean的生命周期回调方法,例如@PostConstruct或者InitializingBean接口的afterPropertiesSet()方法,这些方法可以用于完成Bean的初始化工作。
  5. 启动Tomcat:在初始化Bean的过程中,如果应用程序需要启动一个Web服务器,那么Spring Boot会自动启动一个内嵌的Tomcat服务器。在启动Tomcat的过程中,Spring Boot会加载所有的Servlet、Filter和Listener组件,并且启动Tomcat的HttpConnector,以便接受客户端的请求。
  6. 启动应用程序:在启动Tomcat的过程中,如果没有任何错误,那么Spring Boot就会启动应用程序,并且接受客户端的请求。在这个阶段,应用程序已经准备好提供服务了,并且可以开始处理客户端的请求。
SpringBoot的核心注解

启动类上面的注解是@SpringBootApplication,他也是SpringBoot的核心注解,主要组合包含了以下3个注解:

  • @SpringBootConfiguration:组合了@Configuration注解,实现配置文件的功能;
  • @EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置的功能:
  • @SpringBootApplication(exclude={DataSourceAutoConfiguration.class});
  • @ComponentScan:Spring组件扫描。
SpringBoot stater

SpringBoot中的starter是一种非常重要的机制(自动化配置),能够抛弃以前繁杂的配置,将其统一集成进starter,应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启动相应的默认配置。starter让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰。SpringBoot会自动通过classpath路径下的类发现需要的Bean,并注册进IOC容器。

SpringBoot实现异常处理

Spring提供了一种使用ControllerAdvice处理异常的非常有用的方法。通过实现一个ControlerAdvice类,来处理控制类抛出的所有异常。

Myabtis中#和$的区别是什么

$ {}是 Properties 文件中的变量占位符,它可以用于标签属性值和 sql 内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc. Driver。
#{}是 sql 的参数占位符,MyBatis 会将 sql 中的#{}替换为? 号,在 sql 执行前会使用 PreparedStatement 的参数设置方法,按序给 sql 的? 号占位符设置参数值,比如 ps.setInt(0, parameterValue),#{item.name} 的取值方式为使用反射从参数对象中获取 item 对象的 name 属性值,相当于 param.getItem().getName()。

DAO接口的方法重载

Mybatis 的 Dao 接口可以有多个重载方法,但是多个接口对应的映射必须只有一个,Mybatis 的 xml 里面的 ID 不允许重复,否则启动会报错。

Mybatis分页原理

(1) MyBatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页;
(2) 可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能;
(3) 也可以使用分页插件来完成物理分页;

分页插件的基本原理是使用 MyBatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
spring 的优点? 1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 2.可以使用容易提供的众多服务,如事务管理,消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能 5.容器提供了众多的辅助类,能加快应用的开发 6.spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等 7.spring属于低侵入式设计,代码的污染极低 8.独立于各种应用服务器 9.spring的DI机制降低了业务对象替换的复杂性 10.Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可以自由选择spring的部分或全部 什么是DI机制? 依赖注入(Dependecy Injection)和控制反转(Inversion of Control)是同一个概念,具体的讲:当某个角色 需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中 创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者 因此也称为依赖注入。 spring以动态灵活的方式来管理对象 , 注入的两种方式,设置注入和构造注入。 设置注入的优点:直观,自然 构造注入的优点:可以在构造器中决定依赖关系的顺序。 什么是AOP? 面向切面编程(AOP)完善spring的依赖注入(DI),面向切面编程在spring中主要表现为两个方面 1.面向切面编程提供声明式事务管理 2.spring支持用户自定义的切面 面向切面编程(aop)是对面向对象编程(oop)的补充, 面向对象编程将程序分解成各个层次的对象,面向切面编程将程序运行过程分解成各个切面。 AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,oop是静态的抽象,aop是动态的抽象, 是对应用执行过程中的步骤进行抽象,,从而获得步骤之间的逻辑划分。 aop框架具有的两个特征: 1.各个步骤之间的良好隔离性 2.源代码无关性 Hibernate工作原理及为什么要用? 原理: 1.读取并解析配置文件 2.读取并解析映射信息,创建SessionFactory 3.打开Sesssion 4.创建事务Transation 5.持久化操作 6.提交事务 7.关闭Session 8.关闭SesstionFactory 为什么要用: 1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。 2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作 3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。 4. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。 2. Hibernate是如何延迟加载? 1. Hibernate2延迟加载实现:a)实体对象 b)集合(Collection) 2. Hibernate3 提供了属性的延迟加载功能 当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。 3.Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系) 类与类之间的关系主要体现在表与表之间的关系进行操作,它们都市对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many、 4. 说下Hibernate的缓存机制 1. 内部缓存存在Hibernate中又叫一级缓存,属于应用事物级缓存 2. 二级缓存: a) 应用及缓存 b) 分布式缓存 条件:数据不会被第三方修改、数据大小在可接受范围、数据更新频率低、同一数据被系统频繁使用、非 关键数据 c) 第三方缓存的实现 5. Hibernate的查询方式 Sql、Criteria,object comptosition Hql: 1、 属性查询 2、 参数查询、命名参数查询 3、 关联查询 4、 分页查询 5、 统计函数 6. 如何优化Hibernate? 1.使用双向一对多关联,不使用单向一对多 2.灵活使用单向一对多关联 3.不用一对一,用多对一取代 4.配置对象缓存,不使用集合缓存 5.一对多集合使用Bag,多对多集合使用Set 6. 继承类使用显式多态 7. 表字段要少,表关联不要

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sklit88

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值