spring面试题

本文详细介绍了Spring框架的核心特性,包括轻量级、非侵入式设计、控制反转(IOC)和面向切面编程(AOP)。讨论了Bean的生命周期、依赖查找与依赖注入的区别以及各种注入方式。此外,还涵盖了Spring中的事务管理,如隔离级别和事务传播属性。文章进一步阐述了SpringMVC的工作原理和SpringBoot的自动装配机制。最后提到了SpringCloud的关键组件,如Eureka服务注册与发现,Hystrix的熔断机制在解决服务雪崩问题中的作用。
摘要由CSDN通过智能技术生成

Spring

特点

  1. 轻量级:完整的Spring框架可以在一个只有1M多的JAR文件里发布;非侵入式的(spring应用中的对象不依赖与spring的特定类);
  2. 控制反转(IOC):创建对象的控制权被反转到了Spring框架上;
  3. 面向切面(AOP):Spring支持面向切面工程,并且把应用业务逻辑和系统服务分开;
  4. 容器
  5. 框架集合

bean生命周期

  1. 根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean;
  2. 利用依赖注入完成 Bean 中所有属性值的配置注入;
  3. 如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值;
  4. 如果Bean实现了BeanFactoryAware接口,则Spring调用setBeanFactory()方法传入当前工厂实例的引用;
  5. 如果Bean实现了ApplicationContextAware接口,则Spring调用setApplicationContext()方法传入当前ApplicationContext实例的引用;
  6. 如果BeanPostProcessor和Bean关联,则Spring将调用该接口的预初始化方法postProcessBeforeInitialization方法对Bean进行加工操作,此处非常重要,Spring的AOP就是利用它实现的;
  7. 如果Bean实现了Initialization接口,则Spring将调用afterPropertiesSet方法;
  8. 如果在配置文件中通过init-method属性指定了初始化方法,则调用该初始化方法;
  9. 如果BeanPostProcessor和Bean关联,则Spring将调用该接口的初始化方法postProcessAfterInitialization方法。注:以上工作完成以后就可以应用这个Bean了,那这个Bean是一个Singleton的,所以一般情况下我们调用同一个id的Bean会是在内容地址相同的实例,当然在Spring配置文件中也可以配置非Singleton;
  10. 如果Bean实现了DisposableBean接口,则Spring会调用destroy()方法将Spring中的Bean销毁;如果在配置文件中通过destroy-method属性指定了Bean的销毁方法,则Spring将调用该方法对Bean进行销毁。

Spring中,两个id相同的bean会报错吗?

首先在同一XML配置文件中不能存在id相同的两个bean,否则spring容器在启动时会报错,因为id这个属性表示bean里边的唯一标志符号,所以spring在启动的时候回去验证id的唯一性,一旦发现重复会报错,这个错误发生在spring多xml文件进行解析转化为BeanDefinition的一个阶段。但是在两个不同的xml配置文件里边可以存在id相同的两个bean,IOC容器在加载Bean的时候默认会把多个相同id的bean进行覆盖。在spring3.x版本以后,这个问题就发生了变化,它提供了一个@Configuration注解去声明一个配置类,然后使用@Bean这个注解去实现bean的声明,如果我们在同一个配置类里边去声明多个相同名字的Bean,Spring IOC容器在解析的时候只会注册第一个声明Bean的一个实例。

IOC

通常,我们实例化一个对象时,都是使用类的构造方法来new一个对象,这个是由我们自己来控制的,而控制反转就把new对象的工作交给了Spring容器。
IOC的主要实现方式有两种:依赖查找和依赖注入。依赖注入是一种更可取的方式。

依赖查找和依赖入注入的区别

依赖查找:主要是容器为组件提供一个回调接口和上下文环境。这样一来,组件就必须自己使用容器提供的API来查找资源和协作对象,控制反转进体现在那些回调方法上,容器调用这些回调方法,从而应用代码获取到资源。
依赖注入:组件不做定位查询,只提供标准的java方法让容器去决定依赖关系。容器全权负责组件的装配,把符合依赖关系的对象通过JavaBean属性或构造方法传递给需要的对象。

依赖注入方式
  1. 注解注入方式;
  2. Set注入方式
  3. 构造器注入方式
  4. 静态工厂注入方式

