zoukankan      html  css  js  c++  java
  • spring Bean的作用域

      在默认的情况下,Spring IoC容器只会对一个Bean创建一个实例,比如下面的测试:

    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig2.class);
    RoleDataSourceService RoleService = context.getBean(RoleDataSourceService.class);
    RoleDataSourceService RoleService2 = context.getBean(RoleDataSourceService.class);
    System.out.println("RoleService == RoleService2:" + (RoleService == RoleService2));

      这里我们通过类型两次从Spring IoC容器中取出Bean,然后通过==比较,这是一个位比较。换句话说,就是比较RoleService和RoleService2是否为同一个对象,经过测试它的结果为true。
    在默认的情况下,Spring IoC容器只会为配置的Bean生成一个实例,而不是多个。

      有时候我们希望能够通过Spring IoC容器中获取多个实例,比如Struts2(现在它的使用已经比较少了)中的Action(Struts2的控制层类),它往往绑定了从页面请求过来的订单。如果它也是一个实例,那么订单就从头到尾只有一个,而不是多个,这样就不能满足互联网的并发要求了。为了解决这个问题,有时候我们希望Action是多个实例,每当我们请求的时候就产生一个独立的对象,而不是默认的一个,这样多个实例就可以在不同的线程运行了,就没有并发问题了。关于这些是由Spring的作用域所决定的。
      Spring提供了4种作用域,它会根据情况来决定是否生成新的对象。
      •单例(singleton):它是默认的选项,在整个应用中,Spring只为其生成一个Bean的实例。
      •原型(prototype):当每次注入,或者通过Spring IoC容器获取Bean时,Spring都会为它创建一个新的实例。
      •会话(session):在Web应用中使用,就是在会话过程中Spring只创建一个实例。
      •请求(request):在Web应用中使用的,就是在一次请求中Spring会创建一个实例,但是不同的请求会创建不同的实例。
      从4种作用域可以看出,对于Struts2的Action而言,使用请求会合理一些。在4种作用域中会话和请求只能在Web应用中使用

      代码清单:给RoleDataSourceServiceImpl声明原型

    import com.ssm.chapter10.annotation.pojo.Role;
    import com.ssm.chapter10.annotation.service.RoleDataSourceService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.config.ConfigurableBeanFactory;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Component;
    
    import javax.sql.DataSource;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    @Component
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public class RoleDataSourceServiceImpl implements RoleDataSourceService {
    
        @Autowired
        @Qualifier("dataSource2")
        DataSource dataSource = null;
    
        // @Override
        public Role getRole(Long id) {
            Connection conn = null;
            ResultSet rs = null;
            PreparedStatement ps = null;
            Role role = null;
            try {
                conn = dataSource.getConnection();
                ps = conn.prepareStatement("select id, role_name, note from t_role where id = ?");
                ps.setLong(1, id);
                rs = ps.executeQuery();
                while (rs.next()) {
                    role = new Role();
                    role.setId(rs.getLong("id"));
                    role.setRoleName(rs.getString("role_name"));
                    role.setNote(rs.getString("note"));
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                /**********close database resources************/
                try {
                    rs.close();
                    ps.close();
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            return role;
        }
    }

      这是再测试两个对象并非同一个对象,因为我们将其声明为了原型,每当我们从Spring IoC容器中获取对象,它就会生成一个新的实例,这样两次获取就获得了不同的对象,于是比较就返回为false了。

  • 相关阅读:
    Java注释中TODO/FIXME/XXX的含义
    关于update set from where
    WEB打印控件Lodop
    jQuery自动完成组建Autocomplete
    Java触发器CronTrigger
    JVM知识点
    JAVA_OPTS
    java.lang.NoClassDefFoundError:TagSupport
    $SVN代码版本管理工具的使用
    $Eclipse+Tomcat搭建本地服务器并跑通HelloWorld程序
  • 原文地址:https://www.cnblogs.com/ooo0/p/10981850.html
Copyright © 2011-2022 走看看