1.我看你项目中都是基于Spring开发的,Spring容器中的Bean是线程安全的吗?
答案:不是线程安全的; Spring容器中的Bean默认是singleton单例的,所有线程都共享一个单例Bean,因此是存在资源竞争的; 但在实际开发中,单例Bean一般都以无状态的方式来使用,即线程之间的操作不会对Bean的成员执行除查询以外的操作,所以这个单例Bean又可以说是线程安全的。比如:Controller、Service、Dao等这些Bean大多数是无状态的,我们不会对这些Bean中的属性进行修改操作,只需要关注方法本身即可;
2.如何保证Spring容器中的Bean是线程安全的呢?
1、把默认的singleton单例的Bean的改为prototype多例的Bean;
2、在Bean对象中避免定义可变的成员变量;
3、如果Bean对象中需要定义可变成员变量,将可变成员变量保存在ThreadLocal中;
3.什么情况下会触发Spring事务回滚?
发生异常的时候
4. 如果事务方法抛出IOException是否会触发Spring事务回滚?
如果采用Spring默认的事务回滚规则,它默认是发生RuntimeException异常时触发事务回滚,而现在是发抛出IOException异常,那不会触发Spring事务回滚;
如果想触发IOException异常事务回滚,需要指定回滚的规则; @Transactional(rollbackFor = IOException.class)
5.有没有遇到过Spring事务失效的情况,什么情况下Spring事务会失效呢?
1、异常类型错误
2、方法或类上没有标注@Transactional注解;
3、同一类中,方法内部自调用;
4、事务方法不是public的;
5、多线程调用;
6、异常被try ... catch
7、手动抛了别的异常
8、事务方法所在的Bean未被 Spring 容器管理
9、方法的事务传播类型不支持事务
10、表的数据库引擎不支持事务,比如MyISAM存储引擎不支持事务;
举例解释:
1、同一个service中,方法a标注事务注解,则方法b没有标注事务注解;
b失效,只有加了注解才会开启事务
2、同一个service中,没有标注事务注解的b方法调用标注了事务注解的a方法;
失效,目标方便没有加注解,aop就不会再调用前开启事务,所以事务失效
3、不同的Service中,没有标注事务注解的b方法调用标注了事务注解的a方法;
不失效,另一个方法在一个新的bean,spring会开启一个代理去访问,此时相当于一个新的入口,aop会判断有没有事务注解,有的话就会再调用前开启事务,调用后提交事务或者回滚
4、标注了事务注解的public方法、protected方法、默认无修饰方法、private方法,final方法,static方法;
只有public生效,事务是通过动态代理完成的,受到其他修饰符影响会无法进行代理覆盖重写,导致事务失效
5、多线程中的事务;
失效,在另一个线程发生的一场会被消化掉,所以主线程不会回滚,导致事务失效
6.对Spring框架Bean的生命周期有了解过吗?
1、解析xml配置或者注解的类,得到BeanDefinition;
2、通过BeanDefinition反射创建Bean对象(实例化Bean对象)。
3、对Bean对象进行属性填充
4、回调实现Aware接口的方法,比如BeanNameAware
5、调用BeanPostProcessor的初始化前方法;
6、调用init初始化方法(如果有的话);
7、调用BeanPostProcessor的初始化后方法,此处会进行AOP;
8、将创建好的Bean对象放入一个Map中;
9、业务中使用Bean对象就从Map中获取;
10、Spring容器关闭时调用DisposableBean的destory方法销毁Bean对象;