Spring bean scope --scopes

The scope of spring's bean is mainly used to specify how to create a bean object. The system has implemented five main types, namely: singleton, prototype, request, session and globalSession, of which request, session and globalSession are only available in Used in the web environment  , when you use them in a non-web environment, the system will throw them. IllegalStateException异常, Of course, this can also be defined by yourself.

Note: When using request, session and globalSession, if you are not using springMVC, you need to do a little configuration. The specific method is :

a. If you are using servlet2.4+, then you need to add a RequestContextListener listener to web.xml

Xml code   Favorite code
  1. <web-app>  
  2. ...  
  3. <listener>  
  4.   <listener-class>  
  5.       org.springframework.web.context.request.RequestContextListener  
  6.   </listener-class>  
  7. </listener>  
  8. ...  
  9. </web-app>  

 b. Of course, if you are using an older version, you need to add a RequestContextFilter to web.xml

Xml code   Favorite code
  1. <filter>  
  2.   <filter-name>requestContextFilter</filter-name>  
  3.   <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>  
  4. </filter>  
  5. <filter-mapping>  
  6.   <filter-name>requestContextFilter</filter-name>  
  7.   <url-pattern>/*</url-pattern>  
  8. </filter-mapping>  

 

 

XML-based scope specification:

Xml code   Favorite code
  1. <bean id="test" class="com.xxx.spring.cope.Test" scope="singleton"/>  

 

 

 

1.singleton, the default scope of the system is singleton, which means that only one bean object will be created during the entire request process. After the object is created, it will be saved in the cache of singleton beans, and will be obtained every time it is needed in the future. a bean object.

 

 

It is worth noting that the singleton (singleton) in spring is different from the singleton in the GOF design pattern. The singleton in GOF is that there is only one object under each class loader, while the singleton in spring is each Each spring container (BeanFactory and ApplicationContext) will have an object.

 

2.prototype:

The prototype is not a singleton, it will generate a new object every time there is a new request for the current object.

It is worth noting that when a singleton bean A depends on a prototype bean B, since the singleton bean A will only be initialized once, if a prototype bean B is injected into it when it is initialized, A The owned B will only be initialized once when A is initialized, and the same object B is used every time A uses B, which is a bit contrary to our original idea that B is a prototype, not the result we want , the solution is to make bean A implement an ApplicationContextAware interface, and take a B object from the ApplicationContext every time A needs to use B, and the B object taken at this time will be different each time.

 

Java代码   Favorite code
  1. import org.springframework.beans.BeansException;  
  2. import org.springframework.context.ApplicationContext;  
  3. import org.springframework.context.ApplicationContextAware;  
  4. import org.springframework.stereotype.Component;  
  5.   
  6. @Component  
  7. public class A implements ApplicationContextAware {  
  8.   
  9.     private ApplicationContext applicationContext;  
  10.       
  11.     private B b;  
  12.       
  13.     @Override  
  14.     public void setApplicationContext(ApplicationContext applicationContext)  
  15.             throws BeansException {  
  16.         // TODO Auto-generated method stub  
  17.         this.applicationContext = applicationContext;  
  18.     }  
  19.   
  20.     public B getB() {  
  21.         return applicationContext.getBean(B.class);  
  22.     }  
  23.   
  24.     public void setB(B b) {  
  25.         this.b = b;  
  26.     }  
  27.   
  28. }  
Java代码   Favorite code
  1. import org.springframework.context.annotation.Scope;  
  2. import org.springframework.stereotype.Component;  
  3.   
  4. @Component  
  5. @Scope("prototype")  
  6. public class B {  
  7.     //类里面的其他内容  
  8. }  

 

 

3、request:

先看下面这样一个bean定义:

Xml代码   Favorite code
  1. <bean id="loginAction" class="com.xxx.LoginAction" scope="request"/>  

 上面的情况,在每次有一个http Request请求LoginAction的时候,spring容器都会新建一个全新的LoginAction对象。这就是Request级别的scope。由于每个请求都对应一个全新的LoginAction对象,所以在请求过程中,你可以随意改变其中包含的实例属性。当一次Request请求完毕之后,其对应的LoginAction对象也就被销毁了。

 

4、session:

先看下面这样一个bean定义:

Java代码   Favorite code
  1. <bean id="UserService" class="com.xxx.UserService" scope="session"/>  

 在上面这种情况,spring容器会为每个处于活跃状态的http Session创建一个UserService对象,这就是session级别的scope。其是和httpSession一起销毁的。

 

5.globalSession:

先看下面这样一个bean定义:

Java代码   Favorite code
  1. <bean id="UserService" class="com.xxx.UserService" scope="globalSession"/>  

globalSession表示在一个全局的HttpSession下会拥有一个单独的实例,通常用于Portlet环境下。

 

 

当需要把一个http级别的scope的对象注入到其他bean中的时候,需要在声明的http级别的scope的对象中加入<aop:scoped-proxy/>,如下面的userPreferences对象

 

Xml代码   Favorite code
  1. <!-- an HTTP Session-scoped bean exposed as a proxy -->  
  2.   <bean id="userPreferences" class="com.foo.UserPreferences" scope="session">  
  3.   
  4.         <!-- this next element effects the proxying of the surrounding bean -->  
  5.         <aop:scoped-proxy/>  
  6.   </bean>  
  7.   
  8.   <!-- a singleton-scoped bean injected with a proxy to the above bean -->  
  9.   <bean id="userService" class="com.foo.SimpleUserService">  
  10.   
  11.       <!-- a reference to the proxied userPreferences bean -->  
  12.       <property name="userPreferences" ref="userPreferences"/>  
  13.   
  14.   </bean>  

这样做的原因 是正常情况下singleton的userService中有一个session级别的对象,这样singleton的userService只初始化一次,而其所依赖的session级别的userPreferences也只初始化一次。这就与我们所定义的每个session对应一个对象的初衷相违背了,而使用<aop:scoped-proxy/>的时候,就会在实际调用的时候每次使用代理去代理userPreferences调用其对应的方法,代理访问的是对应的session中的对象,这样就可以实现每个session对应一个对象。而在代理的时候有两种方式,一种是基于JDK的interface的,一种是CGLIB形式的,如果要代理的类是面向对象的,就可以直接使用JDK的代理,否则就需要开启对CGLIB代理的支持,同时要引入CGLIB的jar包。

Xml代码   Favorite code
  1. <bean id="userPreferences" class="com.foo.DefaultUserPreferences" scope="session">  
  2.   <aop:scoped-proxy proxy-target-class="false"/><!-- 为true则为开启对CGLIB的支持  -->  
  3. </bean>  

 

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327094698&siteId=291194637