Spring-Bean的作用域-request、session和application

Spring-Bean的作用域-request、session和application

一、web-aware

只有当使用web-aware的Spring ApplicationContext实现(如XmlWebApplicationContext)时,requestsessionapplication 的作用域才可用。如果将这些作用域与常规Spring IoC容器(如ClassPathXmlApplicationContext)一起使用,则会抛出一个举报未知bean作用域的IllegalStateException。
在这里插入图片描述
这几个作用域都是基于web,所以在org.springframework.web.context.annotation包下都进行了继承。

  • @RequestScope
  • @SessionScope
  • @ApplicationScope

二、应用场景

  • web服务
  • 同一个用户操作内的资源共享

为了在requestsessionapplication级别(web作用域bean)支持bean的作用域,在定义bean之前需要进行初始化Web配置Configuration。

三、request

Spring容器通过为每个HTTP请求使用bean定义来创建bean的新实例。也就是说,bean的作用域是在HTTP请求级别。可以随心所欲地更改已创建实例的内部状态,因为从相同的bean定义创建的其他实例看不到这些状态更改。它们是针对个别要求的。当请求完成处理时,将丢弃作用域为该请求的bean。

3.1、基于XML

<bean id="loginController" class="com.example.LoginController" scope="request"/>

3.2、基于注解

@Scope("request")
@Controller
public class LoginController{
   private int flag = 0;

    @RequestMapping("/login")
    public int login(){
        return flag++;
    }
}

或者使用@RequestScope

@RestController
@RequestScope
public class LoginController {

    private int flag = 0;

    @RequestMapping("/login")
    public int login(){
        return flag++;
    }
}

启动项目,访问得到的效果与Prototype的一样,每刷新一次页面就会有一个新的请求,创建的是一个新的实例;与Prototype不同的是request不需要开发人员去实现bean后处理器来清除实例,这些生命周期由web容器接管。

四、session

Spring容器通过在单个HTTP会话的生命周期中使用bean定义来创建bean的新实例。换句话说,bean有效地限定在HTTP会话级别。与request作用域内bean一样,可以改变已创建实例的内部状态,即使其他HTTP会话实例也使用相同的实例创建这个bean的定义,它也看不到这些变化,因为他们是特定于一个单独的HTTP会话。当HTTP Session最终被丢弃时,限定在该特定HTTP Session范围内的bean也将被丢弃。

4.1、基于XML

在一个session生命周期内共享操作用户的资源信息。

<bean id="userController" class="com.example.UserController" scope="session"/>

4.2、基于注解

@RestController
@Scope("session")
public class UserController {
    private int flag = 0;
    
    @RequestMapping("/getUser")
    public int getUser(){
        return flag++;
    }

}

或者

@RestController
@SessionScope
public class UserController {
    private int flag = 0;
    
    @RequestMapping("/getUser")
    public int getUser(){
        return flag++;
    }

}

在同一个浏览器上(或者说在同一个Session范围内)多次请求,效果上与Singleton的一样,在一个session生命周期自然结束、清除浏览缓存、不同的浏览器等等操作导致session的结束,再次请求都会获得一个新的实例。

五、application

Spring容器通过对整个web应用使用一次bean定义来创建一个bean的新实例。也就是说,该bean的作用域在ServletContext级别,并存储为常规的ServletContext属性。这有点类似于Spring单例bean,但在两个重要方面不同:

  • 它是每个ServletContext的一个单例,而不是每个Spring ‘ApplicationContext’(在任何给定的web应用程序中可能有几个);

  • 它实际上是暴露的,因此可以作为可见的ServletContext属性。

5.1、基于XML

一个web程序会创建唯一一个ServletContext,他的生命周期从启动应用到关闭应用,也就是说,只要你的web服务没挂,请求获得的都是同一个bean实例。

<bean id="appPreferences" class="com.example.AppPreferences" scope="application"/>

5.2、基于注解

@RestController
@Scope("application")
public class ServletController {
    private int flag = 0;

    @RequestMapping("/get")
    public int login(){
        return flag++;
    }
}

或者

@RestController
@ApplicationScope
public class ServletController {
    private int flag = 0;

    @RequestMapping("/get")
    public int login(){
        return flag++;
    }
}

Spring IoC容器不仅管理对象(bean)的实例化,还管理协作者(或依赖项)的连接。如果想将(例如)一个HTTP Request作用域的bean注入到另一个生命周期较长的作用域bean中,可以选择注入一个AOP代理来代替该作用域bean。也就是说,需要注入一个代理对象,该对象公开与作用域对象相同的公共接口,但也可以从相关作用域(例如HTTP request)检索实际目标对象,并将方法调用委托给实际对象。

你可能感兴趣的:(Spring,Boot,后端,代码案例,spring,java,bean)