`

DefaultAnnotationHandlerMapping初始化

 
阅读更多

DefaultAnnotationHandlerMapping的继承关系:

DefaultAnnotationHandlerMapping实现了ApplicationContextAware接口,通过IOC实例化后会调用ApplicationContextAwareProcessor的postProcessBeforeInitialization方法完成context的注入。

 

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			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) {
				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}
		}
	}

 

该方法中的prepareBeanFactory方法会完成对factory的各种配置,包括postProcessor的注册:

 

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

 在IOC初始化的流程中会调用doCreateBean方法来实例化bean,在实例化后会调用initializeBean方法对bean进行初始化工作

 

 

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
		Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, new ObjectFactory() {
				public Object getObject() throws BeansException {
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

 

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				public Object run() {
					invokeAwareMethods(beanName, bean);
					return null;
				}
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}
		
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}

		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}

 

 

 

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			result = beanProcessor.postProcessBeforeInitialization(result, beanName);
			if (result == null) {
				return result;
			}
		}
		return result;
	}

 getBeanPostProcessors方法返回的集合中包含了最上面注册过的ApplicationContextAwareProcessor实例

 

 
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
		AccessControlContext acc = null;

		if (System.getSecurityManager() != null &&
				(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
						bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
						bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				public Object run() {
					invokeAwareInterfaces(bean);
					return null;
				}
			}, acc);
		}
		else {
			invokeAwareInterfaces(bean);
		}
		
		return bean;
	}
 
private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof EnvironmentAware) {
				((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
			}
			if (bean instanceof EmbeddedValueResolverAware) {
				((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
						new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
			}
			if (bean instanceof ResourceLoaderAware) {
				((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
			}
			if (bean instanceof ApplicationEventPublisherAware) {
				((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
			}
			if (bean instanceof MessageSourceAware) {
				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
			}
			if (bean instanceof ApplicationContextAware) {
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}
 DefaultAnnotationHandlerMapping继承ApplicationObjectSupport,ApplicationObjectSupport是ApplicationContextAware的一个实现类,实现了setApplicationContext方法:
public final void setApplicationContext(ApplicationContext context) throws BeansException {
		if (context == null && !isContextRequired()) {
			// Reset internal context state.
			this.applicationContext = null;
			this.messageSourceAccessor = null;
		}
		else if (this.applicationContext == null) {
			// Initialize with passed-in context.
			if (!requiredContextClass().isInstance(context)) {
				throw new ApplicationContextException(
						"Invalid application context: needs to be of type [" + requiredContextClass().getName() + "]");
			}
			this.applicationContext = context;
			this.messageSourceAccessor = new MessageSourceAccessor(context);
			initApplicationContext(context);
		}
		else {
			// Ignore reinitialization if same context passed in.
			if (this.applicationContext != context) {
				throw new ApplicationContextException(
						"Cannot reinitialize with different application context: current one is [" +
						this.applicationContext + "], passed-in one is [" + context + "]");
			}
		}
	}
 AbstractDetectingUrlHandlerMapping继承了ApplicationObjectSupport,并重写了initApplicationContext方法:
public void initApplicationContext() throws ApplicationContextException {
		super.initApplicationContext();
		detectHandlers();
	}
  
 detectHandlers方法负责获取context中的所有bean,并解析注解,如果有RequestMaping就注册该url对应一个bean的Map中,在DispatcherServlet启动后就可以通过request找到对应的处理bean了。
protected void detectHandlers() throws BeansException {
		if (logger.isDebugEnabled()) {
			logger.debug("Looking for URL mappings in application context: " + getApplicationContext());
		}
		String[] beanNames = (this.detectHandlersInAncestorContexts ?
				BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
				getApplicationContext().getBeanNamesForType(Object.class));

		// Take any bean name that we can determine URLs for.
		for (String beanName : beanNames) {
			String[] urls = determineUrlsForHandler(beanName);
			if (!ObjectUtils.isEmpty(urls)) {
				// URL paths found: Let's consider it a handler.
				registerHandler(urls, beanName);
			}
			else {
				if (logger.isDebugEnabled()) {
					logger.debug("Rejected bean name '" + beanName + "': no URL paths identified");
				}
			}
		}
	}
 
  • 大小: 36.7 KB
分享到:
评论

相关推荐

    spring3.0MVC注解(附实例).

    此配置不仅展示了如何配置`DefaultAnnotationHandlerMapping`和`AnnotationMethodHandlerAdapter`,还包括了拦截器和自定义初始化器的定义,为注解驱动的MVC应用提供了完整的配置框架。 ### 总结 Spring3.0MVC注解...

    spring mvc

    此外,`web.xml`文件中的配置也是Spring MVC应用程序的关键部分,它定义了`DispatcherServlet`的初始化参数和过滤器等。尽管这里没有提供完整的`web.xml`配置,但通常会包含类似以下的设置: ```xml &lt;!-- ...

    spring

    5. **Spring Boot** - 快速开发现代Spring应用的工具,通过自动配置简化项目初始化。 6. **Spring Tool Suite** - 专为Spring开发设计的集成开发环境,提供了一流的Spring支持。 7. **包结构和组织** - 通过`package...

    spring mvc学习文档

    4. **自定义初始化器** - `webBindingInitializer` 属性用于设置一个自定义的 `WebBindingInitializer`,可以进一步定制数据绑定的行为。例如,`ZfptBindingInitializer` 可能包含了自定义的数据验证规则。 ```xml...

    Spring MVC工作原理 及注解说明1

    `&lt;mvc:annotation-driven /&gt;` 配置元素简化了Spring MVC的初始化,自动注册了DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter,分别用于处理类级别的注解和方法级别的注解。 4. **常用注解**: ...

    Spring_MVC 3.0整理汇总

    DispatcherServlet是Spring_MVC的入口点,它初始化时会创建两个ApplicationContext,一个是父Context,另一个是子Context。父Context用于加载应用范围内的Bean,子Context则包含特定于Spring_MVC的配置。 五、父子...

    从源码的角度来看SpringMVC_从源码的角度来看SpringMVC_

    通过在web.xml中配置DispatcherServlet,我们可以定制其初始化参数,如加载自定义的配置文件。 4. **HandlerMapping** HandlerMapping负责将请求映射到合适的处理器。SpringMVC提供了多种实现,如...

    SourceCode of SpringFramework MCV step by step

    1. 了解`DispatcherServlet`的生命周期,掌握其初始化和请求处理过程。 2. 研究`HandlerMapping`和`HandlerAdapter`,理解它们是如何映射请求和调用Controller的。 3. 分析`ModelAndView`和`ViewResolver`的工作机制...

    springMVC最基础配置[参照].pdf

    在`web.xml`中,你需要定义DispatcherServlet并配置SpringMVC的相关监听器,如`ContextLoaderListener`,用于初始化Spring的ApplicationContext。示例中的`application_spring_mvc.xml`是Spring的配置文件,通常位于...

    springMVC学习笔记

    默认情况下,`DispatcherServlet`会加载`/WEB-INF/&lt;servletName&gt;-servlet.xml`的配置文件来初始化Spring容器。我们可以自定义配置文件的位置和名称。 ```xml xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:...

    springmvc入门

    首先,SpringMVC的初始化通常需要一个`DispatcherServlet`,它是整个框架的入口点。在web.xml文件中,你会看到类似以下的配置: ```xml &lt;servlet-name&gt;springmvc &lt;servlet-class&gt;org.springframework.web....

    MyBatis 3 整合Spring3、SpringMVC.docx

    在`web.xml`中,我们配置了Spring的监听器`ContextLoaderListener`,用于初始化Spring应用上下文,并通过`&lt;context-param&gt;`指定了配置文件的位置。同时,定义了Spring MVC的核心Servlet `DispatcherServlet`,设置...

    SpringMvc简单入门

    - **定义**:`DispatcherServlet` 是 Spring MVC 的入口点,它是一个标准的 Servlet,负责初始化 Spring IoC 容器,以及处理所有的 HTTP 请求和响应。 - **配置**:在 `web.xml` 文件中配置 `DispatcherServlet`,...

    springweb3.0MVC注解(附实例)

    - **ContextLoaderListener**:用于初始化 Spring 应用上下文。配置文件 `applicationContext.xml` 被指定为 Spring 核心容器的配置文件。 - **DispatcherServlet**:Spring Web MVC 的前端控制器,它负责接收 HTTP ...

    springMVCjar包

    `web.xml` 中配置的 `DispatcherServlet` 初始化参数和拦截器链会影响其行为。 5. **处理器映射器(HandlerMapping)**:处理器映射器负责将请求URL映射到合适的控制器方法。例如,`BeanNameUrlHandlerMapping` 和 ...

    SpringMVC3和hibernate3的整合

    - 创建SessionFactoryBean,用于初始化SessionFactory。 - 配置数据源,如使用JNDI或直接创建DataSource。 - **定义实体类和映射文件** - 创建Java实体类,并使用Hibernate的注解进行数据库表映射。 - 编写对应...

    使用SpringMVC返回json字符串的实例讲解

    在web.xml中,需要配置DispatcherServlet来指定SpringMVC的配置文件路径,以及在初始化参数中设置contextConfigLocation来指定Spring的配置文件位置。在DispatcherServlet的初始化参数中,同样可以指定SpringMVC的...

Global site tag (gtag.js) - Google Analytics