/** * Return an instance (possibly shared or independent) * of the object managed by this factory. * @return an instance of the bean (should never be {@code null}) * @throws BeansException in case of creation errors */ T getObject()throws BeansException;
publicabstractclassWebApplicationContextUtils{ /** * Factory that exposes the current request object on demand. */ @SuppressWarnings("serial") privatestaticclassRequestObjectFactoryimplementsObjectFactory<ServletRequest>, Serializable{
@Override public ServletRequest getObject(){ return currentRequestAttributes().getRequest(); }
@Override public String toString(){ return"Current HttpServletRequest"; } }
/** * Factory that exposes the current response object on demand. */ @SuppressWarnings("serial") privatestaticclassResponseObjectFactoryimplementsObjectFactory<ServletResponse>, Serializable{
@Override public ServletResponse getObject(){ ServletResponse response = currentRequestAttributes().getResponse(); if (response == null) { thrownew IllegalStateException("Current servlet response not available - " + "consider using RequestContextFilter instead of RequestContextListener"); } return response; }
@Override public String toString(){ return"Current HttpServletResponse"; } }
/** * Factory that exposes the current session object on demand. */ @SuppressWarnings("serial") privatestaticclassSessionObjectFactoryimplementsObjectFactory<HttpSession>, Serializable{
@Override public HttpSession getObject(){ return currentRequestAttributes().getRequest().getSession(); }
@Override public String toString(){ return"Current HttpSession"; } }
/** * Factory that exposes the current WebRequest object on demand. */ @SuppressWarnings("serial") privatestaticclassWebRequestObjectFactoryimplementsObjectFactory<WebRequest>, Serializable{
publicabstractclassAbstractApplicationContextextendsDefaultResourceLoader implementsConfigurableApplicationContext, DisposableBean{ @Override publicvoidrefresh()throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh();
// Tell the subclass to refresh the internal bean factory. // 加载Bean信息,并添加到容器中 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory);
try { // Allows post-processing of the bean factory in context subclasses. // 调用子类重写的方法 postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory);
// Initialize message source for this context. initMessageSource();
// Initialize event multicaster for this context. initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses. onRefresh();
// Check for listener beans and register them. registerListeners();
// Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); }
// Destroy already created singletons to avoid dangling resources. destroyBeans();
// Reset 'active' flag. cancelRefresh(ex);
// Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } } /** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for registering special * BeanPostProcessors etc in certain ApplicationContext implementations. * @param beanFactory the bean factory used by the application context */ protectedvoidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory){ } }
/** * 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 */ publicstaticvoidregisterWebApplicationScopes(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(ServletResponse.class, new ResponseObjectFactory()); beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory()); beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory()); if (jsfPresent) { FacesDependencyRegistrar.registerFacesDependencies(beanFactory); } } }
publicclassDefaultListableBeanFactoryextendsAbstractAutowireCapableBeanFactory implementsConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable{ /** Map from dependency type to corresponding autowired value */ privatefinal Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<Class<?>, Object>(16); @Override publicvoidregisterResolvableDependency(Class<?> dependencyType, Object autowiredValue){ Assert.notNull(dependencyType, "Dependency type must not be null"); if (autowiredValue != null) { if (!(autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue))) { thrownew IllegalArgumentException("Value [" + autowiredValue + "] does not implement specified dependency type [" + dependencyType.getName() + "]"); } this.resolvableDependencies.put(dependencyType, autowiredValue); } } /** * Find bean instances that match the required type. * Called during autowiring for the specified bean. * @param beanName the name of the bean that is about to be wired * @param requiredType the actual type of bean to look for * (may be an array component type or collection element type) * @param descriptor the descriptor of the dependency to resolve * @return a Map of candidate names and candidate instances that match * the required type (never {@code null}) * @throws BeansException in case of errors * @see #autowireByType * @see #autowireConstructor */ protected Map<String, Object> findAutowireCandidates( String beanName, Class<?> requiredType, DependencyDescriptor descriptor){
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length); for (Class<?> autowiringType : this.resolvableDependencies.keySet()) { // 判断当前依赖Bean类型requiredType是否是autowiringType及其子类 if (autowiringType.isAssignableFrom(requiredType)) { // 如果是则使用映射关系值,如:RequestObjectFactory等 Object autowiringValue = this.resolvableDependencies.get(autowiringType); // 关键步骤:生成JDK动态代理 autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); if (requiredType.isInstance(autowiringValue)) { result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); break; } } } for (String candidate : candidateNames) { if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) { // Consider fallback matches if the first pass failed to find anything... DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch(); for (String candidate : candidateNames) { if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty()) { // Consider self references as a final pass... // but in the case of a dependency collection, not the very same bean itself. for (String candidate : candidateNames) { if (isSelfReference(beanName, candidate) && (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) && isAutowireCandidate(candidate, fallbackDescriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } } } return result; } }
abstractclassAutowireUtils{ /** * Resolve the given autowiring value against the given required type, * e.g. an {@link ObjectFactory} value to its actual object result. * @param autowiringValue the value to resolve * @param requiredType the type to assign the result to * @return the resolved value */ publicstatic Object resolveAutowiringValue(Object autowiringValue, Class<?> requiredType){ if (autowiringValue instanceof ObjectFactory && !requiredType.isInstance(autowiringValue)) { ObjectFactory<?> factory = (ObjectFactory<?>) autowiringValue; if (autowiringValue instanceof Serializable && requiredType.isInterface()) { // 如果是接口则生成基于JDK的动态代理 autowiringValue = Proxy.newProxyInstance(requiredType.getClassLoader(), new Class<?>[] {requiredType}, new ObjectFactoryDelegatingInvocationHandler(factory)); } else { // 不是接口则返回factory.getObject()对象 return factory.getObject(); } } // 返回原始值 return autowiringValue; } /** * Reflective InvocationHandler for lazy access to the current target object. */ @SuppressWarnings("serial") privatestaticclassObjectFactoryDelegatingInvocationHandlerimplementsInvocationHandler, Serializable{
/** * Factory that exposes the current request object on demand. */ @SuppressWarnings("serial") privatestaticclassRequestObjectFactoryimplementsObjectFactory<ServletRequest>, Serializable{
@Override public ServletRequest getObject(){ return currentRequestAttributes().getRequest(); }
@Override public String toString(){ return"Current HttpServletRequest"; } } /** * RequestContextHolder 从当前请求上下文中获取真实的Request,Response,Session等对象 * Return the current RequestAttributes instance as ServletRequestAttributes. * @see RequestContextHolder#currentRequestAttributes() */ privatestatic ServletRequestAttributes currentRequestAttributes(){ RequestAttributes requestAttr = RequestContextHolder.currentRequestAttributes(); if (!(requestAttr instanceof ServletRequestAttributes)) { thrownew IllegalStateException("Current request is not a servlet request"); } return (ServletRequestAttributes) requestAttr; }
publicabstractclassRequestContextHolder{ privatestaticfinal ThreadLocal<RequestAttributes> requestAttributesHolder = new NamedThreadLocal<RequestAttributes>("Request attributes");
privatestaticfinal ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder = new NamedInheritableThreadLocal<RequestAttributes>("Request context"); /** * Bind the given RequestAttributes to the current thread. * @param attributes the RequestAttributes to expose, * or {@code null} to reset the thread-bound context * @param inheritable whether to expose the RequestAttributes as inheritable * for child threads (using an {@link InheritableThreadLocal}) */ publicstaticvoidsetRequestAttributes(RequestAttributes attributes, boolean inheritable){ if (attributes == null) { resetRequestAttributes(); } else { if (inheritable) { inheritableRequestAttributesHolder.set(attributes); requestAttributesHolder.remove(); } else { requestAttributesHolder.set(attributes); inheritableRequestAttributesHolder.remove(); } } }
/** * Return the RequestAttributes currently bound to the thread. * @return the RequestAttributes currently bound to the thread, * or {@code null} if none bound */ publicstatic RequestAttributes getRequestAttributes(){ RequestAttributes attributes = requestAttributesHolder.get(); if (attributes == null) { attributes = inheritableRequestAttributesHolder.get(); } return attributes; }
/** * Return the RequestAttributes currently bound to the thread. * <p>Exposes the previously bound RequestAttributes instance, if any. * Falls back to the current JSF FacesContext, if any. * @return the RequestAttributes currently bound to the thread * @throws IllegalStateException if no RequestAttributes object * is bound to the current thread * @see #setRequestAttributes * @see ServletRequestAttributes * @see FacesRequestAttributes * @see javax.faces.context.FacesContext#getCurrentInstance() */ publicstatic RequestAttributes currentRequestAttributes()throws IllegalStateException { RequestAttributes attributes = getRequestAttributes(); if (attributes == null) { if (jsfPresent) { attributes = FacesRequestAttributesFactory.getFacesRequestAttributes(); } if (attributes == null) { thrownew 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."); } } return attributes; }