Spring(10. 面试问题简析)学习笔记

上一篇:9. Spring 底层原理

文章目录

  • 1. 对Spring的IOC机制的理解
  • 2. 对spring的AOP机制的理解
  • 3. 了解过cglib动态代理吗?他跟jdk动态代理的区别是什么?
  • 4. 能说说Spring中的Bean是线程安全的吗?
  • 5. Spring的事务实现原理是什么?能聊聊你对事务传播机制的理解么?
  • 6. 画一张图说说spring boot的核心框架?
  • 7. 画一张图说说spring的核心框架?
  • 8. Spring中使用了哪些设计模式
  • 9. 能说一说springMvc的核心架构么?

1. 对Spring的IOC机制的理解

  • IOC叫控制反转其目的就是为了降低程序的耦合性,这是一种设计思想。IOC 控制反转 意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。

    • 存在一个类 myServiceImpl 实现了 myService 接口,如果在代码中大量使用 new 的方式直接创建了一个 myServiceImpl 对象进行使用,那这些直接使用的地方就和 myServiceImpl 类直接耦合在一起了
    • 若此时不想使用 myServiceImpl ,想要换为 newMyServiceImpl (同样实现 myService),那就需要对所有直接使用的地方进行修改,并且需要重新测试
    • 如上述示例所说,如果代码中各个类完全耦合在一起,出现任何一点变动,都需要修改大量代码,非常复杂
    • 使用 IOC 机制后,实例都是由容器创建的,所以在修改的话,只需要修改注册到容器中的类即可
  • Spring 容器,根据 XML/注解的配置实例化 Bean 对象,然后再根据 XML/注解,对 Bean 之间的引用关系进行依赖注入,让类与类之间彻底解耦,维护代码的时候可以更加轻松
    Spring(10. 面试问题简析)学习笔记_第1张图片

  • 底层的核心技术就是反射。利用反射直接根据你的类去构建对应的对象。

  • 依赖注入(Dependency Injection,DI)由容器动态的将某个依赖关系注入到组件之中。

Spring(10. 面试问题简析)学习笔记_第2张图片

2. 对spring的AOP机制的理解

  • ​ AOP(Aspect-Oriented Programming:面向切面编程),能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

  • AOP 使用场景 : 日志系统 、安全统一效验、事务

  • Spring AOP就是基于动态代理的,

  • 通过以下简单示例,简述基本原理:

    • 原先有这样一个方法:
      对这个方法的切面进行编程
    public class MyServiceAImpl implements MyServiceA{
    	public void doServiceA(){
    		……
    	}
    }
    
    • 动态代理后,会生成一个代理对象
      将原对象注入进来,并且重写方法,将切面中定义的操作加在方法中相应的位置
    public class ProxyMyServiceA implements MyServiceA{
    	privice MyServiceA myServiceA;
    	public void doServiceA(){
    		// 切面封装的方法
    
    		// 调用执行原本的方法
    		myServiceA.doServiceA();
    
    		// 切面封装的方法
    	}
    }
    
    • 调用 MyServiceA 的地方
      此时调用的地方注入的不再是原始的 MyServiceImpl ,而是代理对象 ProxyMyServiceA
    public class MyControllerA{
    	@Autowired
    	privice MyServiceA myServiceA;
    }
    

3. 了解过cglib动态代理吗?他跟jdk动态代理的区别是什么?

  • 动态代理:其实就是动态的创建一个代理类,并创建这个代理类的实例对象,在这个里面引用原来类的方法,然后所有方法的调用,都是先走代理类的对象,代理类负责做一些代码上的增强
  • Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理
  • JDK 动态代理:
    • 目标类实现了某个接口时使用
    • 生成一个代理类,这个代理类会实现和原视类同样的接口,然后通过反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起
  • CGLIB 动态代理:
    • 目标类没有实现任何接口时使用
    • 会在运行时动态的生成目标类的一个子类对象,然后覆盖其中特定方法并添加增强代码

4. 能说说Spring中的Bean是线程安全的吗?

  • Spring 容器中的 Bean 的 五种作用域,(绝大部分的时候,使用的都是单例的)

    • singleton : 单例,默认作用域,容器中只有一个 Bean 实例,单例的。
    • prototype : 原型,原型每次请求都会创建一个 新的bean实例。
    • request : 请求,每一次HTTP请求都会产生一个新的bean,该bean仅 在当前HTTP request内有效。
    • session : 会话,每一次HTTP请求都会产生一个新的bean, 该bean仅在当前HTTP session内有效。
    • global-session : 全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。Portlet是 能够生
  • Spring 中的 Bean 本身是线程不安全的,但是存在以下几种情况下,可以是线程安全的。

