前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >spring八股记录

spring八股记录

作者头像
用户11204257
发布2024-12-04 13:25:45
发布2024-12-04 13:25:45
10800
代码可运行
举报
运行总次数:0
代码可运行

spring专题

*.自己的认识理解

1.mvc架构

model(模型:service、daomapper);view(视图:jsp);controller(控制:servlet)

1.用户发请求 2.servlet接受请求数据,并调用对应的业务逻辑方法 3.业务处理完毕,返回更新后的数据给servlet 4.servlet转向到jsp,jsp渲染页面 5.响应给前端更新后的页面

C:控制器 1.取得表单数据/json数据 2.调用业务逻辑 3.转向指定页面 M:模型 1.业务逻辑 2.保存数据的状态 V:视图 1.显示页面

  1. 切面=切入点+通知
  2. ioc实现了资源的可控制由客户端控制,means 控制反转和易管理、降低对象之间的耦合;aop也是降低代码之间的耦合
  3. ioc、di、构造器注入关系:ioc -ioc的实现方式是di-di依赖注入-依赖注入有属性注入,set方法注入和构造器注入;@Autowire是属性注入
  4. 静态代理:程序员自己写好代理类,在编译时就确定了被代理的类,通常静态代理只代理一个类;动态代理:运行的时候通过反射创建代理类,通常代理的是同一个接口下的多个类; aop就是基于动态代理的;如果要代理的对象实现了某个接口,那么Spring AOP会使用JDK Proxy去创建代理对象,而对于没有实现接口的对象,Spring AOP会使用Cglib生成一个代理对象的子类作为代理。
  5. ioc的总结用到的机制:
  6. 反射-控制中的创建-反射允许在运行时动态的检查类的信息,更灵活的实现对象的实例化和管理
  7. 依赖注入-控制中的初始化-管理对象之间的依赖关系,将组件的依赖关系描述在配置文件或使用注解
  8. 工厂模式-控制中的销毁-控制bean的实例化和生命周期
  9. spring aop的实现依赖于动态代理。动态代理是在运行时动态的生成代理对象,而不是编译的时候。允许在运行时指定要代理的接口和行为,从而在不修改源码的情况下增强方法的功能
  10. 代理的目的/作用:代理模式的主要目的是为其他对象提供一种代理,以控制对这些对象的访问‌。代理模式通过引入一个代理对象来间接访问目标对象,从而可以在访问目标对象之前或之后执行一些额外的操作,如预处理、过滤、增强等功能‌
  11. 方法栈区放一些类的数据结构
  12. 依赖注入是通过后处理器实现的postProcessor{构造器注入}
  13. 消息队列,消息队列的三大作用是:
  14. 解耦:可以在多个系统之间进行解耦,将原本通过网络之间的调用的方式改为使用MQ进行消息的异步通讯,只要该操作不是需要同步的,就可以改为使用MQ进行不同系统之间的联系,这样项目之间不会存在耦合,系统之间不会产生太大的影响,就算一个系统挂了,也只是消息挤压在MQ里面没人进行消费而已,不会对其他的系统产生影响。
  15. 异步:加入一个操作设计到好几个步骤,这些步骤之间不需要同步完成,比如客户去创建了一个订单,还要去客户轨迹系统添加一条轨迹、去库存系统更新库存、去客户系统修改客户的状态等等。这样如果这个系统都直接进行调用,那么将会产生大量的时间,这样对于客户是无法接收的;并且像添加客户轨迹这种操作是不需要去同步操作的,如果使用MQ将客户创建订单时,将后面的轨迹、库存、状态等信息的更新全都放到MQ里面然后去异步操作,这样就可加快系统的访问速度,提供更好的客户体验。
  16. 削峰:一个系统访问流量有高峰时期,也有低峰时期,比如说,中午整点有一个抢购活动等等。比如系统平时流量并不高,一秒钟只有100多个并发请求,系统处理没有任何压力,一切风平浪静,到了某个抢购活动时间,系统并发访问了剧增,比如达到了每秒5000个并发请求,而我们的系统每秒只能处理2000个请求,那么由于流量太大,我们的系统、数据库可能就会崩溃。这时如果使用MQ进行流量削峰,将用户的大量消息直接放到MQ里面,然后我们的系统去按自己的最大消费能力去消费这些消息,就可以保证系统的稳定,只是可能要跟进业务逻辑,给用户返回特定页面或者稍后通过其他方式通知其结果。起到一个缓冲的作用
  17. spring的理解,ioc和aop的实现机制,动态代理,依赖注入DI,
  18. 为什么没有实现接口 jdk proxy不可以动态的创建代理对象? 单继承
  19. spring怎么解决依赖注入的问题
  20. 事务失效的原因?
  21. spring的启动流程:3大步!bean的生命周期!mvc的作用,分层?
  22. springboot主要就是自动装配,自动装配的原理,
  23. mybatis相比jdbc的优点!关系映射,手动做连接的打开关闭,与spring集成;jdbc连接数据库的步骤;mybatis的#与$的区别;
  24. bean的三种注入方式{或者说依赖注入的三种方式/依赖注入与依赖管理配置有什么区别?};工厂模式简介

