Spring 相关

1. spring的bean的scope属性范围  参考:http://jiangshuiy.iteye.com/blog/1667316

原理分析(bean的scope属性范围)


       scope用来声明IOC容器中的对象应该处的限定场景或者说该对象的存活空间,即在IOC容器在对象进入相应的scope之前,生成并装配这些对象,在该对象不再处于这些scope的限定之后,容器通常会销毁这些对象。

 

       Spring容器最初提供了两种bean的scope类型:singleton和prototype,但发布2.0之后,又引入了另外三种scope类 型,即request,session和global session类型。不过这三种类型有所限制,只能在web应用中使用,也就是说,只有在支持web应用的ApplicationContext中使用这 三个scope才是合理的。

       可以使用bean的singleton或scope属性来指定相应对象的scope,其中,scope属性只能在XSD格式的文档生命中使用,类似于如下代码所演示的形式:

 

Xml代码  
DTD:  
<bean id ="mockObject1" class="..." singleton="false" />  
XSD:  
<bean id ="mockObject1" class="..."   scope="prototype" />  
       注意:这里的singleton和设计模式里面的单例模式不一样,标记为singleton的bean是由容器来保证这种类型的bean在同一个容器内只存在一个共享实例,而单例模式则是保证在同一个Classloader中只存在一个这种类型的实例。

 

1. singleton

      singleton类型的bean定义,在一个容器中只存在一个实例,所有对该类型bean的依赖都引用这一单一实例。singleton类型的bean 定义,从容器启动,到他第一次被请求而实例化开始,只要容器不销毁或退出,该类型的bean的单一实例就会一直存活。

       通常情况下,如果你不指定bean的scope,singleton便是容器默认的scope,所以,下面三种配置,形式实际上达成的是同样的效果:

Xml代码  
DTD or XSD:  
<bean id ="mockObject1" class="..." />  
DTD:  
<bean id ="mockObject1" class="..." singleton="true" />  
XSD:  
<bean id ="mockObject1" class="..."   scope="singleton" />  
 

2 prototype

       scope为prototype的bean,容器在接受到该类型的对象的请求的时候,会每次都重新生成一个新的对象给请求方。

       虽然这种类型的对象的实例化以及属性设置等工作都是由容器负责的,但是只要准备完毕,并且对象实例返回给请求方之后,容器就不在拥有当前对象的引用,请 求方需要自己负责当前对象后继生命周期的管理工作,包括该对象的销毁。也就是说,容器每次返回请求方该对象的一个新的实例之后,就由这个对象“自生自灭” 了。

    可以用以下方式定义prototype类型的bean:

Java代码  
DTD:  
<bean id ="mockObject1" class="..." singleton="false" />  
XSD:  
<bean id ="mockObject1" class="..."   scope="prototype" />  
 

3 request ,session和global session

      这三个类型是spring2.0之后新增的,他们不像singleton和prototype那么通用,因为他们只适用于web程序,通常是和XmlWebApplicationContext共同使用。

 

     request:

 

Xml代码  
<bean id ="requestPrecessor" class="...RequestPrecessor"   scope="request" />  
       Spring容器,即XmlWebApplicationContext 会为每个HTTP请求创建一个全新的RequestPrecessor对象,当请求结束后,该对象的生命周期即告结束。当同时有10个HTTP请求进来的 时候,容器会分别针对这10个请求创建10个全新的RequestPrecessor实例,且他们相互之间互不干扰,从不是很严格的意义上 说,request可以看做prototype的一种特例,除了场景更加具体之外,语意上差不多。

 

 

        session:

       对于web应用来说,放到session中最普遍的就是用户的登录信息,对于这种放到session中的信息,我们我们可以使用如下形式的制定scope为session:

 

Xml代码  
<bean id ="userPreferences" class="...UserPreferences"   scope="session" />  
        Spring容器会为每个独立的session创建属于自己的全新的UserPreferences实例,他比request scope的bean会存活更长的时间,其他的方面真是没什么区别。

 

     global session:

 

Xml代码  
<bean id ="userPreferences" class="...UserPreferences"   scope="globalsession" />  
      global session只有应用在基于porlet的web应用程序中才有意义,他映射到porlet的global范围的session,如果普通的 servlet的web 应用中使用了这个scope,容器会把它作为普通的session的scope对待。

(我只是听说过porlet这个词,好像是和servlet类似的一种java web技术,大家以后遇到的时候可以搜一下!)
bean scope

2. 使用Spring @Async异步执行方法  参考:

测试代码:
 
Java代码  
<p>@RunWith(SpringJUnit4ClassRunner.class)</p>@ContextConfiguration(locations = { "/spring/*.xml" })  
public class JobUtilsTest{  
      
    @Autowired  
    private DaoService service;  
  
    @Test  
    public void testAsync() throws Exception {  
        System.out.println("start" );  
        service.update(); // ★ 假设这个方法会比较耗时,需要异步执行  
        System.out.println("end");  
          
          
        Thread.sleep(3000); // 因为junit结束会结束jvm,所以让它等会异步线程  
    }  
}  
 
 DaoService代码:
Java代码  
@Service  
public class DaoService {  
    @Async  
    public void update() {  
        try {  
            Thread.sleep(2000);  
            // do something  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println("operation complete.");  
    }  
}  
 
applicationContext.xml
 
 namespace要注意,加上task
xmlns:task="http://www.springframework.org/schema/task"  
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"
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" xmlns:p="http://www.springframework.org/schema/p"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    http://www.springframework.org/schema/context   
    http://www.springframework.org/schema/context/spring-context-3.0.xsd  
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">  
  
    <context:component-scan base-package="com.chinacache" />  
   
    <task:annotation-driven />  
      
</beans>  
 
输出结果:
 
start
end
operation complete.
 
可以看出,输出不是顺序执行,说明异步调用成功了。
Async

 

posted on 2014-05-12 11:29  王健男  阅读(248)  评论(0编辑  收藏  举报