文章目錄
- Bean作用範圍
-
- Bean标簽簡介
- Bean标簽的scope屬性
- 單例對象産生的線程安全問題
Bean作用範圍
Bean标簽簡介
作用:
- 配置托管給spring的對象,預設情況下調用類的無參構造函數,若果沒有無參構造函數則不能建立成功
屬性:
-
指定對象在容器中的辨別,将其作為參數傳入id:
方法可以擷取擷取對應對象.getBean()
-
指定類的全類名,預設情況下調用無參構造函數class:
-
指定對象的作用範圍,可選值如下scope:
-
單例對象,預設值singleton:
-
多例對象prototype:
-
将對象存入到web項目的request:
中request域
-
将對象存入到web項目的session:
中session域
-
将對象存入到web項目叢集的global session:
中,若不存在叢集,則session域
相當于global session
session
-
-
:指定類中的初始化方法名稱,在對象建立成功之後執行init-method
-
指定類中銷毀方法名稱,對prototype多例對象沒有作用,因為多利對象的銷毀時機不受容器控制destroy-method:
Bean标簽的scope屬性
1、scope=“singleton”:單例對象
- 每個應用隻有一個該對象的執行個體,它的作用範圍就是整個應用
注:singleton是scope的預設值
示例
xml檔案
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="p" class="com.jp.domain.Person" scope="singleton"></bean>
</beans>
代碼
package com.jp.scope;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.jp.domain.Person;
public class Demo {
@Test
public void testScope(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Person p = (Person) ac.getBean("p");
Person p1 = (Person) ac.getBean("p");
Person p2 = (Person) ac.getBean("p");
System.out.println(p);
System.out.println(p1);
System.out.println(p2);
}
}
2、scope=“prototype”:多例對象
- 每次通路對象時,都會重新建立對象執行個體.
示例
xml檔案
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="p" class="com.jp.domain.Person" scope="prototype"></bean>
</beans>
代碼
package com.jp.scope;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.jp.domain.Person;
public class Demo {
@Test
public void testScope(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Person p = (Person) ac.getBean("p");
Person p1 = (Person) ac.getBean("p");
Person p2 = (Person) ac.getBean("p");
System.out.println(p);
System.out.println(p1);
System.out.println(p2);
}
}
3、scope=“request”()
- 每次HTTP請求時建立一個執行個體
4、scope="session"
- 針對每個HTPP session建立一個執行個體
單例對象産生的線程安全問題
帶來的問題
單例模式下,因為每個應用隻有一個執行個體,是以在對象實體類的成員位置進行增删改,可能會引發線程安全問題。
解決辦法
寫在函數内部(局部位置)則不會引發線程安全問題,這是因為對象每一次調用函數,都會在棧空間中開辟空間,函數調用完就退出,生命周期短
代碼
package com.jp.domain;
import java.util.ArrayList;
import java.util.List;
public class Person {
private String name;
//如果對list進行增删改,可能引發線程安全問題。
//public List<String> list = new ArrayList<String>();
//無參構造
public Person() {
}
//有參構造
public Person(String name) {
this.name = name;
}
public void talk(){
//這樣可以解決線程安全問題
List list = new ArrayList();
System.out.println("talk方法...");
}
}