MyBatis、Spring、动态代理面试知识点

226 阅读6分钟

CGLIB和JDK动态代理都是Java中实现动态代理的方式:

  • JDK动态代理是Java提供的一种基于接口的动态代理机制。它通过在运行时创建一个实现指定接口的代理类来实现代理功能。JDK动态代理要求目标类必须实现至少一个接口,代理对象与目标对象共享相同的接口类型。
  • 如果目标类已经实现了接口,且希望代理对象与目标对象共享相同的接口类型,可以选择使用JDK动态代理。
  • CGLIB(Code Generation Library) 是一个强大的、高性能的代码生成库,它可以在运行时扩展Java类和实现接口。CGLIB动态代理不需要目标类实现接口,它通过生成目标类的子类来实现代理功能。CGLIB动态代理通过继承的方式实现代理,因此无法代理被声明为final的方法。
  • 如果目标类没有实现接口,或者希望代理对象是目标类的子类,可以选择使用CGLIB动态代理。

mybatis涉及的知识点

  • MyBatis的工作原理

SqlSessionFactoryBuilder加载xml配置文件-->创建SqlSessionFactory(比作是一个数据库连接池--单例共享,要随用随关闭否则容易资源耗尽出现系统宕机)-->SqlSession(Connection 对象)执行crud-->SQL Mapper-->结束

  • MyBatis中分页的实现
  1. 内存分页: 使用RowBounds对象进行分页,针对ResultSet结果集执行的内存分页。
  2. 物理分页: 使用SQL中自带的limit关键字进行物理分页,在MySQL内存结构中。
  3. 分页插件: 使用PageHelper插件,插件提供SQL的拦截方法,根据dialect方言重写sql,物理分页语句。
  • MyBatis延迟加载: 通过配置lazyLoadingEnabled=true|false是否启用,使用CGLIB动态代理机制,根据接口或类的定义生成一个新的代理类,并在代理类中添加额外的逻辑来实现延迟加载的功能。

  • 当执行查询操作时,MyBatis只会加载主对象的数据,而不会加载关联对象的数据。

  • 当访问主对象的关联对象时,MyBatis会触发延迟加载机制。

  • 延迟加载机制会生成一个代理对象,该代理对象持有关联对象的引用但并未真正加载关联对象的数据。

  • 当第一次访问代理对象的关联对象属性或方法时,代理对象会拦截该操作,并通过执行额外的SQL语句从数据库中加载关联对象的数据。

  • 加载完关联对象的数据后,代理对象会将数据返回给调用方。

  • MyBatis缓存

    • 默认情况下,开启SqlSession级别的本地缓存,粒度更细--每个查询语句都是一个SqlSession级别的

    注意: 一级缓存失效的四种情况

    1. SqlSession缓存级别不同,结论: 每个sqlSession中的缓存相互独立

    2. SqlSession相同,查询条件不同,结论: 当前缓存中,不存在这个数据

    3. SqlSession相同,两次查询之间执行了增删改操作,结论: 因为增删改操作可能会对当前数据产生影响

    4. SqlSession相同,手动清除一级缓存,结论: 一级缓存就是一个map

    • 手动开启,namespace级别的二级缓存 -- 会话关闭了,一级缓存中的数据就保存到作用域更高的全局缓存中,不同mapper查询的数据会存放在自己对应的map中<setting name="cacheEnabled" 1 value="true"/>
    • 也可以通过实现Cache接口来自定义二级缓存(可拓展)

Spring涉及的知识点

  • IOC-控制反转的本质: 是一种设计思想,将原有手动创建对象的控制权交给Spring去管理

    • 控制:指的是对象创建(实例化、管理)的权力
    • 反转:控制权交给外部环境(Spring 框架、IoC 容器)

IoC 容器是 Spring 用来实现 IoC 的载体,IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。

  • IOC创建对象并进行依赖注入的方式:

    1. 构造器注入:通过无参/有参构造方法来创建
    2. Setter方法注入:通过无参构造函数创建对象,然后使用setter方法设置依赖的其他对象。
    3. 拓展注入:常量、bean、数组、list、map、set、null、Properties、P/C命名空间注入
  • SpringBean: 指那些被IOC容器管理的对象。

    • 声明为bean的注解

      • @Component:通用组件注解
      • @Repository:持久化Dao层,
      • @Service:服务层
      • @Controller:控制层
    • 注入bean(自动装配)的注解: @Autowired,@Resource区别:

      • @Autowired 是 Spring 提供的注解,@Resource 是 JDK 提供的注解。
      • @Autowired 默认的注入方式为byType(根据类型进行匹配),@Resource默认注入方式为 byName(根据名称进行匹配)。
      • 当一个接口存在多个实现类的情况下,@Autowired@Resource都需要通过名称才能正确匹配到对应的 Bean。@Autowired 可以通过 @Qualifier 注解来显式指定名称,@Resource可以通过 name 属性来显式指定名称。
      • @Autowired 支持在构造函数、方法、字段和参数上使用。@Resource 主要用于字段和方法上的注入,不支持在构造函数或参数上使用。
    • bean的作用域:

      • singleton : IoC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的,是对单例设计模式的应用。
      • prototype : 每次获取都会创建一个新的 bean 实例。也就是说,连续 getBean() 两次,得到的是不同的 Bean 实例。
      • request (仅 Web 应用可用): 每一次 HTTP 请求都会产生一个新的 bean(请求 bean),该 bean 仅在当前 HTTP request 内有效。
      • session (仅 Web 应用可用) : 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean(会话 bean),该 bean 仅在当前 HTTP session 内有效。
    • bean的生命周期: 包括实例化、属性赋值、初始化、使用和销毁这几个阶段。Spring框架提供了灵活的配置方式和回调机制,使得开发者可以在不同阶段插入自定义的逻辑,以满足特定的需求。

  • Spring AOP: 面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

    • 提供声明式事务,允许用户自定义切面
    • 横切关注点:日志,安全,缓存,事务等
    • 切面:通知:目标:代理:切入点:连接点
    • 五种类型(实现重写接口方法):前置、后置、前后环绕、异常通知、新加方法通知
    • 实现AOP的三种方式:①通过 Spring API 实现 ②自定义类来实现Aop ③使用注解实现
    • Srping支持手动声明+配置事务