Spring Boot进阶:原理、实战与面试题分析
上QQ阅读APP看书,第一时间看更新

2.4.1 把握Bean的作用域

在介绍Setter方法注入时,我们已经提到了Spring中的Bean作用域的概念。作用域描述了Bean在Spring IoC容器上下文中的生命周期和可见性。在这里,我们将讨论Spring框架中不同类型的Bean作用域及其在使用上的指导规则。

如果想要通过注解来设置Bean的作用域,可以使用如代码清单2-26所示的示例代码。

代码清单2-26 设置Bean作用域示例代码

@Configuration
public class AppConfig {
    @Bean
    @Scope("singleton")
    public HealthRecordService createHealthRecordService() {
        return new HealthRecordServiceImpl();
    }
}

可以看到这里使用了一个@Scope注解来指定Bean的作用域为单例的singleton。在Spring中,除了单例作用域之外,还有一个prototype,即原型作用域,也可以称之为多例作用域,以与单例作用域进行区别。使用方式上,我们同样可以使用如代码清单2-27所示的枚举值来对它们进行设置。

代码清单2-27 通过枚举值设置作用域代码

@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)

在Spring IoC容器中,Bean的默认作用域是单例,也就是说不管有多少个对Bean的引用,容器只会创建一个实例。而原型作用域则不同,每次请求Bean时,Spring IoC容器都会创建一个新的对象实例。

从两种作用域的效果而言,我们总结出一条开发上的经验,即对于有状态的Bean,我们应该使用原型作用域,反之则应该使用单例作用域。

那么,什么样的Bean是有状态的呢?结合Web应用程序,我们可以明确对于每次HTTP请求而言,我们都应该创建一个Bean来代表这一次的请求对象。同样,对于会话而言,我们也需要针对每个会话创建一个会话状态对象。这些都是常见的有状态的Bean。为了更好地管理这些Bean的生命周期,Spring还专门针对Web开发场景提供了对应的request和session作用域。