Spring学习--Bean的作用域

**Bean的作用域**:
    作用域:一般指的是对象或者变量之间的可见范围。而在Spring容器中是指其创建的Bean对象相对于其他Bean对象的请求可见范围。
        Spring提供Singleton和prototype两种基本作用域,另外提供Request、session、global、session三种web作用域;Spring还允许用户制定自己的作用域。
    基本的作用域
        **一:Singleton:**指Singleton作用域的Bean只会在每个S平IOC容器中存在一个实例,而且其完整生命周期完全由Spring容器管理。对于所有获取Bean的操作Spring容器将只返回同一个Bean。

            GoF单例设计模式指“保证一个类仅有一个实例,并提供一个访问它的全局访问点”,介绍了两种实现:通过在类上定义静态属性保持该实例和通过注册表方式。

            **1)通过在类上定义静态属性保持该实例**:一般指一个Java虚拟机 ClassLoader装载的类只有一个实例,一般通过类静态属性保持该实例,这样就造成需要单例的类都需要按照单例设计模式进行编码;Spring没采用这种方式,因为该方式属于侵入式设计;
                package org.liang.test;
                /**
                 * 单例类
                 */
                public class Singleton {
                    private String name;

                    private Singleton(){};
                    public static Singleton getInstance(){
                        return new Singleton();
                    }

                    public String getName() {
                        return name;
                    }

                    public void setName(String name) {
                        this.name = name;
                    }
                }
                class TsetSingleton{
                    public static void main(String [] args){
                        Singleton singleton = Singleton.getInstance();
                        singleton.setName("关羽");
                        System.out.println(singleton.getName());
                    }
                }
            **2) 通过注册表方式:** 首先将需要单例的实例通过唯一键注册到注册表,然后通过键来获取单例,让我们直接看实现吧,注意本注册表实现了Spring接口“SingletonBeanRegistry”,该接口定义了操作共享的单例对象,Spring容器实现将实现此接口;所以共享单例对象通过“registerSingleton”方法注册,通过“getSingleton”方法获取,消除了编程方式单例,注意在实现中不考虑并发。

                package org.liang.test;

                import org.liang.entity.Persion;
                import org.springframework.context.support.ClassPathXmlApplicationContext;

                /**
                 * Created by rcc on 2018/2/2.
                 */
                public class TestScope {
                    public static void main(String [] args){
                        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
                        Persion persion = context.getBean(Persion.class);
                        Persion persion1 = context.getBean(Persion.class);

                        System.out.println(persion == persion1);
                        System.out.println("=======================================================");
                        Persion persion2 = new Persion();
                        Persion persion3 = new Persion();
                        System.out.println(persion2 == persion3);


                        System.out.println("=======================================================");
                        System.out.println(persion);
                        System.out.println(persion1);

                        /**
                         * 返回结果:
                         *      true
                         *======================================================
                         *      false
                         *
                          * 这就很奇怪了是不是,使用容器获得的两个所谓的新的对象居然是同一个对象,这和我们直接new两个对象的结果刚好相反。
                                      * 不过仔细想一想也不奇怪,既然对象是从Spring容器中获取的,会不会是容器在对象创建的时候对对象进行了缓存呢?
                                      *
                                      *  基于这个猜想,我们将对象中的属性打印出来:
                          *
                          *      Persion{name='doudou', nickName='zhuzhu', age=18}
                          *      Persion{name='doudou', nickName='zhuzhu', age=18}
                          *  结果居然一模一样,返回的是同一个对象。
                                      *
                                      *  那么这到底是什么原因呢?
                          *      <bean id="persion" class="org.liang.entity.Persion" scope="singleton">
                                    <constructor-arg index="0" value="doudou"/>
                                    <constructor-arg name="nickName" value="zhuzhu"/>
                                    <constructor-arg type="java.lang.Integer" value="18"/>
                                </bean>
                          *  原因就是这个配置:scope="singleton"  ,表示该对象是单例的,所以容器会缓存对象,每次获取的对象都是同一个。
                                      *  在Spring容器中如果没指定作用域默认就是“singleton”。
                                      */



                    }
                }
        **二、prototype:即原型,**指每次向Spring容器请求获取Bean都返回一个全新的Bean,相对于“singleton”来说就是不缓存Bean,每次都是一个根据Bean定义创建的全新Bean。

            <bean id="user" class="org.liang.entity.User" scope="prototype">
                    <property name="name" value="张三"/>
                    <property name="gender" value="男"/>
                    <property name="age" value="18"/>
                </bean>

            ========================================================================================

            User user = (User) context.getBean("user");
            User user1 = (User) context.getBean("user");
            System.out.println(user == user1);

            /**
        返回结果:
                     * =======================================================
                               false   :每次获取的都是全新的对象
                     */
    **Web应用中的作用域:**

    在Web应用中,我们可能需要将数据存储到request、session、global session。因此Spring提供了三种Web作用域:request、session、globalSession。

    一、request作用域:表示每个请求需要容器创建一个全新Bean。比如提交表单的数据必须是对每次请求新建一个Bean来保持这些表单数据,请求结束释放这些数据。

    二、session作用域:表示每个会话需要容器创建一个全新Bean。比如对于每个用户一般会有一个会话,该用户的用户信息需要存储到会话中,此时可以将该Bean配置为web作用域。

    三、globalSession:类似于session作用域,只是其用于portlet环境的web应用。如果在非portlet环境将视为session作用域。

配置方式和基本的作用域相同,只是必须要有web环境支持,并配置相应的容器监听器或拦截器从而能应用这些作用域,我们会在集成web时讲解具体使用,大家只需要知道有这些作用域就可以了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值