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"); } } } }
相关推荐
此配置不仅展示了如何配置`DefaultAnnotationHandlerMapping`和`AnnotationMethodHandlerAdapter`,还包括了拦截器和自定义初始化器的定义,为注解驱动的MVC应用提供了完整的配置框架。 ### 总结 Spring3.0MVC注解...
此外,`web.xml`文件中的配置也是Spring MVC应用程序的关键部分,它定义了`DispatcherServlet`的初始化参数和过滤器等。尽管这里没有提供完整的`web.xml`配置,但通常会包含类似以下的设置: ```xml <!-- ...
5. **Spring Boot** - 快速开发现代Spring应用的工具,通过自动配置简化项目初始化。 6. **Spring Tool Suite** - 专为Spring开发设计的集成开发环境,提供了一流的Spring支持。 7. **包结构和组织** - 通过`package...
4. **自定义初始化器** - `webBindingInitializer` 属性用于设置一个自定义的 `WebBindingInitializer`,可以进一步定制数据绑定的行为。例如,`ZfptBindingInitializer` 可能包含了自定义的数据验证规则。 ```xml...
`<mvc:annotation-driven />` 配置元素简化了Spring MVC的初始化,自动注册了DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter,分别用于处理类级别的注解和方法级别的注解。 4. **常用注解**: ...
DispatcherServlet是Spring_MVC的入口点,它初始化时会创建两个ApplicationContext,一个是父Context,另一个是子Context。父Context用于加载应用范围内的Bean,子Context则包含特定于Spring_MVC的配置。 五、父子...
通过在web.xml中配置DispatcherServlet,我们可以定制其初始化参数,如加载自定义的配置文件。 4. **HandlerMapping** HandlerMapping负责将请求映射到合适的处理器。SpringMVC提供了多种实现,如...
1. 了解`DispatcherServlet`的生命周期,掌握其初始化和请求处理过程。 2. 研究`HandlerMapping`和`HandlerAdapter`,理解它们是如何映射请求和调用Controller的。 3. 分析`ModelAndView`和`ViewResolver`的工作机制...
在`web.xml`中,你需要定义DispatcherServlet并配置SpringMVC的相关监听器,如`ContextLoaderListener`,用于初始化Spring的ApplicationContext。示例中的`application_spring_mvc.xml`是Spring的配置文件,通常位于...
默认情况下,`DispatcherServlet`会加载`/WEB-INF/<servletName>-servlet.xml`的配置文件来初始化Spring容器。我们可以自定义配置文件的位置和名称。 ```xml xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:...
首先,SpringMVC的初始化通常需要一个`DispatcherServlet`,它是整个框架的入口点。在web.xml文件中,你会看到类似以下的配置: ```xml <servlet-name>springmvc <servlet-class>org.springframework.web....
在`web.xml`中,我们配置了Spring的监听器`ContextLoaderListener`,用于初始化Spring应用上下文,并通过`<context-param>`指定了配置文件的位置。同时,定义了Spring MVC的核心Servlet `DispatcherServlet`,设置...
- **定义**:`DispatcherServlet` 是 Spring MVC 的入口点,它是一个标准的 Servlet,负责初始化 Spring IoC 容器,以及处理所有的 HTTP 请求和响应。 - **配置**:在 `web.xml` 文件中配置 `DispatcherServlet`,...
- **ContextLoaderListener**:用于初始化 Spring 应用上下文。配置文件 `applicationContext.xml` 被指定为 Spring 核心容器的配置文件。 - **DispatcherServlet**:Spring Web MVC 的前端控制器,它负责接收 HTTP ...
`web.xml` 中配置的 `DispatcherServlet` 初始化参数和拦截器链会影响其行为。 5. **处理器映射器(HandlerMapping)**:处理器映射器负责将请求URL映射到合适的控制器方法。例如,`BeanNameUrlHandlerMapping` 和 ...
- 创建SessionFactoryBean,用于初始化SessionFactory。 - 配置数据源,如使用JNDI或直接创建DataSource。 - **定义实体类和映射文件** - 创建Java实体类,并使用Hibernate的注解进行数据库表映射。 - 编写对应...
在web.xml中,需要配置DispatcherServlet来指定SpringMVC的配置文件路径,以及在初始化参数中设置contextConfigLocation来指定Spring的配置文件位置。在DispatcherServlet的初始化参数中,同样可以指定SpringMVC的...