课程名称:Spring入门
课程章节:第2章 Spring Bean作用域
课程讲师: 西昆仑
课程内容:
一、自定义作用域
1、自定义作用域
代码示例:
//MyScope.class
public class MyScope implements Scope {
Map<String, Object> map1 = new ConcurrentHashMap<String, Object>();
Map<String, Object> map2 = new ConcurrentHashMap<String, Object>();
//获取一个实例
public Object get(String name, ObjectFactory<?> objectFactory){
if(!map1.containsKey(name)){
Object o = objectFactory.getObject();
map1.put(name, o);
return o;
}
if(!map2.containsKey(name)){
Object o = objectFactory.getObject();
map2.put(name, o);
return o;
}
int i = new Random().nextInt(2);
if(i==0){
return map1.get(name);
}else{
return map2.get(name);
}
}
//移除一个实例
@Nullable
public Object remove(String name){
if(map2.containsKey(name)){
Object o = map2.get(name);
map2.remove(name);
return o;
}
if(map1.containsKey(name)){
Object o = map1.get(name);
map1.remove(name);
return o;
}
return null;
}
}
//spring.xml
<bean class="com.imooc.spring.ioc.class09.MyScope" id="myScope"/>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="myScope" value-ref="myScope"/>
</map>
</property>
</bean>
<bean id="bean" class="com.imooc.spring.ioc.class009.Bean" scope="myScope"/>
//Class009Test.class
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
for(int i=0;i<10;i++){
Bean bean = context.getBean("bean",Bean.class);
System.out.println("bean="+bean);
}
}
运行结果:
2、SimpleThreadScope
//spring.xml
<bean class="com.imooc.spring.ioc.class09.MyScope" id="myScope"/>
<bean class="org.springframework.context.support.SimpleThreadScope" id="simpleThreadScope"/>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="myScope" value-ref="myScope"/>
<entry key="simpleThreadScope" value-ref="simpleThreadScope"/>
</map>
</property>
</bean>
<bean id="bean" class="com.imooc.spring.ioc.class009.Bean" scope="myScope"/>
//Class009Test.class
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
for(int i=0;i<10;i++){
Bean bean = context.getBean("bean",Bean.class);
System.out.println("bean="+bean);
}
for(int i=0;i<10;i++){
new Thread(new Runnable() {
public void Run(){
Bean bean = context.getBean("bean",Bean.class);
System.out.println("bean="+bean);
}
})
}
}
运行结果:
在Prototype作用域下,有多个Bean被创建,每次向Spring上下文请求该Bean都会new一个新的实例。
二、Bean的懒加载
懒加载概念(只对Singleton作用域的bean有效):
Spring容器会在创建容器时提前初始化Singleton作用域的bean。
但是如果Bean被标注了lazy-init="true",则该Bean只有在其被需要的时候才会被初始化。
1)为某个Bean设定懒加载
<bean id="bean2" class="com...Bean" lazy-init="true"/>
2)为所有的Bean设定懒加载
<beans default-lazy-init="true">
……
</beans>
适用场景:如果某个Bean在程序整个运行周期都可能不会被使用,那么可考虑设定该Bean为懒加载
三、Bean初始化
1、Bean初始化
如果需要在Bean初始化之后执行一些逻辑,有两种方法:
使用init-method
让Bean实现InitializingBean接口
2、Bean销毁
如果需要在Bean销毁之前执行一些逻辑,有两种方法:
使用destroy-method
让Bean实现DisposableBean接口
3、使用init-method、destroy-method代码示例
<bean class="com.imocc.spring.ioc.classll.Bean" init-method="onInit" destroy-method="onDestroy" id="bean"/>
运行结果
4、如果所有bean的初始化及销毁方法名称相同,则可在最外层添加
<beans default-init-method="onInit" default-destroy-method="onDestroy">
……
</beans>
课程收获:有了前几节课程的基础,本节课程听着感觉非常细致,容易理解,期待后续的知识学习。