1. Spring框架中bean是单例么?
@Service
@Scope("singleton")
public class UserServiceImpl implements UserService { }
- singleton : bean在每个Spring IOC容器中只有一个实例。
- prototype:一个bean的定义可以有多个实例。
2. Spring框架中的单例bean是线程安全的么?
不是线程安全的 Spring框架中有一个@Scope注解,默认的值就是singleton,单例的。 因为一般在spring的bean的中都是注入无状态的对象,没有线程安全问题,如果在bean中定义了可修改的成员变量,是要考虑线程安全问题的,可以使用多例或者加锁来解决
3. AOP
Spring:AOP
AOP称为面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。
常见的AOP使用场景:
- 记录操作日志
- 缓存处理
- Spring中内置的事务处理
4. 事务
Spring:事务
Spring失效场景
Spring中事务失效的场景有哪些
- 异常捕获处理,自己处理了异常,没有抛出,解决:手动抛出
- 抛出检查异常,配置rollbackFor属性为Exception
- 非public方法导致的事务失效,改为public
5. bean的生命周期?
6. 如何解决Spring中的循环引用?
Spring中的循环引用
- 循环依赖:循环依赖其实就是循环引用,也就是两个或两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于A
- 循环依赖在spring中是允许存在,spring框架依据三级缓存已经解决了大部分的循环依赖
- 一级缓存:单例池,缓存已经经历了完整的生命周期,已经初始化完成的bean对象
- 二级缓存:缓存早期的bean对象(生命周期还没走完)
- 三级缓存:缓存的是ObjectFactory,表示对象工厂,用来创建某个对象的
构造方法出现循环依赖怎么解决?
当您在Spring的一个bean的依赖项上使用
@Lazy
注解时,Spring不会立即创建该依赖项的bean实例。相反,它会创建一个代理对象(在大多数情况下是JDK动态代理或CGLIB代理),该代理对象会在实际调用方法时懒加载真正的bean实例。
- 当Spring尝试创建
BeanA
的实例时,它注意到BeanA
的构造器依赖于BeanB
。- 由于
BeanB
被标记为@Lazy
,Spring不会立即创建BeanB
的实例。相反,它会为BeanB
创建一个代理对象,并将其注入到BeanA
中。- 类似地,当Spring尝试创建
BeanB
的实例时,它注意到BeanB
的构造器依赖于BeanA
。但此时,BeanA
的实例已经存在(尽管它包含一个BeanB
的代理),因此Spring可以安全地创建BeanB
的实例(实际上是BeanB
的代理所指向的实例,但在这个上下文中,重要的是BeanB
的构造器不再等待BeanA
的完整实例)。- 当
BeanA
或BeanB
中的方法首次尝试访问对方(通过代理对象)时,Spring才会实际创建并初始化缺失的bean实例。