一、原理
1.1 spring、springmvc、springboot的区别
spring是一个一站式的java开发框架,核心是IOC和AOP,针对开发WEB层(springmvc),业务层(ioc),持久层(jdbctemplate)提供了配置方案。
springmvc是基于spring,属于WEB层,用于路径映射和视图渲染。
springboot不需要配置xml,遵循默认优先配置,更专注于开发微服务后台接口。
1.2 springmvc的工作流程
1.2 spring的事务传播机制
多个事务在相互调用的时候,事务如何在这些方法之间进行传播。
- REQUIRED:默认的传播特性,如果当前没有事务,就新建一个事务,如果当前存在事务,就加入这个事务。
- SUPPORTS:当前存在事务,则加入当前事务,如果当前没有事务,则以非事务的方式执行。
- MANDATORY:如果当前存在事务,就加入当前事务,如果当前事务不存在就抛出异常。
- REQUIRED_NEW:创建一个新事务,如果当前存在事务,则挂起事务。
- NOT_SUPPORTED:以非事务的方式执行,如果存在当前事务,则挂起当前事务。
- NEVE:不使用事务,如果当前事务存在,则抛出异常。
- NESTED:如果当前事务存在,就在嵌套事务中执行,否则和REQUIRED一样。
1.3 NESTED和REQUIRED_NEW的区别
REQUIRED_NEW新建的事务和和原有的事务无关,如果原有的事务发生异常,父事务会回滚,不影响子事务。NESTED是如果当前事务存在,如果原有事务发生异常,父事务和子事务都会回滚。
1.3 NESTED和REQUIRED的区别
REQUIRED情况下,父和子使用同一个事务,被调用方出现异常,无论是否catch到,事务都会回滚,而在NETSTED情况下,被调用方发生异常,调用方可以catch到异常,只有子事务会回滚,父事务不会。
1.4 Spring的单例Bean是线程安全的吗?
- 如果Bean有状态(有数据存储功能),就需要开发人员保证线程安全,
- 我们本身的controller和service和dao本身不是线程安全的,只是调用里面的方法,多线程调用一个实例方法会在内存复制遍历,是在自己线程的工作内存,是线程安全的。
- 如果需要有状态的实例变量或类变量,需要使用ThreadLocal把他变为线程私有,如果需要多个线程共享,就需要使用cas或synchronize或lock实现线程同步。
1.5 Spring框架使用了哪些设计模式及应用场景?
- 工厂模式:BeanFactory以及ApplicaitonContext创建中应用。
- 模板模式:BeanFactory以及ApplicaitonContext创建中应用。
- 代理模式:SpringAop利用AspectJAop实现。AspectJ利用的是动态代理。
- 策略模式:加载资源文件的方式,使用了不同的方法。如:ClassPathResource、FileSystemResource、ServeletContextResource、UrlResource。在AOP的实现中,采用两种不同的方式,JDK的动态代理和CGLIB代理。
- 单例模式,比如在创建bean的时候。
- 观察者模式,spring中的ApplicationEvent,ApplicationListener,ApplicationEventPublisher
- 适配器模式,MethodBeforeAdviceAdapter,ThrowsAdviceAdapter,AfterReturningAdapter8.装饰者模式,源码中类型带Wrapper或者Decorator的都是
1.6 Spring事务的实现方式原理
- 编程式事务:通过代码来控制事务的处理逻辑。
- 声明式事务:通过@Transaction注解来实现。
- 事务是通过AOP生成代理对象,当使用代理对象的方法时,如果有事务处理,会将事务提交给关闭,然后执行具体逻辑,如果没有出现异常,那么代码逻辑就会提交,否则进行回滚。
1.6 Spring事务什么时候会失效?
- Bean对象没有被spring容器进行管理。
- 方法修饰符不是public。
- 自身调用问题。
- 数据源没有配置事务管理器。
- 数据库不支持事务。
- 异常被捕获。
- 异常类型错误或配置错误。
1.7 Spring支持的Bean的作用域?
- singleton:IOC容器仅创建一个Bean实例,IOC每次返回的都是同一个实例。
- prototype:IOC容器可以创建多个Bean实例,每次返回的都是一个新的实例。
- request:仅对HTTP请求生效,使用该属性定义Bean,每次HTTP请求都会创建一个新的Bean,使用于WebApplicationContext。
- session:同一个Session共享一个Bean实例,不同Session共享不同的实例。
- global-session:所有的Session共享一个Bean实例。
1.8 Spring的Bean的生命周期?
1、 实例化(Instantiation)
首先实例化Bean,当客户向容器请求一个尚未初始化的Bean或者尚未初始化的依赖Bean时,容器会调用doCreateBean()方法进行实例化,实际上就是利用反射的方式创造出一个bean对象。
2、 属性填充(populate)
Bean对象的实例创建出来后,接着对Bean对象的实例进行属性填充,也就是注入这个Bean所依赖的对象。
3、 初始化(Initialization)
属性填充完后,初始化分为以下5个阶段
- 执行Aware接口的方法(Spring会检测对象是否实现了XXXAware,通过Aware类型的接口,可以拿到Spring容器的一些资源,如实现BeanNameAware可以获取BeanName,实现BeanFactoryAware可以获取BeanFactory)
- 执行BeanPostProcessor的前置处理方法postProcessBeforeInitialization()方法,对Bean进行一些自定义的前置处理.
- 判断Bean是否实现了InitializationBean的接口,如果实现了如果实现了,将会执行InitializingBean的afterPropertiesSet()初始化方法。
- 执行用户自定的初始化方法,如init-method等。
- 执行BeanPostProcessor的后置处理方法postProcessAfterInitialization()
4、 销毁(Destruction)
- 首先判断Bean是否实现DestructionAwareBeanPostProcessor接口,如果实现了会调用DestructionAwareBeanPostProcessor的销毁回调方法。
- 其次判断Bean是否实现了DisposableBean接口,如果实现了就会调用对应的destroy()方法。
- 最后判断这个Bean是否配置了destroy-method等自定义的销毁方法,如果有的话,就会用自动调用其销毁方法。
doCreateBean:
填充属性(populateBean):
执行Aware接口方法:
执行前置处理:
执行初始化方法:
执行后置处理器:
1.9 什么是AOP?
-