AOP

面向切面编程就是纵向的编程,AOP主要一般应用与签名验签、参数校验、日志记录、事务控制、权限控制、性能统计、异常处理等;

  • 切面(Aspect):共有功能的实现,如日志切面、权限切面、验签切面等。在实际开发中通常是一个存放共有功能实现的标准java类,当java类使用了@Aspect注解修饰时,就能被AOP容器识别为切面;
  • 通知(Advice):切面的具体实现。就是要给目标对象织入的事情。以目标方法为参照点,根据放置的地方不同,可分为前置通知(Before)、后置通知(AfterReturning)、异常通知(AfterThrowing)、最终通知(After)与环绕通知(Around)。在实际开发中通常是切面类中的一个方法,具体属于哪类通知,通过方法上的注解区分;
  • 连接点(JoinPoint):程序在运行过程中能够插入切面的地点。例如,方法调用、异常抛出等。Spring只支持方法级的连接点。一个类的所有方法前、后、抛出异常时等都是连接点;
  • 切入点(Pointcut):用于定义通知应该切入到哪些连接点上。不同的通知通常需要切入到不同的连接点上,这种精准的匹配是由切入点的正则表达式来定义的;切点就是来定义哪些类里边的哪些方法会得到通知;
  • 目标对象(Target):那些即将切入切面的对象;
  • 代理对象(Proxy):将通知应用到目标对象之后被动态创建的对象,是程序运行过程中的产物。目标对象被织入共有功能后产生的对象
  • 织入(Weaving):将切面应用到目标对象从而创建一个新的代理对象的过程。
