Spring中Bean的初始化及銷燬方式
阿新 • • 發佈:2018-12-19
Spring中Bean的兩種初始化方式
是什麼
Spring中的Bean是由IoC容器來管理,這些Bean在同一個容器中是單例模式的,也就是說為無狀態的。
這個單例不同於自己寫的單例模式:
- 自己寫的單例,從載入來說是通過ClassLoader載入並生成單例;
- Spring中的單例,僅僅是在這一個Spring容器中為單例。
無狀態:不管哪段程式碼執行、不管有多少併發執行,這個Bean都是一樣的。
有狀態:程式執行到不同地方、不同執行緒執行時,這個Bean都有變化。
為什麼
由IoC容器來管理程式中的Bean,能有效提高程式的執行效率,不需要在程式中頻繁new物件,提高了物件的複用性。
但是,如果必須要用多例Bean怎麼辦?
1、可以在每次需要這個多例Bean的時候,手動new;
2、Spring中其實有多例的配置及使用
以下為Spring中的多例及初始化
Spring中bean的scope有六種:singleton(預設),prototype,request,session,global session,application。
- 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的一些屬性,有兩種方式:
- 自定義初始化方法
<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程式碼中添加了要賦值的內容,根據載入流程知道,最後一個賦值的是程式碼中的。
載入順序:
- 通過實現介面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屬性的初始值,也配置了初始化的方法名,在程式碼中也實現並重寫了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()來給屬性賦值");
}
}
載入順序:
對Bean的銷燬,也就是對容器的銷燬
也有兩種方式
- 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");
}
}
- 通過實現介面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");
}
}