1、Spring是什么?

Spring是一个轻量级的控制反转(IOC)和面向切向(AOP)的容器框架,简化企业应用程序的开发。
1.从大小和开销两方面来看Spring都是轻量级的
2.通过IOC(控制反转)技术达到代码解耦的目的
3.提供了AOP(面向切面 )的服务,允许通过分离应用的业务的逻辑与系统服务进行内聚性开发
4.包含并管理应用对象(Bean)的配置和生命周期
5.将简单的组件配置,组合成为复杂的应用

2、对Spring AOP的理解?

主要从OOP和AOP的区别来展开
系统由许多不同的组件所组成,每一个组件各负责一块特定功能。除了实现自身核心功能之外,还经常承担一些额外的职责,例如日志打印、事务管理和安全等,这些系统服务通常称之为横切关注点,因为它们会跨越系统的各个模块。
OOP面向对象,允许开发者定义纵向的关系,但并不适用于定义横向的关系,会导致大量代码的重复。
AOP可以将程序中的交叉业务逻辑(比如日志打印、事务处理),封装成一个切面,然后注入到目标对象(业务逻辑)中,而且AOP可以对某个对象或某些对象的功能进行增强,比如对象中的方法进行增强,可以在对象执行某个方法之前额外做一些事情,在某个方法之后额外做一些事情。
AOP的实现方式:
AOP的实现一般基于代理模式,主要可分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。
(1)AspectJ是静态代理,也称为编译时增强,AOP框架会在编译阶段生成AOP代理类,并将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。
(2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

3、Spring Aop相关术语的理解?

1.连接点:接口类中哪些方法可以被增强,那么这些方法就被称为连接点
2.切入点:实际真正被增强的方法
3.通知(增强):实际增强的逻辑部分,所执行的动作称为通知
前置通知:在连接点之前执行的通知
后置通知:当连接点退出的时候执行的通知
环绕通知:环绕通知可以在方法调用前后完成自定义的行为。可分为around before和around after
异常通知:在方法抛出异常退出时执行的通知
最终通知:在连接点正常完成后执行的通知(若抛出异常,则不执行)
4.切面:被抽取出来的公共模块,可以用来会横切多个对象。

image.png

4、Spirng IOC的理解

1.容器概念:
IOC容器其实是一个map对象,里面存储了各种对象(比如说xml配置的Bean节点,@Repsitory、@Service、@Controller等),在项目启动的时候会读取配置文件里的bean节点,根据全限定类名使用反射的机制创建对象放到map里,接下来我们就在代码里通过@Autowired、@Resourse等注解可以在项目启动时扫描这些对象注解,并根据类型或id注入。
2.控制反转:(控制权由主动行为变为被动行为)
没有引入IOC容器之前,对象A依赖于对象B,那么对象A必须主动去创建对象B或者使用已经创建的对象B,需要A进行主动创建,控制权在自己手上。引入IOC容器之后,对象A和对象B之间失去了直接联系,当对象A运行时需要对象B时,IOC容器会主动创建一个B对象注入到对象A所需要的地方。
3.依赖注入:
获得依赖对象的过程被反转了,控制反转之后,获得依赖对象的过程由自身管理主动创建变为IOC容器主动注入,就是说IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。

5、BeanFactory和ApplicationContext有什么区别?

基本概念:
1、BeanFactory是IOC底层的接口,定义了IOC的基本功能,包含了各种Bean的定义、加载、实例化、依赖注入和生命周期管理等。ApplicaitionContext接口作为BeanFactory接口的子类,除了提供BeanFactory的基本功能以外,还提供了更完整的框架功能,例如:
1)继承了MessageSource,支持国际化
2)统一的资源访问文件
3)提供了在监听器中注册bean的事件
4)同时加载了多个配置文件,使得每一个上下文都专注于一个特定的层次,例如应用的web层。
BeanFactory和ApplicationContext的区别?
1、BeanFactory采用的是延迟加载形式注入Bean的,只有在使用到某个Bean时,才会对Bean进行实例化,这样我们就无法提前发现一些存在的Spring的配置问题;ApplciationContext它是在容器启动的时候,一次性创建了所有的Bean,这样在容器启动时就可以发现Spring存在的配置错误。
2、相比于BeanFactory,ApplicationContext在容器启动时一次性加载了所有的单实例Bean,不足之处在于占用内存空间,当Bean实例较多的时候会导致程序启动较慢。
3.BeanFactory通常是以编程的方式被创建,ApplicationContext还能以声明的方式进行创建(使用ContextLoader)
4.BeanFactory和ApplicationContext都支持BeanPostProcessor和BeanFactoryPostProcessor的使用,但两者的区别在于BeanFacrtory需要手动注册,而ApplicationContext是自动注册的。

