- 配置bean的作用域
参数 |
描述 |
||||||||||||||
proxyMode |
指定是否应将组件配置为作用域代理,如果是,则代理应基于接口还是基于子类。 |
||||||||||||||
scopeName |
指定用于带注释的组件/bean 的范围的名称
|
||||||||||||||
value |
scopeName的别名 |
- 在 Spring 容器中,对于 singleton 作用域的 Bean,容器会负责管理其完整的生命周期,包括创建、初始化、依赖注入、使用、销毁等过程。而对于 prototype 作用域的 Bean,由于每次请求都会创建一个新的实例,因此容器无法管理其完整的生命周期。如果 Spring 容器对于每个 prototype 作用域的 Bean 都要管理其完整的生命周期,那么就会导致性能下降和资源浪费。因此,Spring 选择将 prototype 作用域的 Bean 的生命周期交由调用方来管理,以提高性能和资源利用率。这也是为什么在使用 prototype 作用域时需要特别注意 Bean 实例的生命周期和资源占用情况的原因
- Java 在创建 Java 实例时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会导致系统开销的增加。因此,prototype 作用域 Bean 的创建、销毁代价比较大。而 singleton 作用域的 Bean 实例一旦创建成功,可以重复使用。因此,除非必要,否则尽量避免将 Bean 被设置成 prototype 作用域。
示例
@Controller @RequestMapping(“/test”) @Scope(“prototype”) public class TestController { } |
注
- 对有状态的 bean 应该使用 prototype 作用域,而对无状态的bean则应该使用 singleton 作用域
- singleton 作用域在多线程下是不安全的
- 如果将依赖项原型的 bean 依赖项注入到单例范围的 bean 中,则将实例化新的原型 bean,然后将依赖项注入到单例 bean 中。原型实例是曾经提供给单例范围的 bean 的唯一实例。
- 但是,假设希望单例作用域的 bean 在运行时重复获取原型作用域的 bean 的新实例。不能将原型作用域的 bean 依赖项注入到单例 bean 中,因为当 Spring 容器实例化单例 bean 并解析并注入其依赖项时,该注入仅发生一次。如果在运行时多次需要一个原型 bean 的新实例
- 如果使用 Servlet 2.5 Web 容器,并且在 Spring 的DispatcherServlet之外处理请求(例如,当使用 JSF 或 Struts 时),则需要注册org.springframework.web.context.request.RequestContextListener 和 ServletRequestListener。如果使用 Servlet 3.0,可以使用WebApplicationInitializer接口以编程方式完成此操作。对于较旧的容器,将以下声明添加到 Web 应用程序的web.xml文件中:
<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>
- 如果监听器设置存在问题,请考虑使用 Spring 的RequestContextFilter。过滤器 Map 取决于周围的 Web 应用程序配置,因此必须适当地对其进行更改。以下清单显示了 Web 应用程序的过滤器部分:
<web-app>
...
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
</web-app>