1.spring

1.spring的理解核心/重点

Spring 框架为现代基于 java 的企业应用程序提供了一个全面的编程和配置模型——适用于任何类型的部署平台。

  • ioc:spring通过ioc(控制反转)实现了对象的创建、对象之间的依赖关系管理动态地为一个对象提供所需的另一个对象;对于spring来说,ioc就是一个大容器,负责对象创建,配置,管理
  • aop:面向切面编程,允许开发者定义横切关注点,例如:自动填充,是独立于业务逻辑的代码。切面=切入点+通知|aop将这些重点关注点模块化,可用性,可维护性
  • 事务管理
  • mvc框架:一个基于servlet api构建的web架构,模型视图控制器,他灵活的支持url到页面控制器的映射,以及多种视图技术

2.ioc与aop的介绍

ioc要答到依赖注入 & 反射,aop要答到核心业务与周边功能 & 动态代理 要是说有哪些组成,就是切面=切点+通知

例子:使用ioc管理service层和daomapper层的依赖关系,aop去将横切关注点切到业务逻辑中,实现日志等横切功能

3.Spring 的aop介绍

自定义切面类

代码语言:javascript
代码运行次数:0
运行
复制
 /**
  * 自定义切面类
  * 切面=通知+切入点
  * 是切面就加@aspect
  */
 @Component
 @Slf4j
 @Aspect
 public class AutoFillAspect {
     // 切入点
     // pointCut指的是拦截哪些方法
     // com.sky.mapper.*.*(..) *.* :所有的类所有的方法 ..指的是匹配所有参数
     // execution(* 这个*没有别的意思
     // @annotation(com.sky.annotation.AutoFill) 拦截有这个注释的
     @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
     public void autoFillPointCut(){}
 
     // 通知:什么时候拦截
     /**
      * 自定义前置通知,在通知中,进行公共字段的复制
      */
     @Before("autoFillPointCut()") // 自定义切点表达式
     public void autoFill(JoinPoint joinPoint){
         System.out.println("开始进行公共字段自动填充...");
         // 1.获得被拦截的方法对应的数据库操作类型
         // 获得signature 强转为方法
         MethodSignature signature = (MethodSignature) joinPoint.getSignature();
         // signature中得到注解
         AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
         // 得到注解的值
         OperationType operationType = autoFill.value();
         // 2.得到相应的方法的参数 --> 实体对象
         Object[] args = joinPoint.getArgs();
         // 保险操作
         if (args==null || args.length==0){
             return;
         }
         // 直接得到args,**确保实体类是第一个参数**
         Object entity = args[0];
 
         // 3.准备数据
         LocalDateTime now = LocalDateTime.now();
         Long id = BaseContext.getCurrentId();
         // 4.根据不同方法,为对应的属性通过反射进行赋值
         if (operationType==OperationType.INSERT){
             try {
                 Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                 Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                 Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                 Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                 setCreateTime.invoke(entity, now);
                 setUpdateTime.invoke(entity, now);
                 setCreateUser.invoke(entity, id);
                 setUpdateUser.invoke(entity, id);
             } catch (Exception e) {
                 e.printStackTrace();
             }
         } else if (operationType==OperationType.UPDATE){
             try {
                 Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                 Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                 setUpdateTime.invoke(entity, now);
                 setUpdateUser.invoke(entity, id);
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
     }
 }

4.ioc和aop是通过什么机制实现的?

1.ioc实现机制:

  • 反射:ioc容器使用反射机制动态的加载类、创建对象实例及调用对象方法
  • 依赖注入:ioc的核心概念是依赖注入,用来管理组件的依赖关系 | 构造函数注入、属性注入、方法注入
  • 设计模式-工厂模式:ioc容器采用工厂模式来管理对象的创建和生命周期;容器负责实例化bean以及管理他们的生命周期
  • 容器实现:ioc容器是实现ioc的核心,通常使用beanfactory或applicationcontext来管理bean

2.aop实现机制

有两种动态代理:基于jdk \基于cglib

5.怎么理解spring ioc?

根据配置加载并实例化相关bean,保存到ioc容器中

6.依赖倒置、依赖注入、控制反转分别是指什么?

依赖注入是一种编码方式,不直接在类中new依赖类的对象,而是在外面完成依赖类的对象创建,通过属性注入、set注入、构造函数注入等完成依赖关系的设置 依赖倒置:高层模块不依赖低层模块,他们共同依赖同一个抽象,抽象不要依赖具体实现的细节,具体实现细节依赖抽象

7.如果让你设计一个springioc,你觉得会从哪些方面考虑这个设计?

  • bean的生命周期管理机制:工厂模式和单例模式
  • 依赖注入:xml配置文件&通过反射
  • bean的作用域:需要支持多种bean的作用域:单例、原型、会话、请求,用map来存储不同作用域bean的实例
  • aop功能:动态代理
  • 异常处理:try-catch
  • 配置文件加载:java配置类需要支持从不同的配置文件中加载bean相关信息

8.aop主要想解决什么问题?

非核心功能的整合,面向对象思维的一个补充

9.spring aop | jdk proxy的底层 | 为什么使用jdk proxy动态创建代理对象必须要被代理的类实现接口 了解吗?

动态代理

因为Java是单继承的,而代理类又必须继承自Proxy类,所以通过jdk代理的类必须实现接口。

10.动态代理是什么?

  • 基于jdk proxy的代理:核心是jdk动态代理会创建一个实现相同接口的代理类,然后在运行时动态的生成该类的实例。每一个动态代理类都要实现invocationhandler接口,通过代理对象调用一个方法,会被转发为invocationhandler接口的invoke()调用
  • cglib的代理运行时动态的生成目标类的子类

11.动态代理和静态代理的区别

12.aop实现有哪些注解?

代码语言:javascript
代码运行次数:0
运行
复制
 /**
  * 自定义切面类
  * 切面=通知+切入点
  * 是切面就加@aspect
  */
 @Component
 @Slf4j
 @Aspect
 public class AutoFillAspect {
     // 切入点
     // pointCut指的是拦截哪些方法
     // com.sky.mapper.*.*(..) *.* :所有的类所有的方法 ..指的是匹配所有参数
     // execution(* 这个*没有别的意思
     // @annotation(com.sky.annotation.AutoFill) 拦截有这个注释的
     @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
     public void autoFillPointCut(){}
 
     // 通知:什么时候拦截
     /**
      * 自定义前置通知,在通知中,进行公共字段的复制
      */
     // 自定义切点表达式/自定义切点的方法
     @Before("autoFillPointCut()") 
     public void autoFill(JoinPoint joinPoint){
         System.out.println("开始进行公共字段自动填充...");
         // 1.获得被拦截的方法对应的数据库操作类型
         // 获得signature 强转为方法
         MethodSignature signature = (MethodSignature) joinPoint.getSignature();
         // signature中得到注解
         AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
         // 得到注解的值
         OperationType operationType = autoFill.value();
         // 2.得到相应的方法的参数 --> 实体对象
         Object[] args = joinPoint.getArgs();
         // 保险操作
         if (args==null || args.length==0){
             return;
         }
         // 直接得到args,**确保实体类是第一个参数**
         Object entity = args[0];
 
         // 3.准备数据
         LocalDateTime now = LocalDateTime.now();
         Long id = BaseContext.getCurrentId();
         // 4.根据不同方法,为对应的属性通过反射进行赋值
         if (operationType==OperationType.INSERT){
             try {
                 Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                 Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                 Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                 Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                 setCreateTime.invoke(entity, now);
                 setUpdateTime.invoke(entity, now);
                 setCreateUser.invoke(entity, id);
                 setUpdateUser.invoke(entity, id);
             } catch (Exception e) {
                 e.printStackTrace();
             }
         } else if (operationType==OperationType.UPDATE){
             try {
                 Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                 Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                 setUpdateTime.invoke(entity, now);
                 setUpdateUser.invoke(entity, id);
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
     }
 }

切面=切点+通知

  • @aspect:用于定义切面,标注在切面类上
  • @pointcut:用于定义切点,标注在方法上,用于指定连接点
  • @advice:通知,也可以替换@before、@after、@around方法执行前后都执行通知

13.脱口而出什么是反射?有哪些应用场景?

反射的特性/可以做到什么:

  • 运行时类信息的访问
  • 动态地创建对象:调Class类的newInstance()/Constructor对象的newInsatnce()
  • 动态的方法调用:Method类的invoke(对象实例,参数)
  • 访问修改字段值:Field类的get()/set()

用到的地方:

1.ioc:

用反射实现了依赖注入。开发者会写xml配置文件/注解{@autowire}来表明依赖关系,当spring启动时,扫描到这些注解/配置文件,他就会通过反射实例化bean,并完成依赖关系的装配

2.动态代理的实现: 对现有的类方法进行加强,就会用到反射结合动态代理的技术

典例:aop

反射机制促进了松耦合高内聚

14.重点spring是如何解决循环依赖的:有一个博客园讲的很好?

spring只解决了通过set方法进行依赖注入且是在单例模式下产生的依赖注入问题

通过三级缓存,核心是一个通过构造函数先实例化,放入缓存,然后再属性注入:

当 A、B 两个类发生循环引用时,在 A 完成实例化后,就使用实例化后的对象放到二级缓存去创建一个对象工厂,并添加到三级缓存中 如果 A 被 AOP 代理,那么,通过这个工厂获取到的就是 A 代理后的对象,如果 A 没有被 AOP 代理,那么,这个工厂获取到的就是 A 实例化的对象。

当 A 进行属性注入时,会去创建 B,同时,B 又依赖了 A,所以,创建 B 的同时又会去调用 getBean(a) 来获取需要的依赖,此时的 getBean(a) 会从缓存中获取,工厂起到一个提前暴露bean的作用,第一步,先获取到三级缓存中的工厂;第二步,调用工厂的getObject方法来获取到对应的对象,得到这个对象后将其注入到 B 中。紧接着 B 会走完它的生命周期流程,包括初始化、后置处理器等。当 B 创建完后,会将 B 再注入到 A 中,此时, A 再完成它的整个生命周期。

通过上述流程,可以看出 bean 都是需要先被实例化才可以的,所以,这也就是为什么构造器依赖可能会失败的原因。

例如,Bean A 的构造器依赖 B,而实例化 A 需要先调用 A 的构造函数,发现依赖 B,那么,需要再去初始化 B,但是,B 也依赖 A,不管 B 是通过构造器注入还是 setter 注入,此时,由于 A 没有被实例化,没有放入三级缓存,所以, B 无法被初始化,所以,spring 会直接报错。反之,如果 A 通过 setter 注入的话,那么,则可以通过构造函数先实例化,放入缓存,然后再填充属性,这样的话不管 B 是通过 setter 还是构造器注入 A,都能在缓存中获取到,于是可以初始化。

15.spring三级缓存的数据结构是什么?

三级都是map数据结构

一级缓存singletonObjects|单例池:存放已经完全实例化的bean

二级缓存earlySingletonObjects|早期曝光对象:存放初始化完成了,但是可能还没有属性还没有赋值的bean

三级缓存singletonFactories|早期曝光对象工厂:存放的是 ObjectFactory 的匿名内部类实例,调用 ObjectFactory.getObject() 最终会调用 getEarlyBeanReference 方法,该方法可以获取提前暴露的单例 Bean 引用。解决循环依赖的问题。

16.spring框架中都用到了哪些设计模式?

17.spring中常用的注解

@autowire:自动装配bean @component:将bean注册到ioc容器中,并实例化 @configuration:means spring的配置类;配置类可以有@bean的方法,用于定义和配置bean,作为全局配置 @bean:当一个方法被@bean以后,spring 会将该方法的返回值作为一个bean,并添加到ioc容器 @repository:数据访问层组件| 同@mapper

18.重点事务失效的情况?

  • 方法是非公开的,调事物的方法不是public的
  • 有异常没捕获到
  • 一个非事务方法调用了事务方法,却没有显示的获得代理对象AopContext.currentProxy(),[this关键字进行的不会通过代理对象,使用this关键字的调用是在目标对象内部发生的,因此是直接调用,不经过代理对象]

19.spring事务,使用this调用是否会生效?

不能生效 上一题图片就是说的这个

20.spring启动流程

1.初始化spring容器

  • 实例化bean工厂用于生成bean对象
  • 实例化BeanDefinitionReader注解配置读取器用于对特定注解(如@Service、@Repository)的类进行读取转化成 BeanDefinition 对象,(BeanDefinition 是 Spring 中极其重要的一个概念,它存储了 bean 对象的所有特征信息,如是否单例,是否懒加载,factoryBeanName, bean的类,作用域,初始化方法,销毁方法,依赖关系 等)我感觉有一点像class对象
  • 实例化ClassPathBeanDefinitionScanner路径扫描器用于对指定的包目录进行扫描查找 bean 对象

2.将配置类的beanDefinition注册到容器中

  • 解析用户传入的 Spring 配置类,解析成一个 BeanDefinition 然后注册到容器中

3.调用refresh方法刷新容器

  • 真正的创建并实例化bean是在这里

21.bean的生命周期

所谓的生命周期就是:对象从创建开始到最终销毁的整个过程

图片有错误应该initializingBean的调用和初始化同属一个环节初始化:在属性赋值和BeanPostProcessor前置处理之后,容器会调用Bean的初始化方法,这个初始化方法可以是自定义的初始化方法(通过@Bean(init-method)或@PostConstruct注解声明)或者实现了InitializingBean接口的afterPropertiesSet()方法。

如果你还想在初始化前初始化后添加代码,可以加入“Bean后处理器”需要编写一个类实现BeanPostproccessor接口并重写里面的postProcessBeforeInitialization()和postProcessAfterInitialization()方法

aware的接口需要看执行了什么方法决定他在哪里?Aware相关的接口包括:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware ①当Bean实现了BeanNameAware,Spring会将Bean的名字传递给Bean。 ②当Bean实现了BeanClassLoaderAware,Spring会将加载该Bean的类加载器传递给Bean。 ③当Bean实现了BeanFactoryAware,Spring会将Bean工厂对象传递给Bean。

调用initializingBean接口的afterPropertiesSet()

调用disposableBean的destroy()

Bean生命周期流程总结

  1. 调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()方法,进行Bean实例化前置处理
  2. 调用构造器实例化Bean
  3. populateBean()
  4. 调用InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法,进行Bean实例化后处理
  5. 为Bean的属性赋值
  6. 调用InstantiationAwareBeanPostProcessor.postProcessPropertyValues()方法,进行Bean属性赋值后置处理
  7. initializeBean()
  8. 调用BeanPostProcessor.postProcessBeforeInitialization()方法,进行Bean的初始化前置处理
  9. 执行Bean的初始化方法,如init-methodxml配置文件中、@PostConstruct提交监听消息队列消息的任务等实时性要求很高的方法、或者实现InitializingBean接口的afterPropertiesSet()等方式定义的初始化方法
  10. 调用BeanPostProcessor.postProcessAfterInitialization()方法,进行Bean的初始化后置处理
  11. 注册销毁方法,如destroy-method、@PreDestroy、DisposableBean的destroy()对应上面的这两个接口都只有一个方法等方式定义的销毁方法,将这些销毁逻辑适配成一个DisposableBeanAdapter,注册到容器中,在容器关闭时调用。(销毁方法对于Prototype类型的Bean不生效)

22.bean是否单例

默认单例,如果是多例,在bean的定义中通过设置scope="prototype"中文名原型

23.bean的单例和非单例生命周期是否一样

单例bean的生命周期完全交由ioc容器管理;原型的bean就是创建好以后,容器不在管理

24.bean的作用域有哪些?

单例 | 原型 | request | session | application | websocket

25.spring容器中存的是什么?

bean对象

26.spring中,在bean加载/销毁前后,如果想实现某些逻辑,可以怎么做

初始化前后,实现后处理器接口PostProcessor,重写before() & after()

实现initializingbean接口,实现afterPropertiesSet()

disposableBean接口的destory()

27.注解注入和xml注入{意思是注解配置或者xml配置}最终得到了相同的效果,他们底层是?

都是会有一个beanDefinitionReader去读取特定的东西,如果是xml就是配置文件,如果是bean就是注解,读完以后解析成beandefinition注册到容器里,方便之后的实例化初始化。

28.spring给我们提供了很多扩展点,这些有了解吗

postProcessor:在初始化之前、之后,添加额外的代码

PropertySource:定义不同的属性源数据源

SpringMVC的HandlerInterceptor:用于拦截处理请求,可以在处理请求前、中、后执行特定逻辑,how?

mvcconfig extend MessageConverters/implements mvcconfigurer

拦截器继承

代码语言:javascript
代码运行次数:0
运行
复制
 /**
  * jwt令牌校验的拦截器
  */
 @Component
 @Slf4j
 public class JwtTokenUserInterceptor implements HandlerInterceptor {
 
     @Autowired
     private JwtProperties jwtProperties;
 
     /**
      * 校验jwt
      *
      * @param request
      * @param response
      * @param handler
      * @return
      * @throws Exception
      */
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         //判断当前拦截到的是Controller的方法还是其他资源
         if (!(handler instanceof HandlerMethod)) {
             //当前拦截到的不是动态方法,直接放行
             return true;
         }
 
         //1、从请求头中获取令牌
         String token = request.getHeader(jwtProperties.getUserTokenName());
 //        System.out.println("jwtProperties.getAdminTokenName() = " + jwtProperties.getAdminTokenName());
         // 名字就是token
         //2、校验令牌
         try {
             log.info("jwt校验:{}", token);
             Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token); // 解析令牌
             Long userId = Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString());
             log.info("当前用户id:{}", userId);
             // threadlocal当同一个请求(就是同一个线程),可以用它存当前用户的id
             BaseContext.setCurrentId(userId);
             //3、通过,放行
             return true;
         } catch (Exception ex) {
             //4、不通过,响应401状态码
             response.setStatus(401);
             return false;
         }
     }
 }

29.MVC分层介绍一下?

他是model - view - controller的缩写,一种软件设计典范,将业务逻辑model,界面分离,这样组织代码

model(模型:业务bean:service、daomapper;数据承载的bean:pojo、dto、vo);view(视图:jsp);controller(控制:servlet)

流程步骤: 1.用户通过view界面向服务端发请求 2.Controller层接受请求数据,并调用对应的业务逻辑方法Model 3.业务处理完毕,返回更新后的数据给Controller层承上启下的作用 4.controller层找到相应的view界面,jsp渲染页面,响应给前端更新后的页面

30.spring MVC的处理流程?

1.客户端向服务器发送请求,被dispatcherServlet接收到 2.dispatcherServlet调handlermapping解析url,得到请求资源标识符uri,判断请求对应的handler映射;handlermapping:主要用来解析请求,解析出控制器 3.如果存在,执行:获得handler的所有相关对象(包括他的拦截器),以执行链的形式返回 4.根据handler,选择合适的handleradapter。{handleradapter:HandlerAdapter主要是{不同的调度方法}调度Controller来处理业务逻辑等,相关类有6个。} 5.成功获得HandlerAdapter,此时将开始执行拦截器的preHandler(…)方法【正向】 6.提取request的数据,执行controller里面的方法 7.Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象。 8.拦截器的posthandler() 逆向拦截 9.根据返回的ModelAndView选择一个适合的ViewResolver进行视图解析,根据Model和View,来渲染视图. 10.aftercompletion() 逆向拦截 11.渲染结果返回给前端

请求-->dispatcherServlet-mapping->handler以执行链的形式-handlerAdapter->modelandview-viewresolver->返回前端

handler也是controller

31.handlermapping和handleradapter的区别

handlermapping是根据url/请求将映射到对应处理器controller确定对应的处理器

handleradapter:负责调度controlller处理业务

32.bean注入的方式有哪些?/依赖注入是什么意思

1.构造器注入{离开spring常用这个,一旦初始化没法改};2.set方法注入;{前两个是我们常用的没有spring的时候手动注入的方法}3.属性注入{最常用}@autowired适用于三种方式,加在构造器上是构造器注入,创建的时候就给他注入,set方法上是set注入{调用set的时候注入},直接在类上是属性注入,简单!

依赖注入:不会再类里面去创建依赖类的对象;通过以上三种方法将在外部创建好的依赖类注入到类中

注解的底层都是反射

33.工厂模式

该模式用于封装和管理对象的创建,是一种创建型模式。

   1.简单工厂类:SimpleFactory

简单工厂类(SimpleFactory):只包含创建产品的静态方法。 抽象产品父类(Product):简单工厂类中生产的产品接口,声明了产品的抽象方法。 具体产品子类(ProductA 或ProductB extends Product):具体产品的实现

类FruitFactory 就是一个简单的工厂,将创建对象(苹果或香蕉)的工作单独负责下来,使得外界调用统一的方法 createFruit()即可完成不同对象创建(生产苹果或香蕉)。

2.工厂方法模式

是对简单工厂模式的改进,它去掉了简单工厂模式中工厂方法(例如,createFruit()这个方法)的静态属性{静态方法不可以被重写},使得该方法能够被子类继承,将简单工厂模式中在静态工厂方法中集中创建对象的操作转移到各子类中完成,从而减轻了父类方法的负担。

抽象工厂类(AbstractFactory):工厂方法模式的核心,是具体工厂类必须实现的接口或者必须继承的抽象父类。 具体工厂类(ConcreteFactoryA 或者 ConcreteFactoryB):由具体的类来实现,用于创建工厂类的对象,它必须实现抽象工厂的方法。 抽象产品类(Product):具体产品继承的抽象父类或者实现的接口,定义了产品类的方法。 具体产品类(ProductA 或ProductB):具体工厂类产生的对象就是具体产品类的对象。

3.抽象工厂模式

  抽象工厂模式又是工厂方法模式的升级版本。它的主要思想:提供了一个创建一系列相关或者相互依赖对象的接口。

  它和工厂方法模式的区别:抽象工厂模式有创建多个不同类型的对象的方法,针对的是有多个产品(称为产品族)的创建模式(苹果厂生产苹果、苹果脯;香蕉厂生产香蕉、香蕉干);而工厂方法针对的只是一种产品的创建模式(苹果厂生产苹果;香蕉厂生产香蕉)。抽象工厂模式中的抽象工厂接口里有多个工厂方法。

抽象工厂模式包括以下主要角色:

   抽象工厂类(AbstractFactory):模式的核心,是具体工厂类必须实现的接口或者必须继承的抽象父类。 具体工厂类(ConcreteFactoryA 或者 ConcreteFactoryB):由具体的类来实现,用于创建工厂类的对象,它必须实现抽象工厂的方法。 抽象产品(AbstractProductA和AbstractProductB):具体产品继承的父类或者实现的接口,在Java中由抽象类或者接口实现。 具体产品(ProductA或ProductB):具体工厂类产生的对象就是具体产品类的对象。每一个抽象产品都可以有多个具体产品实现类或者继承子类,称为产品族。

2.springBoot

1.为什么使用springboot?

简化开发:开箱即用的组件template,数据库用的,使得开发人员专注于业务逻辑的实现

  • 自动装配:根据项目中的依赖关系和约定俗成的规则配置应用程序jar包的导入{可以根据项目的环境和依赖,配置应用程序,如果项目引入了mvc依赖,springboot会自动配置一个基本的web应用程序上下文}

快速启动:内嵌tomcat,无需额外部署

2.springboot比spring好在哪里?

自动装配,快速启动

3.springboot用到哪些设计模式?

适配器模式:mvc中用到了对于不同类型的controller适配器模式,handlerAdapter是同一的接口,里面还定义了不同的适配器类

4.理解springboot中的约定大于配置?

1.约定优于配置:约定了项目结构,约定了bean的命名规范,减少开发者做出的决策,保证团队开发的一致性 2.自动化配置:可以根据项目的环境和依赖,配置应用程序,如果项目引入了mvc依赖,springboot会自动配置一个基本的web应用程序上下文 3.起步依赖:快速搭建框架

5.springboot的项目结构是怎么样的?

中间的service层和manager层可以简单的混为一谈

6.大重点springboot的自动装配原理

原理是根据条件化配置和@enableAutoConfiguration注解实现的,通过依赖自动配置应用程序的上下文和功能

介绍理解:

那就是在我们的 HelloService 中通过 @Autowired 注入了一个 RedisTemplate 类,但是我们的代码中并没有写过这个类,也没有使用类似于@RestController,@Service 这样的注解将 RedisTemplate 注入到 Spring IoC 容器中,那为什么我们就可以通过 @Autowired 注解从 IoC 容器中获取到 RedisTemplate 这个类呢?这里就是常说的自动装配的功能了。

其中本质上自动装配的原理很简单,本质上都需要实现一个配置类,只不过这个配置类是官方帮我们创建好了,再加了一些条件类注解,让对应的实例化只发生在类路径存在某些类的时候才会触发。

启动类上面有一个 @SpringBootApplication 注解 -->@EnableAutoConfiguration 注解 --> @Import({AutoConfigurationImportSelector.class}),导入了一个 AutoConfigurationImportSelector 类,该类间接实现了 ImportSelector 接口,实现了一个 String[] selectImports(AnnotationMetadata importingClassMetadata) 方法,这个方法的返回值是一个字符串数组,对应的是一系列主要注入到 Spring IoC 容器中的类名当在 @Import 中导入一个 ImportSelector 的实现类之后,会把该实现类中返回的 Class 名称都装载到 IoC 容器中。一旦被装载到 IoC 容器中过后,我们在后续就可以通过 @Autowired 来进行使用了。

启动类上面有一个 @SpringBootApplication 注解 -->@EnableAutoConfiguration 注解 --> @Import({AutoConfigurationImportSelector.class}) -->selectImports()返回值是string数组,为一系列主要注入到 Spring IoC 容器中的类名 -->getAutoConfigurationEntry() -->getCandidateConfigurations() --> ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).forEach(configurations::add); String location = String.format("META-INF/spring/%s.imports", annotation.getName());