6、Spring bean的生命周期?

  1. - 实例化Bean,其中对于BeanFactory容器,容器调用createBean进行实例化;对于ApplicationContext容器,会获取BeanDifinition对象中的信息,实例化所有的bean
  2. - 设置对象属性(依赖注入):利用@AutoWired注解对属性进行填充
  3. - 处理Aware接口:Spring会检测该对象是否实现了xxxAware相关接口,通过Aware类型的接口,可以让我们拿到Spring 容器的一些资源。

①如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,传入Bean的名字;
②如果这个Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
②如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身。
③如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文;

  - BeanPostProcessor前置处理:实现BeanPostProcessor接口,自定义Bean的一些前置处理逻辑。
  - 调用初始化方法
  - 调用BeanPostProcessor的初始化后的方法,在这里进行AOP

——————————Bean被正确创建——————————————————————————————

  -  使用Bean
  - 实现DisposableBean接口,调用destory()方法

7、Spring中支持的bean的作用域?

1、singleton:默认作用域,单例模式中每一个IOC容器中只有一个bean对象
2、prototype:为每一个bean请求都提供一个实例化
3、request:在每次request请求中创建一个实例,bean在请求完成后进行垃圾回收
4、session:同一个session对话共享一个bean实例,不同的session会话使用不同的bean实例
5、application:bean实例化对象被定义在ServletContext生命周期内中共用的一个单例对象
6、webstock:bean实例化对象被定义在webstock生命周期内中共用的一个单例对象
7、global-session:全局作用域,所有会话共享一个实例。如果想要声明让所有会话共享的存储变量的话,那么这全局变量需要存储在global-session中。

8、Spring 框架中单例Bean是线程安全的吗?

Spring 框架本身没有为单例bean提供多线程安全的封装处理,因此可以说Spring容器中的Bean本身不具备线程安全的特性。
1、对于prototype作用域的bean对象,对每一个bean请求都提供了一个实例化,线程之间不存在bean的共享,因此不存在线程安全问题。
2、对于单例模式下的bean,所有线程都共享同一个bean对象,因此存在线程安全问题。但对于一个无状态的单例Bean(例如Dao、Controller、Service类,线程中的操作不会对Bean的成员执行查询以外的操作),因此不需要考虑线程安全问题
3、但对于有状态的单例Bean,就是有实例变量的对象,可以保存数据,因此多个线程共享单例bean时,需要考虑线程安全问题。对于这种情况,我们可以采用ThreadLocal解决线程安全问题,为每个线程提供一个独立的变量副本,不同线程只操作自己的变量副本(例如多个线程连接数据库,因为connection是有状态的(比如说数据库事务),我们采用ThreadLocal为不同线程维护了一套独立的connection副本,保证线程之间不会互相影响。)

9、Spring框架的设计模式主要有哪些

1、简单工厂:由一个工厂类根据传入的参数,动态决定应该创建哪一类的产品。
2、工厂方法:实现FactoryBean接口的bean是一类叫做factory的bean,其特点是spring会在使用getBean()调用获得该bean时,自动调用该bean的getObject()方法,返回的不是factory的bena对象,而是getObject()方法返回的bean对象
3、单例模式:保证一个类只有一个bean对象(spring默认为单例模式)
4、适配器模式:Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller,让适配器代替controller执行相应的方法。
5、装饰器模式:动态给一个对象添加一些额外的职责,类名中含有wrpper或者decorator
6、观察者模式:spring事件驱动模型是观察者模式的应用,比如事件监听器的实现
7、策略模式:例如Resource的实现类,针对不同的资源文件,实现了不同方式的资源获取策略

