Spring scope proxy的使用
Posted on: 2013-10-23, Last modified: 2015-07-31, View: 10608
Posted on: 2013-10-23, Last modified: 2015-07-31, View: 10608
应用场景:
当有时候要在一个长生命周期的bean里面生命一个较短生命周期的应用的时候(例如在一个Singolton的bean里生命一个session bean),如果直接使用会发现创建Bean失败。
@Scope("session") public SessionBean { } @Scope("singoleton") public SingletonBean { @Inject private SessionBean sessionBean } 这时候会抛出这样的异常:
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private SessionBeanSingletonBEan.SessionBean; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'SessionBean': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
解决方案:
1. Lookup method inject 具体可以参考这里
2. 使用代理注入bean, 在调用的时候决定使用哪一个实例化的被引用bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public SessionBean { } @Scope("singoleton") public SingletonBean { @Inject private SessionBean sessionBean }
或者:
<bean name="singletonBean" class="somepkg.SingletonBean"> <property name="someProperty" ref="sessionBean"/> </bean> <bean name="sessionBean" class="somepkg.SessionBean" scope="session"> <aop:scoped-proxy/> </bean>
这个在Refer spring-framework-reference 3.0, Section 3.5 - Bean scopes, Sub topic - Scoped beans as dependencies 中有详细的论述。