一、Spring框架中的单例bean是现场安全的吗?
不是线程安全的
Spring框架中有一个@Scope注解,默认的值就是singleton,单例的。
因为一般在spring的bean的中都是注入无状态的对象,没有线程安全问题,如果在bean中定义了可修改的成员变量,是要考虑线程安全问题的,可以使用多例或者加锁来解决。
二、什么是AOP?
AOP称为面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。
常见的AOP使用场景:
- 记录操作日志
- 缓存处理
- Spring中内置的事务处理
核心是:使用aop中环绕通知+切点表达式(找到要记录日志的方法), 通过环绕通知的参数获取请求方法的参数(类、方法、注解、请求方式等),获取到这些参数以后,保存到数据库。
三、Spring中的事务是如何实现的
Spring支持编程式事务管理和声明式事务管理两种方式。
-
编程式事务控制:需使用TranscationTemplate来进行实现,对业务代码有侵入性,项目中很少使用。
-
声明式事务管理:声明式事务管理建立在AOP之上的。其本质式通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
try{
//开始事务
//执行业务代码
Object proceed = joinPoint.proceed();
//提交事务
return proceed;
}catch (Exception e){
e.printStackTrace();
//回滚事务
}
}
四、Spring中事务失效的场景有哪些?
-
异常捕获处理
原因:事务通知只有捉到了目标抛出的异常,才能进行后续的回滚处理,如果目标自己处理掉异常,事务通知无法知悉。
解决:在catch块添加throw new RuntimeException(e)抛出
-
抛出检查异常
原因:Spring默认只会回滚非检查异常
解决:配置rollbackFor属性 @Transcational(rollbackFor = Exception.class)
-
非public方法
原因:Spring为方法创建代理、添加事务通知、前提条件都是该方法时public的
解决:改为public方法