詳解Spring Controller autowired Request變量
spring的DI大家比較熟悉了,對于依賴注入的實現也無須贅述。
那么spring的bean的默認scope為singleton,對于controller來說每次方法中均可以獲得request還是比較有意思的。
對于方法參數上的request通過構建方法的參數可以獲得最新的request
public final Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
if (logger.isTraceEnabled()) {
StringBuilder sb = new StringBuilder("Invoking [");
sb.append(getBeanType().getSimpleName()).append(".");
sb.append(getMethod().getName()).append("] method with arguments ");
sb.append(Arrays.asList(args));
logger.trace(sb.toString());
}
Object returnValue = invoke(args);
if (logger.isTraceEnabled()) {
logger.trace("Method [" + getMethod().getName() + "] returned [" + returnValue + "]");
}
return returnValue;
}
2. 對于controller等單實例變量來說如何動態(tài)注入變量呢?spring使用了很聰明的辦法
- 首先request和用戶請求相關
- 不同的用戶同時訪問時是在不同的線程中
- 保存了用戶的請求在threadlocal中
- 用戶獲取該請求需要手動調用threadlocal來獲取
- 為了幫助用戶減少重復代碼,spring可以讓用戶‘動態(tài)'注入request
- 當controller在實例化時,動態(tài)注冊一個proxy到當前request變量中
- 此proxy當被使用是可以將所有方法動態(tài)路由到threadlocal中該request變量上執(zhí)行
/**
* Register web-specific scopes ("request", "session", "globalSession", "application")
* with the given BeanFactory, as used by the WebApplicationContext.
* @param beanFactory the BeanFactory to configure
* @param sc the ServletContext that we're running within
*/
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory, ServletContext sc) {
beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope(false));
beanFactory.registerScope(WebApplicationContext.SCOPE_GLOBAL_SESSION, new SessionScope(true));
if (sc != null) {
ServletContextScope appScope = new ServletContextScope(sc);
beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
// Register as ServletContext attribute, for ContextCleanupListener to detect it.
sc.setAttribute(ServletContextScope.class.getName(), appScope);
}
beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
if (jsfPresent) {
FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
}
}
/**
* Factory that exposes the current request object on demand.
*/
@SuppressWarnings("serial")
private static class RequestObjectFactory implements ObjectFactoryServletRequest>, Serializable {
public ServletRequest getObject() {
return currentRequestAttributes().getRequest();
}
@Override
public String toString() {
return "Current HttpServletRequest";
}
}
如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
您可能感興趣的文章:- 如何在springMVC的controller中獲取request
- 關于Spring MVC在Controller層中注入request的坑詳解
- Spring實現在非controller中獲取request對象