Pointcut用法
execution(modifier-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
  • 修饰符匹配 modifier-pattern?例:public、private
  • 返回值匹配 ret-type-pattern?可以用“*”表示任意返回值
  • 类路径匹配 declaring-type-pattern? 全路径的类名
  • 方法名匹配 name-pattern 可以指定方法名或者用 * 表示所有方法;set星号表示所有以set开头的方法
  • 参数匹配 (param-pattern) 可以指定具体的参数类型,多个参数用“,”分隔;可以用 * 表示匹配任意类型的参数;可以用(…)表示零个或多个任意参数
  • 异常类型匹配 throws-pattern? 例:throws Exception
    其中后边跟着?表示可选项
    例:
@Pointcut("execution(public * cn.wbnull. springbootdemo.controller.*.*(..))")
private void sign() {
 
}

常用注解

  1. @Component:泛指组件,当组件不好归类的时候,可以使用这个注解进行标注
  2. @Controller:控制层组件
  3. @RestController:相当于@Controller和@ResponseBody的组合效果
  4. @Service:业务层组件
  5. @Repository:用于注解DAO层,在daoImpl类上面注解
  6. @ResponseBody:将Controller的方法返回的对象,转换为指定格式后,写入Response对象的body数据区;
  7. @RequestMapping:用来处理请求地址映射的注解,可用于类上或方法上;
  8. @Autowired:可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作;
  9. @PathVariable:用于将请求URL中的模板变量映射到功能处理方法的参数上;
  10. @RequestParam:类似一种request.getParameter(“name”);
  11. @Valid:实体数据校验;
  12. @CookieValue:用来获取Cookie中的值;

实例化的三种方式

构造器实例化、静态工厂方式实例化、实例工厂方式实例化。

隔离级别

  1. DEFAULT(默认):使用数据库默认的事务隔离级别,另外四个与JDBC隔离级别一致;
  2. READ_UNCOMMITTED(读未提交):事务最低的隔离级别,允许一个事务读取另一个事务未提交的数据,可能产生脏读、不可重复读和幻象读;
  3. READ_COMMITTED(读已提交):保证一个事务修改的数据提交之后才能被另一个事务读取。可以避免脏读,但是可能会出现不可重复读和幻象读;
  4. REPEATABLE_READ(可重复读):除了保证一个事务不能读取另一个事务未提交的数据外,还保证了不可重复读,可以防止脏读和不可重复读,但是可能出现幻象读;
  5. SERIALIZABLE(串行化):代价最高但是最可靠的隔离级别,事务被处理为顺序执行。可以防止脏读、不可重复读和幻象读。

事务传播属性

  1. REQUIRED(默认属性):如果存在事务,则支持当前事务,不存在事务,则开启一个新的事务;
  2. MANDATORY:支持当前事务,如果当前没有事务,则抛出异常;
  3. NEVER:以非事务方式运行,如果当前存在事务,则抛出异常:
  4. NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,就把当前事务挂起;
  5. REQUIRES_NEW:新建事务,如果当前没有事务,就以非事务方式运行;
  6. SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式运行;
  7. NESTED:支持当前事务,并且新增一个SavePoint点,与当前事务同步提交或回滚。

spring三级缓存

解决Bean的循环依赖问题

  1. 单例对象缓存:存放完全初始化后的Bean
  2. 早期单例对象的缓存:存放原始Bean,并且存在尚未填充的属性
  3. 单例工厂的缓存:存放的是工厂对象,工厂对象的目的是生成Bean实例
    在Bean的创建过程中,spring会适当的从这三个缓存中检索或者放入对象,确保即使存在循环依赖的情况下,也能成功的去创建和注入Bean

springMVC

springMVC的运行原理
  1. 客户端发送请求,直接请求到DispatcherServlet。
  2. DispatcherServlet根据请求信息调用HandlerMaping,解析获取对应的Handler;
  3. 解析到对应的Handler后,开始有HandlerAdapter适配器处理;
  4. HandlerAdapter会根据Handler来调用真正的处理器开始处理请求,并返回一个ModelAndView对象,Model是返回的数据,View是一个逻辑上的View;
  5. ViewResolver会根据逻辑上的View查找实际的View;
  6. DispatcherServlet把返回的Model传给View,通过View返回给请求者。

springboot

自动装配原理

自动装配是springboot的核心,实际上SpringFramework早就实现了这个功能,SpringBoot只是在其基础上,通过SPI的方式,做了进一步优化。
首先@SpringBootApplication是一个复合注解,可以把它看作是@Configuration、@EnableAutoConfiguration、@ComponentScan注解的集合,实现自动装配的核心注解就是@EnableAutoConfiguration,它上边是有一个@Import注解导入了一个AutoConfigurationImportSelector,这个类里边实现了selectImports方法,这个方法最终就会从META-INF/spring.factories文件中读取@EnableAutoConfiguration类路径为key的类名称列表,然后会通过加载核心类方式过滤当前项目并不需要加载的配置类,然后把需要加载的配置类名称数组返回之后进行加载;

springcloud

五大常用组件:

  1. 服务注册中心:Eureka
  2. 负载均衡:ribbon
  3. 熔断器:Hystrix
  4. 网关:Gateway
  5. 分布式配置:SpringCloudConfig
Eureka

就是服务注册中心,对外暴露自己的地址。提供者启动后向Eureka注册自己的信息(地址、提供什么服务),消费者会向Eureka订阅服务,Eureka会将对应服务的所有提供者地址列表发送给消费者,并且定期更新。提供者定期会通过http方式向Eureka刷新自己的状态(心跳-续约)。

Hystrix

Hystrix是一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败。

解决雪崩问题

Hystrix解决雪崩的问题主要是服务降级,包括线程隔离、服务熔断;

  1. 线程隔离&服务降级:Hystrix会为每个依赖的服务分配一个小的线程池,如果线程池已满调用将立即被拒绝,默认不采取排队的方法,加速失败判断时间。如果线程已满或者请求超时,则会进行降级处理,服务降级(优先保证核心服务,而非核心服务不可用或弱可用)虽然会导致请求失败,但是不会造成阻塞,而且最多会影响这个依赖服务对应的线程池中的资源,对其他服务没有影响。请求在超过一秒后都会返回错误信息,这是因为Hystrix默认超时时间为1秒。
  2. 服务熔断:也叫断路器,Hystrix的服务熔断机制,可以实现弹性容错。一定时间内请求失败百分比达到阈值,则触发熔断,默认失败比的阈值是50%,请求次数不低于20次。断路器打开之后,通过断路的方式,将后续请求直接拒绝,一段时间(默认5秒)之后允许部分请求通过,如果调用成功则关闭断路器,否则继续打开,拒绝请求的服务。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值