Bean作用范围
Bean标签简介
作用:
- 配置托管给spring的对象,默认情况下调用类的无参构造函数,若果没有无参构造函数则不能创建成功
属性:
-
id:
指定对象在容器中的标识,将其作为参数传入getBean()
方法可以获取获取对应对象. -
class:
指定类的全类名,默认情况下调用无参构造函数 -
scope:
指定对象的作用范围,可选值如下singleton:
单例对象,默认值prototype:
多例对象request:
将对象存入到web项目的request域
中session:
将对象存入到web项目的session域
中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方法...");
}
}