java八股文之框架

1.Spring框架中的Bean是否线程安全的

Spring框架中的Bean默认是单例的,不是线程安全的。因为一般在Spring的bean的中都是注入无状态的对象,没有线程安全问题,如果在bean中定义了可修改的成员变量,是要考虑线程安全问题的,可以使用多例或者加锁来解决。

2.说一说AOP

  1. AOP指面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取公共模块复用,降低耦合
    2.AOP的使用场景有记录操作日志,缓存,spring实现的事务都是通过AOP实现的
    核心是:使用op中的环绕通知+切点表达式(找到要记录日志的方法),通过环绕通知的参数获取请求方法的参数(类、方法、注解、请求方式等),获取到这些参数以后,根据不同需要进行不同的处理。如:Spring的事务就是方法前后进行拦截,在执行方法之前开启事务,在执行完目标方法之后根据执行情况提交或者回滚。

3.事务失效的情况

  1. 异常捕获处理,自己处理了异常,没有抛出,解决:手动抛出
  2. 抛出异常为检查异常,Spring事务默认只会处理运行时异常,可以通过配置rollbackFor属性为Exception解决
  3. 非public方法导致的事务失效,改为public即可解决
  4. 当一个类内部的其他方法直接调用时,会发生事务失效情况。这是因为Spring AOP代理机制的原因,直接的方法调用不会经过代理对象,因此事务也不会启动。解决这个问题的一个办法是重构代码,使得事务方法能够被外部访问并由Spring容器来管理调用;另一个是这个类通过懒加载注入自己,再通过注入的代理去调用事务方法即可。

4.说一说Bean的生命周期

  1. 通过BeanDefinition获取bean的定义信息
  2. 调用构造函数实例化bean
  3. 调用了Bean的set方法(属性的依赖注入)
  4. 调用了Bean实现的Aware接口实现的方法,从前到后为:BeanNameAware(Bean的名称)、BeanFactoryAware(Bean的工厂)、ApplicationContextAware(Bean的上下文)
  5. Bean的前置处理器BeanPostProcessor-前置方法,在Bean的初始化方法完成前调用
  6. 自定义初始化方法,从前到后为:@PostConstruct注解的方法、实现了InitializingBean接口的方法
  7. Bean的后置处理器BeanPostPrpcessor-后置方法,在Bean的初始化方法完成后调用
  8. 销毁Bean时调用,从前到后为:@PreDestroy注解的方法,实现了DisposableBean接口的destroy()方法

5.说一说循环依赖

循环依赖:

  • 循环依赖其实就是循环引用,也就是两个或两个以上的bea互相特有对方,最终形成环。比如A依赖于B,B依赖于A
  • 循环依赖在spring中是允许存在,spring框架依据三级缓存已经解决了大部分的循环依赖。剩下的可以用@Lazy懒加载解决
    三级缓存:
    一级缓存:单例池,缓存已经经历了完整的生命周期,已经初始化完成的bean对象
    二级缓存:缓存早期的bean对像(生命周期还没走完)
    三级缓存,缓存的是ObjectFactory,表示对象工厂,用来创建对象的

6.SpringMvc的执行流程

重点组件:

DispatcherServlet:前端控制器

HandlerMapping:处理器映射器

HandlerAdapter:处理器适配器

ViewReslover:视图解析器

1.视图阶段

  1. 用户发送出请求到前端控制器(DispatcherServlet)
  2. 前端控制器收到请求调用处理器映射器(HandlerMapping)
  3. 处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器(如果有),再一起返回给前端控制器。
  4. 前端控制器调用处理器适配器(HandlerAdapter)
  5. 处理器适配器经过适配调用具体的处理器(Handler/Controller)
  6. 处理器执行完成返ModelAndView对象
  7. 处理器适配器将处理器(Controller)执行结果ModelAndView返回给前端控制器
  8. 前端控制器将ModelAndView传给视图解析器(ViewReslover)
  9. 视图解析器解析后返回具体视图(View)
  10. 前端控制器根据视图进行渲染视图(即将模型数据填充至视图中),并相应给用户

2.前后端分离阶段

  1. 用户发送出请求到前端控制器DispatcherServlet
  2. DispatcherServletu收到请求调用HandlerMapping(处理器映射器)
  3. HandlerMapping找到具体的处理器,生成处理器对象及处理器拦截器(如果有),再一起返给DispatcherServlet。
  4. DispatcherServleti调用HandlerAdapter(处理器适配器)
  5. HandlerAdapter经过适配调用具体的处理器(Handler/,Controller)
  6. 因为方法上有@ResponseBody,所以通过HttpMessageConverter来返回结果转换为JSON并响应

