Spring中Bean的初始化及销毁方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiong9999/article/details/84958508

是什么

Spring中的Bean是由IoC容器来管理,这些Bean在同一个容器中是单例模式的,也就是说为无状态的。

这个单例不同于自己写的单例模式:

  1. 自己写的单例,从加载来说是通过ClassLoader加载并生成单例;
  2. Spring中的单例,仅仅是在这一个Spring容器中为单例。

无状态:不管哪段代码执行、不管有多少并发执行,这个Bean都是一样的。
有状态:程序运行到不同地方、不同线程执行时,这个Bean都有变化。

为什么

由IoC容器来管理程序中的Bean,能有效提高程序的运行效率,不需要在程序中频繁new对象,提高了对象的复用性。

但是,如果必须要用多例Bean怎么办?

1、可以在每次需要这个多例Bean的时候,手动new;
2、Spring中其实有多例的配置及使用


以下为Spring中的多例及初始化

Spring中bean的scope有六种:singleton(默认),prototype,request,session,global session,application。

  1. Bean的两个初始化方式
  • xml配置
   <!-- 单例,scope可以不写 -->
   <bean id="singleton" class="com.demo00.spring.bean.init.Demo" scope="singleton"/>
   <!-- 多例 -->
   <bean id="prototype" class="com.demo00.spring.bean.init.Demo" scope="prototype"/>
  • @Bean注解配置
	@Bean(name = {"myBean", "myBean2"})
	@Scope("prototype")//这个如果不写,为单例
    private Demo getTestBean() {
        return new Demo("hello bean!");
    }

再来说说初始化的一些不同细节

以xml形式来初始化Bean为例,
如果初始化时,想要自定义这个Bean的一些属性,有两种方式:

  1. 自定义初始化方法
<bean id="initBean" class="com.demo00.spring.bean.init.Demo" init-method="init">
	<property name="message" value="为Demo对象中的属性message赋值"/>
</bean>
public class Demo {
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public void init() {
        this.setMessage("初始化方法init()来给属性赋值");
    }
}

注意:

  • 这里是在xml中的bean标签中添加了一个属性为init-method,这是bean标签自带的,对应的值为在Bean中的方法名。
  • 这里,既在xml中添加了要赋值的内容,又在Bean代码中添加了要赋值的内容,根据加载流程知道,最后一个赋值的是代码中的。

加载顺序:

扫描二维码关注公众号,回复: 4565336 查看本文章
xml
Bean代码中在xml指定的方法
Bean对象
  1. 通过实现接口InitializingBean并重写afterPropertiesSet()
<bean id="initBean" class="com.demo00.spring.bean.init.Demo2">
	<property name="message" value="为Demo2对象中的属性message赋值"/>
</bean>
import org.springframework.beans.factory.InitializingBean;

public class Demo2 implements InitializingBean {
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    @Override
    public void afterPropertiesSet() {
        this.setMessage("在这里通过重写方法,在初始化时完成对属性赋值");
    }
}

加载顺序:

xml
Bean代码中重写的方法
Bean对象

问题:

如果在xml中配置了Bean属性的初始值,也配置了初始化的方法名,在代码中也实现并重写了afterPropertiesSet()方法,那最后赋值的是哪个?

<bean id="initBean" class="com.demo00.spring.bean.init.Demo2"  init-method="init">
	<property name="message" value="为Demo2对象中的属性message赋值"/>
</bean>
import org.springframework.beans.factory.InitializingBean;

public class Demo2 implements InitializingBean {
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    @Override
    public void afterPropertiesSet() {
        this.setMessage("在这里通过重写方法,在初始化时完成对属性赋值");
    }
	public void init() {
        this.setMessage("初始化方法init()来给属性赋值");
    }
}

加载顺序:

xml
Bean代码中重写的方法
Bean代码中在xml指定的方法
Bean对象

对Bean的销毁,也就是对容器的销毁

也有两种方式

  1. xml配置
<bean id="initBean" class="com.demo00.spring.bean.init.Demo" init-method="init" destroy-method="cleanup">
	<property name="message" value="为Demo对象中的属性message赋值"/>
</bean>
public class Demo {
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public void init() {
        this.setMessage("初始化方法init()来给属性赋值");
    }
    public void cleanup() {
        //TODO
        System.out.println("销毁这个Bean");
    }
}
  1. 通过实现接口DisposableBean
<bean id="initBean" class="com.demo00.spring.bean.init.Demo2">
	<property name="message" value="为Demo2对象中的属性message赋值"/>
</bean>
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class Demo2 implements InitializingBean, DisposableBean {
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    @Override
    public void afterPropertiesSet() {
        this.setMessage("在这里通过重写方法,在初始化时完成对属性赋值");
    }
     @Override
    public void destroy() {
        //TODO
        System.out.println("销毁这个Bean2");
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/xiong9999/article/details/84958508