10、Spring事务的实现方式和原理及隔离级别?

Spring事务的本质是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。Spring只提供统一事务管理接口,具体实现都是由各数据库自己实现,数据库事务的提交和回滚是通过binlog或者undo log实现的。Spring会在事务开始时,根据当前环境中设置的隔离级别,调整数据库隔离级别,由此保持一致。
1、Spring事务的种类:
spring事务支持编程式和声明式管理两种,编程式事务管理使用TransactionTemplate;声明式事务管理建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前启动一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
image.png
2、spring事务的隔离级别:

image.png

11、spring事务传播机制?

比如方法A是一个事务,方法A中执行过程中调用方法B,那么方法B有无事务以及方法B对事务的要求都会影响方法A事务的执行流程,同时方法A事务也会对方法B事务造成影响,主要是由事务传播机制造成的:
image.png
NESTED和REQUIRED的区别:
REQUIRED事务传播机制下,如果调用方存在事务,那么被调用方和调用方共用一个事务,如果被调用方出现异常时,那么两者都会回滚(共享一个事务);而NESTED机制下,被调用方和调用方共用一个事务,如果被调用方出现异常,调用方可以利用catch捕获异常,这样只有被调用方(子事务)回滚、
NESTED和REQUIRED_NEW的区别:
无论当前存不存在事务,REQUIRED_NEW都会创建一个新事物进行执行,而且这个新开启的事务和原有的事务是无关的,而NESTED则是在当前事务(父事务)的基础下开启一个嵌套事务(子事务),若父事务发生回滚,则子事务也会发生回滚;而在REQUIRED_NEW机制下原有事务的回滚,不会影响新开启的事务。

12、Srping事务什么时候会失效?

spring事务的原理是AOP,进行了切面增强,那么失效的原因就是AOP不起作用了,常见的情况如下:
1、发生了自调用,类里面使用了this调用本类的方法,此时这个this对象不是代理类,而是userService对象本身,解决办法让那个this对象变成userService的代理类即可(AOP有关)。
2、方法不是public的,@Transactional只能用于public方法,否则事务不会失效。
3、数据库不支持事务。
4、没有被spring管理。
5、异常没有被定义,事务不会回滚。

13、Spring中bean的自动装配方式?

在spring中,使用autowire来配置自动装载模式,对象无需自己查找或创建与其关联的其他对象,由容器负责把需要相互协作的对象引用赋予各个对象。
(1)在spirng框架中xml配置的装配方式:

  - no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean。
  - byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。 
  - byType:通过参数的数据类型进行自动装配。
  - constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配。
  - autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。

(2)基于注解的自动装配方式:
使用@Autowired、@Resource注解来自动装配指定的bean。在使用@Autowired注解之前需要在Spring配置文件进行配置,。在启动spring IOC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性。在使用@Autowired时,首先在容器中查询对应类型的bean:

  • 如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据;
  • 如果查询的结果不止一个,那么@Autowired会根据名称来查找;
  • 如果上述查找的结果为空,那么会抛出异常。解决方法时,使用required=false

    14、Spring 、Spring MVC、Spring Boot有什么区别?

    spring是一个IOC容器、主要用来管理Bean,使用依赖注入实现控制反转,可以很方便的整合各种框架,而且可以提供AOP机制来弥补OOP的代码冗余问题,使不同类的不同方法中的公共处理逻辑抽取成切面,自动注入给各个方法使用(日志、异常)。
    Spring MVC是spring针对于web框架的一个解决方案,提供了一个总的前端控制器Servlet,接收http请求并进行处理,然后定义了一套路由策略(url到handle的映射)及适配执行handle,将handle结果使用相应的视图解析技术生成视图给前端。
    Spring Boot整合了spring和Spring MVC的快速开发工具包,简化了相应的配置,整合了一系列的解决方案(starter机制)、redis等,我们只需引入相应的依赖,即可进行开发使用
    [

](https://blog.csdn.net/a745233700/article/details/80959716)