Bean的作用域
1、测试:bean的默认管理(singleton)
- 第一步:创建了,自定义无参构造方法
public class SpringBean {
public SpringBean() {
System.out.println("springBean 被创建");
}
}
- 第二步:配置 spring 配置文件,让 spring 管理
<bean id="springBean" class="com.wang.bean.SpringBean"/>
- 第三步:测试
@org.junit.Test
public void scope() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring_scope.xml");
System.out.println("=================");
SpringBean springBean = applicationContext.getBean("springBean", SpringBean.class);
System.out.println(springBean);
//com.wang.bean.SpringBean@1aa7ecca
SpringBean springBean2 = applicationContext.getBean("springBean", SpringBean.class);
System.out.println(springBean2);
//com.wang.bean.SpringBean@1aa7ecca
}
- 第四步:输出结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NGB7bFpw-1691736406890)(C:\Users\ASUS\Desktop\java\4_Spring6\image\1667635833031.png)]
- 总结:
默认
情况下 Bean 都是单例的(singleton)- 在 spring 加载上下文的时候进行实例化
- 每次调用 getBean() 方法的时候,都返回那个 单例的对象
2、设置bean为多例(prototype)(getBean()时创建)
- 第一步:创建了,自定义无参构造方法
public class SpringBean {
public SpringBean() {
System.out.println("springBean 被创建");
}
}
- 第二步:配置 spring 配置文件,让 spring 管理,并且添加
scope ="prototype"
设置多例
- scope 属性有两个值:
- singleton(单例,默认情况)(
启动容器创建对象
)- prototype(多例)(
getBean()时创建对象
)
<!-- 添加 scope = "propotype" 设置多例 -->
<bean id="springBean" class="com.wang.bean.SpringBean" scope="prototype"/>
<!--
scope 属性有两个值:
1:singleton(单例,默认情况)(启动容器创建对象)
2:prototype(多例)(getBean()时创建对象)
-->
- 第三步:测试
@org.junit.Test
public void scope() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring_scope.xml");
System.out.println("=================");
SpringBean springBean = applicationContext.getBean("springBean", SpringBean.class);
System.out.println(springBean);
SpringBean springBean2 = applicationContext.getBean("springBean", SpringBean.class);
System.out.println(springBean2);
}
- 第四步:测试结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ezR6cOd2-1691736406891)(C:\Users\ASUS\Desktop\java\4_Spring6\image\1667636240729.png)]
- 第五步:总结
- 将把 bean 的 scope 属性设置为 prototype 时,spring 不会再加载上下文的时候创建对象,而是再调用 getBean()方法的时候创建新的对象,并且返回 (如果scope属性为prototype则不会在加载配置文件的时候创建bean的对象)
- 每次 getBean()创建的对象都是不同的
- 将把 bean 的 scope 属性设置为 prototype 时,spring 并不会初始化这些· prototype 的 bean
- prototype 翻译为原型
3、scope的其它选择
- 其实 scope 属性有多个值:
- 比如:request,session;但是项目必须是一个web应用,当引入 springmvc 框架的时候,就可以使用了
- request :一次请求中 一个 bean
- session:一次会话一个 bean
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LpiogE5r-1691736406892)(C:\Users\ASUS\Desktop\java\4_Spring6\image\1667640865686.png)]
4、自定义 scope(一个线程一个bean)
4.1、测试再默认情况下的 bean
单例模式
下,再多个线程中,拿到的 bean 对象,任然是单例
的
@org.junit.Test
public void thread() {
//主线程
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring_scope.xml");
SpringBean springBean = applicationContext.getBean("springBean", SpringBean.class);
SpringBean springBean1 = applicationContext.getBean("springBean", SpringBean.class);
System.out.println(springBean);
System.out.println(springBean1);
//子线程
new Thread(new Runnable() {
@Override
public void run() {
SpringBean beanTh = applicationContext.getBean("springBean", SpringBean.class);
SpringBean beanTh1 = applicationContext.getBean("springBean", SpringBean.class);
System.out.println(beanTh);
System.out.println(beanTh1);
}
}).start();
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AYzNjJpD-1691736406893)(C:\Users\ASUS\Desktop\java\4_Spring6\image\1667641297975.png)]
4.2、自定义一个线程一个 bean
- 第一步:自定义 scope(实现 scope接口)
- spring 内置了线程范围的类:SimpleThreadScore,可以直接使用
- 第二步:将自定义的 scope 注册到 spring 容器中
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<!-- scope 作用域的名字-->
<entry key="myThread">
<!-- 内部 bean-->
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>
- 第三步:使用 scope
<bean id="springBean" class="com.wang.bean.SpringBean" scope="myThread"/>
- 第四步:测试
@org.junit.Test
public void thread() {
//主线程
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring_scope.xml");
SpringBean springBean = applicationContext.getBean("springBean", SpringBean.class);
SpringBean springBean1 = applicationContext.getBean("springBean", SpringBean.class);
System.out.println(springBean);
System.out.println(springBean1);
//子线程
new Thread(new Runnable() {
@Override
public void run() {
SpringBean beanTh = applicationContext.getBean("springBean", SpringBean.class);
SpringBean beanTh1 = applicationContext.getBean("springBean", SpringBean.class);
System.out.println(beanTh);
System.out.println(beanTh1);
}
}).start();
}
- 第五步:结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v5cqg44f-1691736406894)(C:\Users\ASUS\Desktop\java\4_Spring6\image\1667641779543.png)]
applicationContext.getBean(“springBean”, SpringBean.class);
System.out.println(beanTh);
System.out.println(beanTh1);
}
}).start();
}
- 第五步:结果
[外链图片转存中...(img-v5cqg44f-1691736406894)]