与一般的 Spring 管理的组件一样,自动检测的组件的默认和最常见的作用域是 singleton。然而,有时你需要一个不同的作用域,可以通过 @Scope
注解来指定。你可以在注解中提供作用域的名称,如下面的例子所示:
@Scope("prototype")
@Repository
public class MovieFinderImpl implements MovieFinder {
// ...
}
:::info @Scope 注解只对具体的 Bean 类(对于注解的组件)或工厂方法(对于 @Bean 方法)进行反省。与XML bean 定义相比,没有 bean 定义继承的概念,而且类级别的继承层次与元数据的目的无关。 :::
有关 Spring上下文中 request
或 session
等 Web 特定作用域的详细信息,请参阅 Request、Session、Application 和 WebSocket 作用域。与这些作用域的预建注解一样,你也可以通过使用 Spring 的元注解方法来组成你自己的作用域注解:例如,用 @Scope("prototype")
元注解的自定义注解,可能还会声明一个自定义作用域代理模式。
:::info 为了给作用域解析提供一个自定义的策略,而不是依赖于基于注解的方法,你可以实现 ScopeMetadataResolver 接口。请确保包含一个默认的无参数构造函数。然后你可以在配置扫描器时提供完全合格的类名,就像下面这个注释和 Bean 定义的例子所显示的那样。 :::
@Configuration
@ComponentScan(basePackages = "org.example", scopeResolver = MyScopeResolver.class)
public class AppConfig {
// ...
}
<beans>
<context:component-scan base-package="org.example" scope-resolver="org.example.MyScopeResolver"/>
</beans>
当使用某些非单例作用域时,可能需要为作用域对象生成代理。这个 将作用域的 Bean 作为依赖项 中有描述。为了这个目的,组件扫描(component-scan)元素上有一个 scoped-proxy
属性。三个可能的值是:no、interfaces 和 targetClass。例如,以下配置的结果是标准的 JDK 动态代理:
@Configuration
@ComponentScan(basePackages = "org.example", scopedProxy = ScopedProxyMode.INTERFACES)
public class AppConfig {
// ...
}
<beans>
<context:component-scan base-package="org.example" scoped-proxy="interfaces"/>
</beans>