Spring配置项<context:component-scan/>和<mvc:annotation-driven/>
<mvc:annotation-driven/>
关于这个标签,网上很多资料的信息都过时了,还是基于Spring3.1以前的版本(现在最新的是5.1.2),通过调试源码查看Log并查资料,总结如下:
其对应的实现类:org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser
它会向Spring容器中注册14个Bean,而其中主要的是下面几个:
1 RequestMappingHandlerMapping 2 BeanNameUrlHandlerMapping 3 RequestMappingHandlerAdapter 4 HttpRequestHandlerAdapter 5 SimpleControllerHandlerAdapter 6 ExceptionHandlerExceptionResolver 7 ResponseStatusExceptionResolver 8 DefaultHandlerExceptionResolver
上面几个Bean实例,都是用来做什么的呢?
关于它们的详细功能,在IDEA中将光标移动到AnnotationDrivenBeanDefinitionParser类名上,按Ctrl+q即可查看类文档。
前两个是HandlerMapping接口的实现类,用来处理请求映射的
- 其中第一个是处理
@RequestMapping
注解的 - 第二个会将controller类的名字映射为请求url
中间三个是用来处理请求的.具体点说就是确定调用哪个controller的哪个方法来处理当前请求
- 第一个处
理@Controller
注解的处理器,支持自定义方法参数和返回值(很酷) - 第二个是处理继承HttpRequestHandler的处理器
- 第三个处理继承自Controller接口的处理器
后面三个是用来处理异常的解析器
另外还将提供以下支持:
① 支持使用ConversionService实例对表单参数进行类型转换;
② 支持使用@NumberFormatannotation,@DateTimeFormat注解完成数据类型的格式化;
③ 支持使用@Valid注解对Java bean实例进行JSR 303验证;
④ 支持使用@RequestBody和@ResponseBody注解
综上,<mvc:annotation-driven/>标签主要是用来帮助我们处理请求映射,决定是哪个controller的哪个方法来处理当前请求,以及异常处理。
而在最新的spring项目中,如果不配置<mvc:annotation-driven/>,应用也可以正常处理请求。原因是什么呢?
经过debug DispatcherServlet的源码,发现如果不配置,spring将从DispatcherServlet.properties这个配置文件中加载默认配置,也是可以将上述的所有类注册到容器中的。
因此<mvc:annotation-driven/>这个标签其实是可以省略不写的。
<context:annotation-config/>
这是一条向Spring容器中注册
AutowiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
PersistenceAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor
这4个BeanPostProcessor.注册这4个BeanPostProcessor的作用,就是为了你的系统能够识别相应的注解。
那么哪些注释依赖这些Bean呢。
如果想使用 @Resource、@PostConstruct、@PreDestroy等注解就必须声明CommonAnnotationBeanPostProcessor。
如果想使用 @PersistenceContext注解,就必须声明PersistenceAnnotationBeanPostProcessor的Bean。
如果想使用 @Autowired注解,那么就必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。
如果想使用 @Required的注解,就必须声明RequiredAnnotationBeanPostProcessor的Bean。
同样,传统的声明方式如下:
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor "/>
但是,就一般而言,这些注解我们是经常使用,比如Antowired,Resuource等注解,如果总是按照传统的方式一条一条的配置,感觉比较繁琐和机械。于是Spring给我们提供了<context:annotation-config/>的简化的配置方式。
注意:即使你使用了<context:annotation-config/>注解,以@Autowired为例,对于需要注入的Bean,仍然还要在xml中手动声明。这样很不方便,因此就引出了下面的<context:component-scan>注解。
<context:component-scan>
<context:component-scan>首先有和<context:annotation-config/>一样的作用,此外,它还可以扫描指定包下的类,将拥有注解的它们注册到Spring容器中。
综上,也就是说,如果用<context:annotation-config/>,我们还需要配置Xml注册Bean,而使用<context:component-scan />的话,注册的步骤都免了,当然前提是我们对需要扫描的类使用的注解(比如@Componet,@Service),而如果同时使用两个配置的话,<context:annotation-config/>会被忽略掉(如果配置了<context:component-scan>,就可以不配置<context:annotation-config/>了)。