本文已参与「新人创作礼」活动,一起开启掘金创作之路。
-
@lazy 注解的作用?
- 懒加载实例化bean,可以解决循环依赖
-
spring 是什么?
- 轻量级的开源的j2ee框架。容器框架,中间层框架,让企业开发更快,更简洁。
- 轻量级的IOC 和AOP容器框架
- 包含并管理Bean的配置和生命周期,这个意义来讲是容器spring 是什么?
-
spring boot 零配置底层实现原理
- autoConfig, eg: Tomcat , 当类存在的存在的时候,实例化,最后根据类型去取,且结果应该只是一个。
- bean的后置处理器(BeanPostProcessor)使用application.yml中配置信息
-
spring事务实现方式,原理?
- 编程式(手动),申明式 @Transactinal
- @Transactional注解的方法,spring会基于这个类生产代理对象。代理逻辑先自动提交为false
- 执行业务方法
- 没有异常,提交事务,否则回滚。
- 针对哪些异常回滚事务是可以控制的。rollbackFor属性配置。默认对Error和RuntimeException回滚。catch后不在回滚。
-
spring的事务传播机制?
- 多个事务方法@Transactional(propagation = Propagation.REQUIRED)互相调用时,事务如何在这些方法间传播
-
REQUIRED:spring默认事务传播类型,如果当前没有事务,则新建一个事务,如果当前存在事务,则加入这个事务。 SUPPORTS:当前存在事务,则加入当前事务,如果当前没有事务,就以非事务方法执行。 MANDATORY:当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常。 REQUIRES_NEW:创建一个新事务,如果存在当前事务,则挂起该事务。 NOT_SUPPORTED: 以非事务的方式执行,如果当前存在事务,则挂起当前事务 NEVER:不使用事务,如果当前事务存在,则抛出异常。 NESTED:如果当前事务存在,则在嵌套事务中执行,否则REQUIRED的操作一样(开启一个事务) 对比REQUIRES_NEW:REQUIRES_NEW 是新建一个事务并且新事物与原事务无关,而NESTED则是当前存在事务时会嵌套一个事务(父子事务),父事务回滚,子事务也回滚,而在REQUIRES_NEW下,原有事务回滚不影响新开启事务。 对比REQUIRED: REQUIRED下,调用方存在事务时,使用同一事务,被调用方异常时,是否catch,事务都会回滚。而NESTED下,被调用方异常时,调用方可以catch异常,这样子事务回滚,父事不受影响。
-
Spring中事务隔离级别
-
DEFAULT:使用数据库默认的事务隔离级别。 READ_UNCOMMITTED:读未提交。允许事务在执行过程中,读取其他事务未提交的数据。 READ_COMMITTED:读已提交。允许事务在执行过程中,读取其它事务已经提交的数据。 REPEATABLE_READ:可重复读。在同一个事务内,任意时刻的查询结果是一致的。 SERIALIZABLE:所有事务依次执行。 - 已spring配置的隔离级别为准,如果db不支持,以db的为准。
-
-
spring 创建Bean的过程
实例化 -》属性赋值-》初始化-》销毁
-
实例化: new xxx(); 两个时机:a. 当客户端向容器申请一个Bean时,b. 当容器在初始化一个bean时发现需要依赖另一个bean。BeanDefinition对象保存。
-
设置对象属性():Spring 通过BeanDefinition找到对象依赖的其他对象,并将这些对象赋予当前对象。
-
处理Aware接口:Spring 会检测对象是否实现xxxxAware接口,实现的话,会调用对应的方法。BeanNameAware、BeanClassLoaderAware、BeanFactoryAware、ApplicationContextAware
-
BeanPostProcessor前置处理: 调用org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
-
InitializingBean: 实现接口后,调用org.springframework.beans.factory.InitializingBean#afterPropertiesSet,定制初始化逻辑
-
init-method: 、@PostConstruct ,配置后执行初始化逻辑。
-
BeanPostProcessor后置处理:调用org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
Bean可以正常使用了
-
DisposableBean: 实现接口后,对象销毁前调用org.springframework.beans.factory.DisposableBean#destroy
-
destroy-method: @PreDestroy
-
-
Spring框架中Bean是县城安全的吗?如果不安全,如何处理?
本身没有安全处理,如果bean无状态是安全的,如果bean有状态的是不安全的。
- 对于prototype作用域,每次都是生成一个新的对象,所以不存在线程安全问题
- 对于sington作用域:默认线程不安全。无状态表示这个实例没有属性对象。不能保存数据,是不变的数据。
- ThreadLocal 来解决线程安全问题。为每个线程存储一个变量副本。
-
Spring 中用到了哪些设计模式
- 简单工厂:根据传入参数,动态决定应该创建哪一个产品类:BeanFactory.
- 工厂方法:实现FactoryBean接口的Bean是一类叫做factory的bean。重写getObject()方法。getBean()返回bean.getObject()的返回值。
- 单例模式:获取单例bean。提供返回单一对象的入口。
- 装饰器:
- 代理模式:基于AOP的切面编程,产生代理对象
- 观察者模式:spring 事件驱动模型使用的是观察者模式。Spring中Observer常用listener的实现。
- 策略模式:Resource接口。
-
Spring中后置处理器的作用?
- 对bean进行加工。eg:AOP,基于原实例对象,判断是否要AOP,要的话生产代理对象。
-
IOC
- 容器,控制反转,依赖注入是实现IOC的一种方式。
-
如何理解Spring Boot中的starter?
- starter就是定义一个starter的jar包,写一个@Configuration配置类,将这些bean定义在里面,然后再starter包的META-INF/spring.factories中写入该配置类,springboot会按照约定来加载该配置类
- 开发人员只需要将相应的starter包依赖进项目中,进行相应的属性配置(使用默认配置时,不用配置),就可以进行代码开发,使用对应的功能。eg:spring-boot-starter-redis
-
如何实现一个IOC容器?
这个问题可以参考spring容器的实现,讲一下实现流程。定制化的功能可能要特殊处理,生成代理bean。简单流程如下:
- 配置文件配置包扫描路径
- 递归包扫描获取.class文件
- 反射、确定需要交给IOC管理的类
- 对需要注入的类进行依赖注入
- 对实例化的bean用map来存储