天天看點

Spring總結——Bean的作用範圍Bean作用範圍

文章目錄

  • Bean作用範圍
    • Bean标簽簡介
    • Bean标簽的scope屬性
    • 單例對象産生的線程安全問題

Bean作用範圍

Bean标簽簡介

作用:

  • 配置托管給spring的對象,預設情況下調用類的無參構造函數,若果沒有無參構造函數則不能建立成功

屬性:

  • id:

    指定對象在容器中的辨別,将其作為參數傳入

    getBean()

    方法可以擷取擷取對應對象.
  • class:

    指定類的全類名,預設情況下調用無參構造函數
  • scope:

    指定對象的作用範圍,可選值如下
    1. singleton:

      單例對象,預設值
    2. prototype:

      多例對象
    3. request:

      将對象存入到web項目的

      request域

    4. session:

      将對象存入到web項目的

      session域

    5. global session:

      将對象存入到web項目叢集的

      session域

      中,若不存在叢集,則

      global session

      相當于

      session

  • init-method

    :指定類中的初始化方法名稱,在對象建立成功之後執行
  • destroy-method:

    指定類中銷毀方法名稱,對prototype多例對象沒有作用,因為多利對象的銷毀時機不受容器控制

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方法...");
	}
}