Spring

使用spring的优势是什么?

1、Spring通过DI(依赖注入),AOP和消除样板式代码(通过切面和模板)来简化开发

2、低侵入式设计

  • 不强制类要实现Spring的任何接口或类,没有任何地方表明它是一个Spring组件。 意味着这个类在Spring应用和非Spring应用中都可以发挥同样的作用

3、Spring的IOC容器降低了业务对象替换的复杂性,提高了组件之间的解耦

4、Spring的AOP支持允许将一些通用任务如安全,事务,日志等进行集中式的管理,进行更好地复用

5、Spring的ORM和DAO提供了与第三方持久层框架的良好整合(mp之类),并简化了底层的数据库访问

  • DAO层一般是进行数据存取操作的,集中到一起,主要是为了方便维护,逻辑比较清晰

  • ORM其实是一种处理问题的方式,它目的其实是让程序员能够运用面向对象的思想来操作数据对象,比如将数据库表映射成java的实体类对象,封装一些基本的数据操作

6、Spring高度开放,并不强制应用完全依赖于Spring,可以自由选用框架的一部分


Spring的事务传播机制是什么?

详见Spring事务 | Z.yang (hzzzzzy.icu)


单例Bean是线程安全的吗?

Spring中的对象默认是单例的,框架中并没有对bean进行多线程的封装处理

如果bean是有状态的,那么就需要自己来保证线程开发的安全比如将作用域singleton改为prototype,这样每次请求bean对象就相当于创建新的对象来保证线程的安全

  • 有状态:有数据存储的功能
  • 无状态:无存储数据功能

在使用时,不要在bean中声明有状态的变量或者类变量

  • 如果必须要这么做,那么应该用ThreadLocal将变量变成线程私有的

  • 如果bean中声明的实例变量或类变量需要在多线程之间共享,那么只能使用synchronized,lock,cas等实现线程同步的方式(效率低)


Spring中使用了哪些设计模式及应用场景

工厂模式:在各种BeanFactory和ApplicationContext创建中都用到

模板模式:在各种BeanFactory和ApplicationContext的实现中都用到

代理模式:Spring AOP 利用 AspectJ AOP 实现的,AspectJ AOP 底层使用了动态代理

单例模式:创建bean的时候

观察者模式:ApplicationEvent,ApplicationListener,ApplicationEventPublisher

策略模式:在APO的实现中,采用了两种不同的方式,jdk和cglib动态代理


Spring事务的隔离级别有哪些?

Spring事务 | Z.yang (hzzzzzy.icu)


Spring事务的实现方式原理是什么?

当一个方法添加@Transaction注解时,spring会基于这个类生成一个代理对象,会将这个代理对象作为bean,当使用到这个代理对象的方法时

  • 如果有事务处理,则会先关闭事务的自动功能,然后执行方法的具体业务逻辑

  • 如果业务逻辑没有异常,那么代理逻辑就会直接提交,如果出现任何异常,那么直接进行回滚操作(也可以控制对一些特定的异常进行特定的操作)


Spring事务什么时候会失效?

  • bean对象没有被spring容器进行管理
  • 方法的访问修饰符不是public
  • 异常被捕获
  • 异常类型错误或配置错误

Bean生命周期是什么?

image-20221109161103870
  • 实例化Bean:反射的方式生成对象

  • 填充Bean的属性:populateBean(),循环依赖,三级缓存

  • 调用Aware接口相关方法:invokeAwareMethod()(完成BeanName,BeanFactory,BeanClass,BeanClassLoader对象的属性设置)

  • 调用BeanPostProcessor中的前置处理方法(比如:ApplicationContextPostProcessor)

  • 调用initmethod方法:判断是否实现了InitializingBean接口,如果有,调用afterPropertiesSet方法,没有就不调用

  • 调用BeanPostProcessor的后置处理方法:Spring的AOP就是在此处实现

  • 注册Destruction相关的回调接口

  • 获取到完整对象,可以通过getBean的方法来进行对象的获取

  • 销毁流程

    • 判断是否实现了DisposableBean接口
    • 调用destoryMethod方法

Spring支持的Bean作用域有哪些?

  1. singleton

    使用该属性定义Bean时,IOC容器仅创建一个Bean实例,IOC容器每次返回的是同一个Bean实例

  2. prototype

    使用该属性定义Bean时,IOC容器可以创建多个Bean实例,每次返回的都是一个新的实例

  3. request

    该属性仅对HTTP请求产生作用,使用该属性定义Bean时,每次HTTP请求都会创建一个新的Bean,适用于
    WebApplicationContext环境

  4. session

    该属性仅用于HTTP Session,同一个Session:共享一个Bean实例。不同Session使用不同的实例

  5. global-session

    该属性仅用于HTTP Session,同session作用域不同的是,所有的Session:共享一个Bean实例


什么是Bean自动装配,它有哪些方式?

bean的自动装配指的是bean的属性值在进行注入时通过某种特定的规则和方式去容器中进行查找,并设置到具体的对象属性中,主要有以下方式

  • no:缺省情况下,自动配置是通过”ref”属性来手动设定的
  • byName:根据属性名称自动装配
  • byType:根据数据类型自动装配(存在相同类型的不同名对象时会出现错误)
  • constructor:构造函数参数的byType方式
  • autodetect:如果找到默认的构造函数,使用“constructor方式”否则使用“byType方式”进行装配

SpringBoot

如何理解Springboot中的starter?

使用spring+springmvc进行开发时,如果需要引入mybatis框架,那么需要在xml中定义需要的bean对象,如果需要引入额外的组件,也需要进行复杂的配置,所以springboot引入了starter

starter可以理解为一个jar包。写一个@Configuration的配置类,如何将这些Bean定义在里面,然后再starter包的META-INF/spring.factory中写入配置类,那么在springboot程序启动时就会进行加载