詳解Spring Controller autowired Request變量
spring的DI大家比較熟悉了,對(duì)于依賴(lài)注入的實(shí)現(xiàn)也無(wú)須贅述。
那么spring的bean的默認(rèn)scope為singleton,對(duì)于controller來(lái)說(shuō)每次方法中均可以獲得request還是比較有意思的。
對(duì)于方法參數(shù)上的request通過(guò)構(gòu)建方法的參數(shù)可以獲得最新的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. 對(duì)于controller等單實(shí)例變量來(lái)說(shuō)如何動(dòng)態(tài)注入變量呢?spring使用了很聰明的辦法
- 首先request和用戶(hù)請(qǐng)求相關(guān)
- 不同的用戶(hù)同時(shí)訪(fǎng)問(wèn)時(shí)是在不同的線(xiàn)程中
- 保存了用戶(hù)的請(qǐng)求在threadlocal中
- 用戶(hù)獲取該請(qǐng)求需要手動(dòng)調(diào)用threadlocal來(lái)獲取
- 為了幫助用戶(hù)減少重復(fù)代碼,spring可以讓用戶(hù)‘動(dòng)態(tài)'注入request
- 當(dāng)controller在實(shí)例化時(shí),動(dòng)態(tài)注冊(cè)一個(gè)proxy到當(dāng)前request變量中
- 此proxy當(dāng)被使用是可以將所有方法動(dòng)態(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";
}
}
如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
您可能感興趣的文章:- 如何在springMVC的controller中獲取request
- 關(guān)于Spring MVC在Controller層中注入request的坑詳解
- Spring實(shí)現(xiàn)在非controller中獲取request對(duì)象