自定义作用域代码

自定义作用域配置

SimpleThreadScope

map删除,应该用remove()吗

spring通过xml实现自定义作用域(自定义双例模式作用域)
SimpleThreadScope:Spring内置作用域。
编写自定义作用域:
步骤1:实现Scope接口(org.springframework.beans.factory.config),主要关注实现的get方法和remove方法。
get方法:按照name参数,按照我们自己定义的规则,去返回一个Bean,如果我们定义的规则里,Bean不存在,那么将通过objectFactory去创建一个Bean。
双例模式:一个bean的Id对应两个实例,实现双例模式,需要两个Map集合,Map<String,Object> map1=new HashMap<String,Object>();Map<String,Object> map2=new HashMap<String,Object>();。


org.springframework.beans.factory.config

代码回顾
SimpThreadScope
代码回顾
自定义作用域(spring.xml部分)
代码回顾
自定义作用域(自定义类部分)
测试方法,如图
创建线程的方法为
new Thread(new Runnable() {
@Override
public void run() {
Bean bean = context.getBean("bean",Bean.class);
System.out.println("bean = " + bean);
}
}).start();
使用SimpleThreadScope作用域
该作用域的作用是,在每一个线程里spring会提供一个全新的实例。在同一个线程多次向spring上下文申请实例的时候spring会提供同一个实例。但如果在多个线程里面每一个线程都向spring上下文申请一个实例,那么spring会给每一个线程申请一个新的实例。
先定义出SimpleThreadScope的实例
<bean class="org.springframework.context.support.SimpleThreadScope" id="SimpleThreadScope"/>
然后再在CustomScopeConfigurer的实例中加上
<entry key="simplethreadScope" value-ref="SimpleThreadScope"/>
在spring.xml中,修改
<bean class="com.imooc.spring.ioc.class009.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"/> </map> </property> </bean> <bean id="bean" class="com.imooc.spring.ioc.class009.Bean" scope="myScope"/>
自定义作用域
需要引用Scope接口,注意是
import org.springframework.beans.factory.config.Scope;
然后实现这个接口的方法。
重点关注get 和 remove方法,如图为实现双例模式(每一个Bean对应两个实例)。
public Object get(String s, ObjectFactory<?> objectFactory) {
if(!map1.containsKey(s)){
Object o = objectFactory.getObject();
map1.put(s,o);
return o;
}
if(!map2.containsKey(s)){
Object o = objectFactory.getObject();
map2.put(s,o);
return o;
}
//若map1 和 map2都存在s,则随机返回一个
int i = new Random().nextInt(2);//0 or 1
if(i == 0){
return map1.get(s);
}else {
return map2.get(s);
}
}
public Object remove(String s) {
if(map2.containsKey(s)){
Object o=map2.get(s);
map2.remove(s);
return o;
}
if(map1.containsKey(s)){
Object o=map1.get(s);
map1.remove(s);
return o;
}
return null;
}
2-5 自定义作用域
自定义作用域,singleThreadScope
自定义实例
<!--自定义作用域--> <bean id="Myscope" class="com.imooc.coursescore1108.video19053.MyScope"></bean> <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"> <property name="scopes"> <map> <entry key="myscope" value-ref="Myscope"></entry> </map> </property> </bean> <bean id="scopebean" class="com.imooc.coursescore1108.video19053.MyScopeBean" scope="myscope"></bean>

内置作用域 simpleThreadScope
使用自定义
实现方法,重点关注get和remove方法
spring内置的SimpleThreadScope,每个线程都会创建一个单独的实例,它和 java.lang.ThreadLocal 所实现的功能很像,但是也有细微的区别
创建和使用自定义的作用域:
自定义作用域:实现org.springframework.beans.factory.config.Scope
spring通过xml实现自定义作用域(自定义双例模式作用域)
SimpleThreadScope:Spring内置作用域。
编写自定义作用域:
步骤1:实现Scope接口(org.springframework.beans.factory.config),主要关注实现的get方法和remove方法。
get方法:按照name参数,按照我们自己定义的规则,去返回一个Bean,如果我们定义的规则里,Bean不存在,那么将通过objectFactory去创建一个Bean。
双例模式:一个bean的Id对应两个实例,实现双例模式,需要两个Map集合,Map<String,Object> map1=new HashMap<String,Object>();Map<String,Object> map2=new HashMap<String,Object>();。
get方法:
public Object get(String name, ObjectFactory<?> objectFactory) {
if(!map1.containsKey(name)){ //判断map1是否包含名为name的Bean实例
Object o=objectFactory.getObject();//如果不存在则创建一个ObjectFactory规则Bean
map1.put(name, o); //并把这个Bean放入集合,并命名为name
return o;
}
if(!map2.containsKey(name)){ //map2同map1操作
Object o=objectFactory.getObject();
map2.put(name, o);
return o;
}
//如果map1和map2都包含这个Bean,也就是说Spring上下文通过Id获取有两个实例,则返回一个0或1
int i=new Random().nextInt(2);
if(i==0){
return map1.get(name);//如果是0,则返回对象1
}else{
return map2.get(name);//如果是0,则返回对象2
}
}
remove方法:和get方法相反,按照name参数,去移除一个Bean。
public Object remove(String name) {
if(map1.containsKey(name)){
Object o=map1.get(name);
map1.remove(name);
return o;
}
if(map2.containsKey(name)){
Object o=map2.get(name);
map2.remove(name);
return o;
}
return null; //说明没拿到任何实例
}
xml配置:
<bean id="myScope" class="main.java.com.自定义作用域.MyScope" >
</bean>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="myscope" value-ref="myScope"></entry>
</map>
</property>
</bean>
测试代码:
@Test
public void testBean(){
ApplicationContext ac=new ClassPathXmlApplicationContext("spring-zidingyi.xml");
for(int i=0;i<10;i++){
Bean bean=ac.getBean(“myScope”", Bean.class);
System.out.println(bean);
}
}
Spring提供的另外一个作用域:SimpleThreadScope(同一线程,Spring上下文会分配同一实例,不同线程,则获得不同实例。
srping配置:
<bean id="myScope" class="main.java.com.自定义作用域.MyScope" ></bean>
<bean id="simpleThreadScope" class="org.springframework.context.support.SimpleThreadScope"></bean>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="myscope" value-ref="myScope"></entry>
<entry key="simpleThreadScope" value-ref="simpleThreadScope"></entry>
</map>
</property>
</bean>
<bean id="bean11" class="main.java.com.自定义作用域.Bean" scope="simpleThreadScope"></bean>
测试代码:
public void testBean(){
final ApplicationContext ac=new ClassPathXmlApplicationContext("spring-zidingyi.xml");
for(int i=0;i<10;i++){
new Thread(new Runnable(){
@Override
public void run() {
Bean bean=ac.getBean("bean11", Bean.class);
System.out.println(bean);
}
}).start();
}
}
}
SimpleThreadScope(每个线程都会创建一个单独的实例):和java.lang.ThreadLocal类实现的功能很像!
自定义作用域的spring.xml文件配置:
自定义bean的作用域:
实现scope接口即可实现自定义bean作用域
SimpleThreadScope
自定义一个作用域