wordpress图片托管,seo挖关键词,张家界简单的网站建设,贵阳网站建设推广公司#x1f468;#x1f393;作者简介#xff1a;一位大四、研0学生#xff0c;正在努力准备大四暑假的实习 #x1f30c;上期文章#xff1a;Java后端面试#xff1a;MySQL面试篇#xff08;底层事务、SQL调优#xff09; #x1f4da;订阅专栏#xff1a;Java后端面… 作者简介一位大四、研0学生正在努力准备大四暑假的实习 上期文章Java后端面试MySQL面试篇底层事务、SQL调优 订阅专栏Java后端面试 希望文章对你们有所帮助 框架篇高频面试Spring、SpringMVC、SpringBoot、MyBatis Spring单例bean是线程安全的吗AOP相关面试题Spring事务失效的场景bean的生命周期bean的循环依赖循环引用 SpringMVC-执行流程视图阶段JSP前后端分离阶段 SpringBoot-自动装配原理Spring框架常见注解Spring、SpringMVC、SpringBootMyBatis执行流程延迟加载使用及原理一级、二级缓存 Spring
单例bean是线程安全的吗
通过Scope注解可以设置bean是单例的还是多例的默认是单例的。 而单例bean线程不安全。 Spring的bean中都是注入无状态的对象也就是说无法修改不会有线程安全问题。 但是如果在bean中定义了可修改的成员变量是要考虑线程安全问题的当然可以使用多例模式或者加锁来解决。 AOP相关面试题
AOP很重要在Spring也算是一个难点吧但是像IOC、AOP这种Spring核心不会的话说不过去这里就简单说说。
1、何为AOP AOP称为面向切面编程用于将那些与业务无关但却对多个对象产生影响的公共行为和逻辑抽取并封装为一个可重用的模块这个模块被称为切面(Aspect)减少系统中的重复代码降低了模块间的耦合度同时提高了系统的可维护性。
2、常见的AOP使用场景 1、记录操作日志自行学习Aspect、切点、环绕通知 2、缓存处理 3、Spring中内置的事务处理 3、Spring中的事务是如何实现的一定要提到AOP Spring支持编程式事务管理和声明式事务管理两种方式主要使用的是声明式事务。 声明式事务管理是建立在AOP上的。本质是通过AOP功能对方法的前后进行拦截将事务处理的功能编织到拦截的方法中也就是在目标方法开始之前加入一个事务在执行目标方法之后执行情况提交或者回滚事务。Transactional注解就是这样的其底层的实现开启事务、提交/回滚事务就是AOP追加的 Spring事务失效的场景
这种问题能够体现出我们对Spring框架的深入理解以及复杂业务的编码经验。
有三种非常常见的事务失效的情况
1、异常捕获处理 对于转账的业务我们会给整个业务增加Transactional注解如果中途发生了异常我们就会回滚。 但是如果这个业务方法中使用了try…catch中途发生异常以后Transactional将会失效。 原因事务通知只有捉到了目标抛出的异常才能进行后续的回滚处理如果目标自己处理掉异常事务通知将会无法知悉 解决方法在catch块中添加throw new RuntimeException(E)将异常给抛出不要处理。 2、抛出检查异常 依旧是转账业务这次不用try…catch而是在方法体使用throws来抛出检查异常类似FileNotFoundException这种非运行异常这种情况也会导致事务失效。 原因Spring默认只会回滚非检查异常。 解决方法配置rollbackFor属性Transactional(rollbackForException.class)这样事务回滚就不只是针对运行时异常了。 3、非public方法 如果没有用public修饰方法就会导致事务失效。 原因Spring为方法创建代理、添加事务通知前提条件都是该方法是public的 解决改为public方法 bean的生命周期
这个在业务开发过程中重要吗可能真的不太重要这就是个纯八股。但是面试官还是挺喜欢问的可能是掌握生命周期能显得你更了解框架方便调试和解决问题。 1、通过BeanDefinition获取bean的定义信息 2、调用构造函数实例化bean 3、bean的依赖注入 4、处理Aware接口 5、Bean的后置处理器BeanPostProcessor-前置 6、初始化方法 7、Bean的后置处理器BeanPostProcessor-后置 8、销毁bean bean的循环依赖循环引用
如果是两个bean成员变量分别用对方来注入这就是循环依赖。 这种方式是会出现死循环的对于A先实例化bean再初始化初始化的过程中需要设置b属性而b是B类型的对象可是容器中不存在B对象就会去实例化B的bean对象再去初始化初始化的时候需要设置a属性a是A类型的对象但是容器中也不存在A对象最后造成了死循环。
Spring框架已经帮助我们解决了大部分的循环依赖问题通过的是三级缓存 一级缓存单力池缓存已经经历了完整声明周期即已经初始化完成的bean对象 二级缓存缓存早期的bean对象生命周期还没走完 三级缓存缓存的是对象工厂ObjectFactory用来创建某个对象的 整体流程非常的复杂大家可以自行去看相关资料来理解写起来很麻烦但要记住一级缓存二级缓存可以解决大部分的循环依赖问题但是解决不了存在代理对象时的问题而一级二级三级可以解决代理对象的循环依赖问题过程需要理解。
这些都是发生在初始化的时候而如果我们在声明周期的构造方法换发出现了循环依赖也就是注入的方式是用构造函数。解决是使用Lazy进行懒加载什么时候需要对象了再进行bean对象的创建就好了。
SpringMVC-执行流程
如果要问到SpringMVC那么执行流程可以说是非常重要的。 但是其实开发分为了两个阶段一个是视图阶段老旧的JSP等另外一个是前后端分离阶段接口开发异步现在我们都是用的前后端分离的开发但是视图阶段的开发也是面试可能会问到的很繁琐得记住。
视图阶段JSP 1、对于一个浏览器发起的请求视图阶段的执行流程如下 1、浏览器发起请求给前端控制器DispatcherServlet 2、查询handler前端控制器根据前端请求去处理器映射器HandlerMapping中查询对应的执行方法 3、返回处理器执行链因为对于一个请求除了要找到这个路径对应的类名.方法名还需要判断它是否会被拦截器拦截因此处理器映射器不是直接返回方法给前端控制器而是返回一个处理器执行链处理器执行链可以暂且理解成方法handler拦截器 4、请求执行handler处理器执行链不会被拦截那么前端控制器就要开始执行方法handler这个执行需要向处理器适配器去请求而不是直接到处理器中适配器模式用适配器有两个好处 1可以处理请求的参数 2处理返回值 5、处理器适配器向处理器请求 6、处理器将响应返回给处理器适配器这个响应就是ModelAndView 7、处理器适配器再将ModelAndView返回给前端控制器 8、前端控制器返回视图解析器ViewResolver这个视图解析器的作用是将逻辑视图解析为真正的视图View 9、视图解析器将真正的视图View返回给前端控制器 10、前端控制器将视图渲染 2、SpringMVC执行过程中重要的四个组件 1、前端控制器DispatcherServlet调度中心处理所有的请求 2、处理器映射器HandlerMapping通过路径查询方法handler返回处理器执行链 3、处理器适配器HandlerAdaptor执行handler、处理handler中的参数 4、视图解析器ViewResolver将逻辑视图ModelAndView解析为真正的视图View 前后端分离阶段
现在的开发不太一样没有ModelAndView了而是返回的Json数据流程将会简化为 这时候处理器Handler的执行是变化了 1、处理器Handler的方法上添加ResponseBody注解 2、底层会通过一个转化器HttpMessageConverter将返回结果转化为JSON格式响应给前端 SpringBoot-自动装配原理
这是SpringBoot最高频的面试题了也是框架的最核心思想。
我们的SpringBoot启动类中一定会有一个注解SpringBootApplication这个注解底层包含了三个部分 SpringBootConfiguration与Configuration相同用来声明当前是个配置类 ComponentScan组件扫描默认扫描当前引导类所在包及其子包 EnableAutoConfigurationSpringBoot实现自动化配置的核心注解 其中EnableAutoConfiguration是实现自动化配置的核心注解该注解底层通过Import来导入对应的配置选择器。 其内部就是读取该项目和该项目引用的jar包的classpath路径下META-INF/spring.factories文件中的所配置的类的全类名。在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中。 这个条件判断会有ConditionalOnClass这样的注解判断是否有对应的class文件字节码文件若有则加载该类把这个配置类中所有的Bean都放入Spring容器中使用。 Spring框架常见注解Spring、SpringMVC、SpringBoot
Spring的注解主要是用来进行bean的实例化以及依赖注入的SpringMVC的注解主要是用来处理请求和响应的而SpringBoot的注解尽量说一下跟自动装配有关系的被问到不要混淆着讲。 1、Spring注解
注解说明Componennt、Controller、Service、Repository使用在类上用于实例化beanAutowired在字段上根据类型依赖注入Qualifier结合Autowired一起使用用于根据名称进行依赖注入Scope标注Bean的作用返回单例or多例Configuration指定当前类是一个Spring配置类当创建容器时会从该类上加载注解ComponentScan用于指定Spring在初始化容器时要扫描的包Bean用在方法上标注该方法的返回值会存到Spring容器中Import该注解导入的类会被Spring加载到IOC容器中Aspect、Before、After、Around、Pointcut用于AOP切面、前置通知、后置通知、环绕通知、切入点表达式
2、SpringMVC注解
注解说明RequestMapping也有衍生的PostMapping、GetMapping等用于映射请求路径定义在类上或方法上用在类上则该类中的所有方法都是以该地址作为父路径的RequestBody接受http请求的json数据将json转化为java对象ResponseBody将controller方法返回的对象转化为json对象响应给客户端RequestParam指定请求参数的名称和数据库字段名不一致时使用PathViriable从请求路径下获取请求参数/user/{id}传递给方法的形式参数Restful风格RequestHeader获取指定的请求头数据RestControllerControllerResponseBody
3、SpringBoot注解
注解说明SpringBootConfiguration配置文件EnableAutoConfiguration打开自动配置ComponentScanSpring组件扫描
MyBatis
执行流程 1、读取MyBatis配置文件mybatis-config.xml加载运行环境数据库相关信息和mapper映射文件 2、构造会话工厂SqlSessionFactory会话工厂是全局唯一的 3、会话工厂创建SqlSession对象包含了执行SQL语句的所有方法每次操作都会创建出一个会话 4、Executor执行器是真正操作数据库的接口同时负责了查询缓存的维护 5、Executor接口的执行方法中有一个MappedStatement类型的参数封装了映射信息 6、输入参数的映射将java类型转化为数据库处理的类型 7、输出结果映射将数据库操作的结果映射成java类型 延迟加载使用及原理
1、延迟加载是需要用到数据的时候才会加载不需要的时候就不会加载。 2、MyBatis是支持延迟加载的但是默认是没有开启的。可以局部开启或者全局开启。 3、延迟加载的底层原理 1使用CGLIB创建目标对象的代理对象 2当调用方法的时候进入拦截器invoke方法发现目标方法是null值执行SQL查询 3获取数据后调用set方法设置属性值再继续查询目标方法就有值了 一级、二级缓存 一级缓存基于HashMap本地缓存其存储作用域为SqlSession当SqlSession进行flush或close之后该Session中的Cache就被清空默认开启 二级缓存基于namespace和mapper的作用域起作用的不依赖于SqlSession默认也是基于HashMap存储需要单独开启通过核心配置文件