7.说一说SpringBoot自动配置原理

  1. 在Spring Boot项目中的l导类上有一个注解@SpringBootApplication,这个注解是对三个注解进行了封装,分别是:
  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan
  1. 其中@EnableAutoConfiguration是实现自动化配置的核心注解。该注解通过@Importi注解导入对应的配置选择器,内部就是读取了该项目和该项目引用的jar包的classpath路径下META-lNF/spring.factories.文件中的所配置的类的全类名。在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中。
  2. 条件判断会有像@ConditionalOnClass这样的注解,判断是否有对应的class文件,如果有则加载该类,把这个配置类的所有的Bean放入
    spring容器中使用。

8.Spring中常见的注解

1.Spring

  • 使用在类上用于实例化Bean
    -- @Component
    -- @Controller
    -- @Service
    -- @Repository
  • 使用在字段上用于根据类型依赖注入
    -- @Autowired
  • 结合@Autowired一起使用用于根据名称进行依赖注入
    -- @Qualifier
  • 标注Bean的作用范围
    -- @Scope
  • 指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解
    -- @Configuration
  • 用于指定Spring在初始化容器时要扫描的包
    -- @ComponentScan
  • 使用在方法上,标注将该方法的返回值存储到Spring容器中
    -- @Bean
  • 使用@Import导入的类会被Spring加载到Ioc容器中
    -- @Import
  • 用于切面编程(AOP)
    -- @Aspect
    -- @Before
    -- @After
    -- @Around
    -- @Pointcut

2.SpringMVC

  • 用于映射请求路径,可以定义在类上和方法上。用于类上,则表示类中的所有的方法都是以该地址作为父路径
    -- @RequestMapping
  • 注解实现接收http请求的json数据,将json转换为java对象
    -- @RequestBody
  • 指定请求参数的名称
    -- @RequestParam
  • 从请求路径下中获取请求参数(/user/{id}),传递给方法的形式参数
    -- @PathViriable
  • 注解实现将controller方法返回对象转化为json对象响应给客户端
    -- @ResponseBody
  • 获取指定的请求头数据
    -- @RequestHeader
  • @Controller和@ResponseBody合体
    -- @RestController

3.SpringBoot

  • 组合了-@Configuration注解,实现配置文件的功能
    -- @SpringBootConfiguration
  • 打开自动配置的功能
    -- @EnableAutoConfiguration
  • @ComponentScan
    -- Spring组件扫描

9.Mybatis的执行流程

  1. 读取MyBatis配置文件:mybatis-config.xml加载运行环境和映射文件
  2. 构造会话工厂SqlSessionFactory
  3. 会话工厂创建SqlSessioni对象(包含了执行SQL语句的所有方法)
  4. 操作数据库的接口,Executor执行器,同时负责查询缓存的维护
  5. Executor接口的执行方法里面,会从一个MappedStatement类型的对象里面读取其中封装的映射信息。
  6. 输入参数映射(java转数据库)
  7. 输出结果映射(数据库转java)

10.说一说Mybatis延迟加载

  1. 延迟加载的意思是:就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。
  2. Mybatis支持一对一关联对象和一对多关联集合对象的延迟加载
  3. 在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=truelfalse,默认是关闭的。或者在mapper文件中局部配置
  4. 底层原理是使用CGLIB创建目标对象的代理对象。当调用目标方法时,进入拦截器invoke方法,发现目标方法是null值,执行sgl查询。获取数据以后,调用set方法设置属性值,再继续查询目标方法,就有值了。

11.说一说Mybatis缓存

  1. 一级缓存: 基于PerpetualCache的HashMap本地缓存,其存储作用域为Session,当Session进行flush或close之后,该Session中的所有Cache就将清空,默认打开一级缓存
  2. 二级缓存: 是基于namespace和mapper的作用域起作用的,不是依赖于SQL session,默认也是采用PerpetualCache,HashMap存储。需要单独开启,一个是核心配置,一个是mapperB映射文件
  3. 清理缓存: 当某一个作用域(一级缓存Session,/二级缓存Namespaces)进行了新增、修改、删除操作后,默认该作用域下所有select中的缓存将被clear。
相关推荐
yy_xzz2 分钟前
基于条码数据生成校验密码的C++实现方案
开发语言·c++
李迟9 分钟前
TiDB 数据库8.1版本编译及部署
数据库·tidb
技术小白Byteman13 分钟前
蓝桥刷题note13(排序)
开发语言·数据结构·c++·学习·算法·visualstudio
苏卫苏卫苏卫14 分钟前
【Vue】选项卡案例——NBA新闻
开发语言·前端·javascript·css·vue.js·笔记
莫魂魂15 分钟前
009_抽象类和接口
java·开发语言·单例模式
矛取矛求22 分钟前
创意 Python 爱心代码
开发语言·python
雷渊23 分钟前
谈一谈分布式锁实现方式
java·后端·面试
小郝 小郝26 分钟前
【C语言】内存函数 (续)
c语言·开发语言·学习
_星辰大海乀28 分钟前
二叉树相关练习--2
java·开发语言·数据结构·算法·链表·idea
爱的叹息32 分钟前
关于Spring MVC中@RequestMapping注解的详细解析,涵盖其核心功能、属性、使用场景及最佳实践
java·spring·mvc