SSSM框架相关问题总结
Spring框架中的单例bean是线程安全的吗?
单例bean不是线程安全的。Spring中并没有封装关于单例bean多线程处理的任何操作,关于多线程的安全操作需要我们自己维护。
线程安全的核心问题在于:
第一,如果单例bean是无状态的,即没有成员变量或状态数据,通常bean是线程安全的。
第二,如果单例bean是有状态的,即包含可修改的成员变量,此bean是可能有线程安全风险的。
介绍一下AOP
AOP即面向切面编程,用于将那些与业务无关但却与多个对象产生影响的公共行为和逻辑封装起来,抽取到一个切面中,实现代码的复用,降低耦合。常见的使用场景有:操作日志记录、性能统计和权限控制等等。
Spring中的事务是如何实现的?
在spring中事物的核心是AOP完成的。它通过对方法前后进行拦截,在方法执行前开启事物,在方法执行完毕后,根据执行情况决定提交还是回滚事物。
Spring中事务失效的场景有哪些?
在项目开发中,Spring中事务失效的场景有很多,我遇到的失效场景有以下几种:
第一,非public调用导致的事物失效,这是因为 Spring 的事务拦截器默认只对public生效。
第二,this调用导致的事物失效,解决方法是通过代理对象调用,如将自身注入,然后调用事物方法。
第三,异常类型不匹配导致的事物失效,若抛出的是检查型异常,在
@Transactional
注解上配置rollbackFor
属性为Exception。
请你解释一下Spring中bean的生命周期?
Spring bean的生命周期是指bean在spring容器中创建、初始化、使用到销毁的全过程。其大致分为四个阶段包含多个关键点:
第一阶段为实例化阶段,通过BeanDefinition获取bean的定义信息,然后调用构造函数实例化bean。
第二阶段为依赖注入阶段,进行bean的依赖注入,例如通过setter方法或@Autowride注解。
第三阶段为初始化阶段,包含四个关键点:第一,处理实现了Aware接口的bean;第二,执行
BeanPostProcessor的前置处理器;第三,调用初始化方法,如实现了InitializingBean接口或自定义的init方法;第四,执行BeanPostProcessor的后置处理器。
第四阶段为销毁阶段,销毁bean,释放 Bean 占用的资源。
Spring中的循环引用?
Spring中的循环引用是指两个或两个以上的bean相互依赖,形成闭环。Spring中允许相互依赖,并提供了三级缓存可以解决大多数循环引用的问题。
一级缓存,单例池,缓存已完成初始化的bean对象。
二级缓存,缓存生命周期尚未完成的早期bean对象。
三级缓存,缓存beanfactory,用于创建bean。
你知道Spring中解决循环引用的具体流程吗?
Spring中使用三级缓存来解决循环引用,其具体流程如下:
第一,实例化A对象并创建
ObjectFactory存入三级缓存中。
第二,A初始化时需要使用B,B开始实例化并创建
ObjectFactory存入三级缓存中。
第三,B需要使用A,通过三级缓存获取
ObjectFactory,ObjectFactory创建A对象并存入二级缓存中。
第四,B完成初始化创建成功,存入一级缓存。
第五,由于B创建完成,A可以直接注入B,完成创建并存入一级缓存。
第六,清除二级缓存中的临时对象。
构造方法出现了循环依赖怎么解决?
可以使用@Lazy懒加载注解,延迟bean的加载直至开始使用。
SpringMVC的执行流程?
SpringMVC的执行流程包含以下步骤:
第一,用户端发送请求给前端处理器
DispatcherServlet,前端处理器接收请求并进行统一处理。
第二,
DispatcherServlet调用处理映射器HandleMapping找到具体的处理器,处理映射器返回处理器对象和响应的拦截器。
第三,
DispatcherServlet调用处理适配器HandlerAdapter适配并调用相应的处理器Controller,处理器处理完成后返回ModelAndView对象。
第四,
DispatcherServlet调用视图解析器ViewResolver解析并返回视图View对象。
第五,
DispatcherServlet
渲染视图并响应用户。以上是使用JSP视图阶段的执行流程,对于现在常用的前后端分离阶段流程,不同的是在具体处理器处理完成后返回的不是ModelAndView,而是在方法上添加@ResponseBody注解,通过HttpMessageConverter来返回结果转换为JSO并响应。
Springboot自动配置原理?
Springboot的自动装配原理依赖于@SpringBootApplication注解,它封装了
@SpringBootConfiguration
、@EnableAutoConfiguration
和@ComponentScan
。其中@EnableAutoConfiguration注解是实现自动装配的核心,该注解又组合了@Import注解,导入了AutoConfigurationImportSelector类,
实现了selectImports
方法,这个方法经过层层调用,最终会读取META-INF 目录下的后缀名为imports的文件或者spring.factories文件。读取到全类名了之后,会解析注册条件,把满足注册条件的Bean对象自动注入到IOC容器中
Spring 的常见注解有哪些?
Spring的常见注解包括:
声明Bean的注解:
@Component
、@Service
、@Repository
、@Controller
。依赖注入相关注解:
@Autowired
、@
Qualifier
、@Resource
。设置作用域的注解:
@Scope
。配置相关注解:
@Configuration
、@ComponentScan
、@Bean
。AOP相关注解:
@Aspect
、@Before
、@After
、@Around
、@Pointcut
。
SpringMVC常见的注解有哪些?
SpringMVC的常见注解有:
@RequestMapping
:映射请求路径。
@RequestBody
:接收HTTP请求的JSON数据。
@RequestParam
:指定请求参数名称。
@PathVariable
:从请求路径中获取参数。
@ResponseBody
:将Controller方法返回的对象转化为JSON。
@RequestHeader
:获取请求头数据。
@PostMapping
、@GetMapping
等。
Springboot常见注解有哪些?
Spring Boot的常见注解包括:
@SpringBootApplication
:由@
SpringBootConfiguration
、@
EnableAutoConfiguration
和@
ComponentScan
组成。其他注解如
@RestController
、@GetMapping
、@PostMapping
等,用于简化Spring MVC的配置。
MyBatis执行流程?
MyBatis执行流程如下:
第一,加载Mybatis的核心配置文件mybatis-config.xml和所有 Mapper 映射文件。
第二,创建SqlSessionFactory会话工厂。
第三,通过SqlSessionFactory会话工厂创建SqlSession,每次操作都需要一个SqlSession。
第四,通过SqlSession获取Mapper的动态代理对象,拦截接口方法调用。
第五,通过 Executor 执行器处理执行逻辑并完成参数绑定,执行SQL,将结果映射返回。
第六,进行事物处理并关闭会话是否资源。
Mybatis是否支持延迟加载?它的底层原理是什么?
Mybatis支持延迟加载,即在需要的时候才会加载关联数据。可以通过配置文件中的
lazyLoadingEnabled
配置启用或禁用延迟加载。它的底层原理主要是基于动态代理机制实现的。
第一,通过JDK 动态代理或 CGLIB 获取目标的代理对象,代理对象会拦截关联属性getter方法的调用。
第二,当代理对象检测到关联属性被访问时,会触发延迟加载器,执行预设的SQL语句。
第三,查询到关联属性后会属性设置,并继续查询目标方法返回。
Mybatis的一级、二级缓存用过吗?
MyBatis的一级缓存是基于
Perpetual
Cache
的HashMap本地缓存,作用域为Session,默认开启。若同一 SqlSession 内执行相同查询,MyBatis 会直接从缓存中获取结果,不再访问数据库。当 SqlSession 关闭时,一级缓存会被清空。二级缓存需要单独开启,作用域为Namespace或mapper,默认也是采用
PerpetualCache
,HashMap存储。当 SqlSession 关闭时,其一级缓存中的数据会被 刷入二级缓存,供其他 SqlSession 使用。
Mybatis的二级缓存什么时候会清理缓存中的数据?
当作用域(一级缓存Session/二级缓存Namespaces)进行了新增、修改、删除操作后,默认该作用域下所有select中的缓存将被清空。