其中的 ImportCandidates.load 方法我们可以看到是通过加载 路径{src/main/resources/meta-inf/spring.factories}String location = String.format("META-INF/spring/%s.imports", annotation.getName()); 对应路径下的 org.springframework.boot.autoconfigure.EnableAutoConfiguration 文件,其中就包含了很多自动装配的配置类,并且这些配置类中就有我们需要的很多bean。在配置类上面有一个 @ConditionalOnClass({RedisOperations.class}) 注解,表示只要在类路径上有 RedisOperations.class 这个类的时候才会进行实例化。这也就是为什么只要我们添加了依赖,就可以自动装配的原因。

7.说几个启动器?

8.写过springboot的starter吗?

1.创建maven项目,添加相关的依赖 2.在main/resources/meta-inf/spring.factories添加一个自定义的配置类,并且创建该类里面有一个bean,有一个配置属性类,加上@configuration的注解和@EnableConfigurationProperties用于启用我们自定义的配置属性类 3.创建配置属性类:加上@ConfigurationProperties,绑定配置文件中的属性 4.在application.yml中配置属性

9.springboot中有哪些注解?

10.spring怎么开启事务?

3.mybatis

jdbc是什么:Java DataBase Connectivity(Java语言连接数据库)

1.与传统的jdbc相比,mybatis的优点?

