spring创建Bean对象的控制

Posted 梦里下起了雨夹雪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring创建Bean对象的控制相关的知识,希望对你有一定的参考价值。

1、spring容器中Bean对象的使用范围控制

       a、控制对象创建方式(使用范围),在<bean>元素中使用scope属性控制,scope可以支持singleton或prototype,默认值是singleton

              <bean scope= "singleton"> 该组件在spring容器里只有一个bean对象。每次取出的bean都是同一个bean,相当于单例模式

              <bean scope = "prototype">该组件每次使用getBean("")都会返回一个新的对象

例如我们自定义了一个ExampleBean类:

public class ExampleBean {
   public void execute() {
       System.out.println("调用了execute方法");
   }
}

在applicationContext.xml中进行配置,默认使用scope="singleton"

<!-- 创建一个ExampleBean对象 -->
    <bean id ="example" class="com.zlc.test.ExampleBean"></bean>

我们测试一下每次取出的bean是否为同一个bean:

public static void main(String[] args) {
        String conf = "applicationContext.xml";
        //创建容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext(conf); 
        //得到Example对象
        ExampleBean e1 = ac.getBean("example",ExampleBean.class);
        ExampleBean e2 = ac.getBean("example",ExampleBean.class);
        System.out.println(e1 == e2);    
    }

运行结果:

由此可见:每次我们从容器中取出的对象都是同一个对象


接下来我们将scope改成"prototype",例如:

<!-- 创建一个ExampleBean对象 -->
    <bean id ="example" class="com.zlc.test.ExampleBean" scope="prototype"></bean>

重新运行上面的代码,看看两次取出的对象是否一致,运行结果如下:

由此可知,当scope设置为"prototype"时,每次从Spring容器中获取该对象时,容器都会返回一个新的对象

 2、spring容器中对象(组件)的初始化控制

在某些时候,我们需要在创建完对象后,对其进行一些初始化操作,例如解析某个xml文件,读取某些相关的配置信息等,使用spring容器管理和创建该对象(组件时),我们就可以指定某些初始化控制。

(1)在构造器中进行某些初始化操作,例如:

public class ExampleBean {
   public ExampleBean() {
       System.out.println("正在进行初始化操作。。。。");
   }
   public void execute() {
       System.out.println("调用了execute方法");
   }
}

 

public static void main(String[] args) {
        String conf = "applicationContext.xml";
        //创建容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext(conf); 
        //得到Example对象
        ExampleBean e1 = ac.getBean("example",ExampleBean.class);
        ExampleBean e2 = ac.getBean("example",ExampleBean.class);
        System.out.println(e1 == e2);    
    }

运行代码,我们可以看到在spring使用构造器创建该对象(组件)时,调用了构造器中的初始化方法:

(2)指定某个方法作为初始化方法,例如我们在ExampleBean中新增一个init方法进行初始化操作

public class ExampleBean {
   public ExampleBean() {
       System.out.println("正在进行初始化操作。。。。");
   }
   public void execute() {
       System.out.println("调用了execute方法");
   }
   public void init() {
       System.out.println("正在执行初始化方法中的操作。。。。");
   }
}

在xml文件中我们指定其初始化方法。

<!-- 创建一个ExampleBean对象 -->
    <bean id ="example" class="com.zlc.test.ExampleBean" scope="prototype" init-method = "init"></bean>

运行以上代码,结果如下:

由此可以看出:spring容器创建完对象后,将会执行xml文件中指定的初始化方法,单例模式中初始化方法只会执行一次

 3、指定对象(组件)的销毁方法

在xml文件中,我们为其指定一个属性destroy-method,它指定对象的销毁方法。

<!-- 创建一个ExampleBean对象 -->
    <bean id ="example" class="com.zlc.test.ExampleBean" init-method = "init"
     destroy-method="destroy">
    </bean>

我们试着关闭spring容器对象以触发该单例对象的destroy方法:

public static void main(String[] args) {
        String conf = "applicationContext.xml";
        //创建容器对象
        AbstractApplicationContext ac = new ClassPathXmlApplicationContext(conf); 
        //得到Example对象
        ExampleBean e1 = ac.getBean("example",ExampleBean.class);
        ExampleBean e2= ac.getBean("example",ExampleBean.class);
        ac.close();//释放spring容器对象,它会自动调用单例的destroy方法。
        
    }

运行结果如下:

由此我们可以看出,spring容器在销毁单例对象前,先会去调用该对象指定的destroy方法

注意:只有在销毁单例对象时,才会调用该对象的destroy方法,若其scope设置为:prototype,则不会调用该方法

总结:指定对象的销毁方法,使用<bean destroy-method=""></bean>,在满足以下条件时触发其产生作用:

1、组件对象为单例模式

2、调用AbstractApplicationContext对象的close()方法

 

以上是关于spring创建Bean对象的控制的主要内容,如果未能解决你的问题,请参考以下文章

spring如何控制对象创建的顺序?

spring核心概念

Spring Bean Scope

Spring Bean Scope

spring源码-bean之初始化-1

Spring笔记2