Spring(10. 面试问题简析)学习笔记_第3张图片

  • 如上图,Tomcat 会使用多个线程并发的去处理多个请求,这些线程并发的访问多个组件,因为大多使用的是单例的 Bean ,所以这些请求会访问到同一个实例对象中,如果在该对象中存在写操作,此时就是线程不安全的
  • 但是以下几种情况下,也可以是线程安全的
    • 不存在对内存数据的写操作
    • 通过各个组件的互相调用,最终访问到数据库
    • 代码中使用了线程安全的数据结构、方法

5. Spring的事务实现原理是什么?能聊聊你对事务传播机制的理解么?

  • 事务的实现原理:

    • 如果在方法上加了 @Transactional 注解
    • 此时 Spring 会采用 AOP 的思想拦截注解,在方法执行前开始事务,在方法执行完成后,根据执行结果来决定是回滚还是提交
  • 事务传播机制

    • 方法A 和 方法B 都使用了 @Transactional 注解,并且在 A 中调用了 B, 此时就涉及到事务的传播机制

    • 7 中事务的传播机制/级别

      支持当前事务的情况:

      1. TransactionDefinition.PROPAGATION_ REQUIRED:(默认使用)
        • 如果当前存在事务, 则加入该事务;(也即: 开启事务 -> 执行方法A -> 执行方法 B -> 提交/回滚 )
        • 如果当前没有事务,则创建一个新的事务。
      2. TransactionDefinition.PROPAGATION_ SUPPORTS:
        • 如果当前存在事务,则加入该事务;
        • 如果当前没有事务,则以非事务的方式继续运行。
      3. TransactionDefinition.PROPAGATION_ MANDATORY:
        • 如果当前存在事务,则加入该事务;
        • 如果当前没有事务,则抛出异常。(mandatory: 强制性)
      4. TransactionDefinition.PROPAGATION_ REQUIRES_ NEW:
        • 创建一个新的事务。
          Spring(10. 面试问题简析)学习笔记_第4张图片
      5. TransactionDefinition.PROPAGATION_ NOT_ SUPPORTED:
        • 以非事务方式运行
      6. TransactionDefinition.PROPAGATION_ NEVER:
        • 以非事务方式运行,如果当前存在事务,则抛出异常。:
      7. TransactionDefinition.PROPAGATION_ NESTED:
        • 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_ REQUIRED。
          Spring(10. 面试问题简析)学习笔记_第5张图片

6. 画一张图说说spring boot的核心框架?

  • Spring Boot 是 Spring 组件一站式解决方案,主要是简化了使用 Spring 的难度,简省了繁重xml的配置,提供了各种启动器,在运行过程中自定配置。
  • Spring Boot 启动时会启动内嵌的 Tomcat,并且将 Spring MVC、Mybatis …… 核心组件自动注入进容器。当需要使用到这些组件时,直接使用容器中的组件

7. 画一张图说说spring的核心框架?

Spring(10. 面试问题简析)学习笔记_第6张图片

  • 使用 BeanDefinitionReader 接口读取 Bean 的基本信息
  • 读取 Bean 的定义信息,在读取之前可以通过 BeanFactoryPostProcesser 修改一些 Bean 的定义信息
  • 对象工厂(BeanFactory)通过反射的方式获取 Bean 的实例化对象,在类实例化的过程中,可以自定义很多 BeanPostProcesser,来完整 Bean 的实例化,增强某些功能,这些就是 Spring 容器对象

8. Spring中使用了哪些设计模式

  1. 工厂设计模式 : 把一个对象的创建过程封装到一个工厂里
    • Spring 使用工厂模式通过 BeanFactor 创建 bean 对象。
    • Spring 本身就是一个大工厂,把所有的 Bean 实例都放在容器里,需要用到的时候,不用创建,直接去容器里获取就好
  2. 代理设计模式 : Spring AOP 功能的实现。通过动态代理增强切面
  3. 单例设计模式 : Spring 中的 Bean 默认都是单例的。
  4. 模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
  5. 包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
  6. 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
  7. 适配器模式 :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller。

9. 能说一说springMvc的核心架构么?

Spring(10. 面试问题简析)学习笔记_第7张图片

你可能感兴趣的:(面试,Spring,spring,面试,学习)