Spring bean scope 的几种类型

【正文】

Spring容器最初提供了两种bean的scope类型:singleton和prototype,但发布2.0以后,又引入了另外三种scope类型:request、session和global session,这三种只能在web 应用中才可以使用。

一、基础概念

singleton: 在Spring的IoC容器中只存在一个对象实例,所有该对象的引用都共享这个实例Spring 容器只会创建该bean定义的唯一实例,这个实例会被保存到缓存中,并且对该bean的所有后续请求和引用都将返回该缓存中的对象实例,一般情况下,无状态的bean使用该scope。

prototype:每次对该bean的请求都会创建一个新的实例,一般情况下,有状态的bean使用该scope。
request:每次http请求将会有各自的bean实例,类似于prototype。
session:在一个http session中,一个bean定义对应一个bean实例。
global session:在一个全局的http session中,一个bean定义对应一个bean实例。典型情况下,仅在使用portlet context的时候有效。

其次说明spring的默认scope(bean作用域)是singleton

 

二、自定义scope类型

在spring2.0中作用域是可以任意扩展的,你可以自定义作用域,甚至你也可以重新定义已有的作用域(但是你不能覆盖singleton和 prototype),spring的作用域由接口org.springframework.beans.factory.config.Scope来定 义,自定义自己的作用域只要实现该接口即可,下面给个实例:
我们建立一个线程的scope,该scope在表示一个线程中有效,代码如下:

publicclass MyScope implements Scope { 
      privatefinal ThreadLocal threadScope = new ThreadLocal() {
          protected Object initialValue() {
             returnnew HashMap(); 
           } 
     }; 
     public Object get(String name, ObjectFactory objectFactory) { 
         Map scope = (Map) threadScope.get(); 
         Object object = scope.get(name); 
        if(object==null) { 
           object = objectFactory.getObject(); 
           scope.put(name, object); 
         } 
        return object; 
      } 
     public Object remove(String name) { 
         Map scope = (Map) threadScope.get(); 
        return scope.remove(name); 
      }
      publicvoid registerDestructionCallback(String name, Runnable callback) { 
      }
    public String getConversationId() {
       // TODO Auto-generated method stub
        returnnull;
     } 
}

【总结】

① 问:scope类型什么时候声明为singleton,何时声明为prototype?

默认scope是singleton。

无状态的bean使用该scope。

有状态的bean使用prototype。

有状态和无状态会话bean的本质区别是它们的生命期。

bean保持了用户的信息,即“有状态”

无状态会话bean :bean一旦实例化就被加进会话池中,各个用户都可以共用。由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean。但无状态会话bean 并非没有状态,如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响,这是在实际应用中必须注意的。

② 在ssh2 项目中 , struts2的action交由spring管理的时候 ,spring默认是singleton的 ,而struts2的action显然是有状态的 ,所以必须显示设置为 scope=“prototype”;
但是对那些Dao的实现类推介scope=“singleton” ,因为这些类没有状态,用singleton只需维护一个实例,显然性能高一些。

③ 比较:

用singleton 的性能要高一些 ,因为只有一个实例;

④ 实际应用举例:

之前在开发过程中遇到了一个问题,当request发起下一个请求的时候,action中的属性值并没有清除,而是继续采用上次使用过的参数值进行查询并响应,导致数据查询不真实或失败。对此,有同事告诉我说,需要在spring配置文件的bean中添加属性scope=prototype。结果还真的有用。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringBean是指由Spring容器创建、管理和装配的对象。在Spring中,Bean是一个由Spring IoC容器管理的Java对象Bean可以是任何普通的Java对象,也可以是需要在Spring容器中特殊处理的对象,如DataSource、JdbcTemplate等。 Spring中的Bean装配方式有以下几种: 1. XML配置方式:通过在XML配置文件中定义Bean的信息,然后由Spring容器根据配置文件来创建和管理Bean。 2. 注解方式:通过在Java类中使用注解来定义Bean,然后由Spring容器根据注解来创建和管理Bean。 3. Java Config方式:通过Java类来定义Bean的信息,然后由Spring容器根据Java类来创建和管理Bean。 XML配置方式是Spring中最常用的装配方式,它可以通过`<bean>`标签来定义Bean的信息,如id、class、scope、property等。例如: ```xml <bean id="userService" class="com.example.UserService"> <property name="userDao" ref="userDao"/> </bean> <bean id="userDao" class="com.example.UserDaoImpl"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mydatabase"/> <property name="username" value="root"/> <property name="password" value="password"/> </bean> ``` 注解方式是一种更加简洁、方便的装配方式,它可以通过在Java类中的属性、构造函数、方法上使用注解来定义Bean的信息。例如: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; //... } @Repository public class UserDaoImpl implements UserDao { @Autowired private DataSource dataSource; //... } ``` Java Config方式是一种基于Java类的配置方式,它可以通过Java类来定义Bean的信息,同时也可以通过Java类来配置Bean之间的依赖关系。例如: ```java @Configuration public class AppConfig { @Bean public UserService userService() { UserServiceImpl userService = new UserServiceImpl(); userService.setUserDao(userDao()); return userService; } @Bean public UserDao userDao() { UserDaoImpl userDao = new UserDaoImpl(); userDao.setDataSource(dataSource()); return userDao; } @Bean public DataSource dataSource() { BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/mydatabase"); dataSource.setUsername("root"); dataSource.setPassword("password"); return dataSource; } } ``` 总之,SpringBean是Spring IoC容器管理的Java对象,它可以通过XML配置方式、注解方式、Java Config方式等多种方式进行装配,每种方式都有其特点和适用场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值