不用像jdbc那样打开关闭连接;提供对象字段映射,提供对象关系映射这里其实就是在定义数据库字段和Java属性之间的映射关系!重点:一对多;与spring集成

2.jdbc连接数据库的步骤?

加载数据库驱动:不一样的数据库的驱动不一样 建立数据库连接连接:url name password 创建statement对象 executeupdate/executequery 处理查询结果 关闭连接

3.如果用原生mybatis去查询,该怎么写?

配置mybatis

代码语言:javascript
代码运行次数:0
运行
复制
 mybatis:
   #mapper配置文件
   mapper-locations: classpath:mapper/*.xml
   # 简化类型映射,在MyBatis的XML配置文件中,类型映射通常需要指定完整的类名{全限定名},用这个只用类名
   type-aliases-package: com.sky.entity 
   configuration:
     #开启驼峰命名!!! 重要
     map-underscore-to-camel-case: true

创建实体类 编写mapper接口:创建数据库操作方法 编写sql映射文件{xml}:定义sql语句和映射关系 编写具体sql语句 调用查询方法

4.mybatis里的"#"和"$"的区别?

"#":防sql注入,会采用预编译的方式 "$":简单的拼接,不能防止sql注入的安全问题

5.MybatisPlus和Mybatis的区别?

简化crud操作,自动生成mapper接口以及xml映射文件{即编写sql映射文件xml},通用方法的封装:排序、分页查询

6.mybatis运用了哪些常见的设计模式?

适配器 mybatis对jdbc不同数据源的适配{我们在springboot中会配置datasource}

4.springcloud相关

1.分布式是什么意思

分布式系统是独立计算机的集合,对于用户来说访问分布式系统就像访问一个单个系统

目的是利用更多的机器处理更多的数据{业务模块放在单机放不下}

2.rpc & http

两台机相互调用的方式http&rpc

3.进程之间的通信方式

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • spring专题
    • *.自己的认识理解
    • 1.spring
      • 1.spring的理解核心/重点
      • 2.ioc与aop的介绍
      • 3.Spring 的aop介绍
      • 4.ioc和aop是通过什么机制实现的?
      • 5.怎么理解spring ioc?
      • 6.依赖倒置、依赖注入、控制反转分别是指什么?
      • 7.如果让你设计一个springioc,你觉得会从哪些方面考虑这个设计?
      • 8.aop主要想解决什么问题?
      • 9.spring aop | jdk proxy的底层 | 为什么使用jdk proxy动态创建代理对象必须要被代理的类实现接口 了解吗?
      • 10.动态代理是什么?
      • 11.动态代理和静态代理的区别
      • 12.aop实现有哪些注解?
      • 13.脱口而出什么是反射?有哪些应用场景?
      • 14.重点spring是如何解决循环依赖的:有一个博客园讲的很好?
      • 15.spring三级缓存的数据结构是什么?
      • 16.spring框架中都用到了哪些设计模式?
      • 17.spring中常用的注解
      • 18.重点事务失效的情况?
      • 19.spring事务,使用this调用是否会生效?
      • 20.spring启动流程
      • 21.bean的生命周期
      • 22.bean是否单例
      • 23.bean的单例和非单例生命周期是否一样
      • 24.bean的作用域有哪些?
      • 25.spring容器中存的是什么?
      • 26.spring中,在bean加载/销毁前后,如果想实现某些逻辑,可以怎么做
      • 27.注解注入和xml注入{意思是注解配置或者xml配置}最终得到了相同的效果,他们底层是?
      • 28.spring给我们提供了很多扩展点,这些有了解吗
      • 29.MVC分层介绍一下?
      • 30.spring MVC的处理流程?
      • 31.handlermapping和handleradapter的区别
      • 32.bean注入的方式有哪些?/依赖注入是什么意思
      • 33.工厂模式
    • 2.springBoot
      • 1.为什么使用springboot?
      • 2.springboot比spring好在哪里?
      • 3.springboot用到哪些设计模式?
      • 4.理解springboot中的约定大于配置?
      • 5.springboot的项目结构是怎么样的?
      • 6.大重点springboot的自动装配原理
      • 7.说几个启动器?
      • 8.写过springboot的starter吗?
      • 9.springboot中有哪些注解?
      • 10.spring怎么开启事务?
    • 3.mybatis
      • 1.与传统的jdbc相比,mybatis的优点?
      • 2.jdbc连接数据库的步骤?
      • 3.如果用原生mybatis去查询,该怎么写?
      • 4.mybatis里的"#"和"$"的区别?
      • 5.MybatisPlus和Mybatis的区别?
      • 6.mybatis运用了哪些常见的设计模式?
    • 4.springcloud相关
      • 1.分布式是什么意思
      • 2.rpc & http
      • 3.进程之间的通信方式
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档