context:annotation-config與mvc:annotation-driven和context:component-scan詳解
現在常用框架中SpringMVC.xml配置是:
<mvc:annotation-driven/>和<context:component-scan>
那麼<context:annotation-config/>
呢?
【1】 <context:annotation-config/>
- 如果你想使用@Autowired註解,那麼就必須事先在 Spring 容器中宣告
AutowiredAnnotationBeanPostProcessor Bean。
-
如果想使用@Resource 、@PostConstruct、@PreDestroy等註解就必須宣告
CommonAnnotationBeanPostProcessor。
-
如果想使用@PersistenceContext註解,就必須宣告
PersistenceAnnotationBeanPostProcessor的Bean。
JPA中你將會遇到這個註解。
-
如果想使用 @Required的註解,就必須宣告
RequiredAnnotationBeanPostProcessor的Bean
。
<context:annotation-config/
>隱式地向 Spring容器註冊這4個BeanPostProcessor:
AutowiredAnnotationBeanPostProcessor、 RequiredAnnotationBeanPostProcessor、 CommonAnnotationBeanPostProcessor以及 PersistenceAnnotationBeanPostProcessor
即<context:annotation- config/>
是用來使上述註解起作用的,也就是說啟用已經在application context中註冊的bean。
之所以這樣說是因為<context:annotation-config />
僅能夠在已經在已經註冊過的bean上面起作用。
對於沒有在spring容器中註冊的bean,它並不能執行任何操作,也就是說如果你並沒有spring容器中註冊過bean(spring配置檔案中配置bean就是註冊(也就是說spring中不存在你想使用的bean)),那麼上述的那些註解並不會在你未註冊過的bean中起作用。
這裡可能會有疑問,比如明明註冊了AutowiredAnnotationBeanPostProcessor
這裡需要注意的是,@Autowired註解在你使用的時候自動注入的前提是,spring容器中已經有了該bean!
那麼你可以隨意在某個controller或者service使用該註解。並非該註解可以無中生有立即造一個bean給你使用!!
【2】<context:component-scan>
<context:component-scan>做了<context:annotation-config>
要做的事情,還額外支援@Component,@Repository,@Service,@Controller @RestController,@ControllerAdvice, and @Configuration
註解。
並且<context:component-scan>
掃描base-package並且在application context中註冊掃描到的使用註解注入的beans。
這裡著重注意第二段話,<context:component-scan>
該註解可以掃描並註冊你使用註解諸如@controller @service @component..
的bean!!!
也就是說,你不用xml中顯示配置,需要的時候儘管用@Resource或者@Autowired來自動注入!!!
所以配置<context:component-scan>
就不需要配置<context:annotation- config/>
!
該標籤的XSD說明見下圖:
【3】 <mvc:annotation-driven/>
至於該項看字首就應該知道是springmvc所需要的註解。
我們找到對應的實現類是:org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser
原始碼示例如下:
/**
* A {@link BeanDefinitionParser} that provides the configuration for the
* {@code <annotation-driven/>} MVC namespace element.
*
* <p>This class registers the following {@link HandlerMapping}s:</p>
* <ul>
* <li>{@link RequestMappingHandlerMapping}
* ordered at 0 for mapping requests to annotated controller methods.
* <li>{@link BeanNameUrlHandlerMapping}
* ordered at 2 to map URL paths to controller bean names.
* </ul>
*
* <p><strong>Note:</strong> Additional HandlerMappings may be registered
* as a result of using the {@code <view-controller>} or the
* {@code <resources>} MVC namespace elements.
*
* <p>This class registers the following {@link HandlerAdapter}s:
* <ul>
* <li>{@link RequestMappingHandlerAdapter}
* for processing requests with annotated controller methods.
* <li>{@link HttpRequestHandlerAdapter}
* for processing requests with {@link HttpRequestHandler}s.
* <li>{@link SimpleControllerHandlerAdapter}
* for processing requests with interface-based {@link Controller}s.
* </ul>
*
* <p>This class registers the following {@link HandlerExceptionResolver}s:
* <ul>
* <li>{@link ExceptionHandlerExceptionResolver} for handling exceptions
* through @{@link ExceptionHandler} methods.
* <li>{@link ResponseStatusExceptionResolver} for exceptions annotated
* with @{@link ResponseStatus}.
* <li>{@link DefaultHandlerExceptionResolver} for resolving known Spring
* exception types
* </ul>
*
* <p>This class registers an {@link org.springframework.util.AntPathMatcher}
* and a {@link org.springframework.web.util.UrlPathHelper} to be used by:
* <ul>
* <li>the {@link RequestMappingHandlerMapping},
* <li>the {@link HandlerMapping} for ViewControllers
* <li>and the {@link HandlerMapping} for serving resources
* </ul>
* Note that those beans can be configured by using the {@code path-matching} MVC namespace element.
*
* <p>Both the {@link RequestMappingHandlerAdapter} and the
* {@link ExceptionHandlerExceptionResolver} are configured with instances of
* the following by default:
* <ul>
* <li>A {@link ContentNegotiationManager}
* <li>A {@link DefaultFormattingConversionService}
* <li>A {@link org.springframework.validation.beanvalidation.LocalValidatorFactoryBean}
* if a JSR-303 implementation is available on the classpath
* <li>A range of {@link HttpMessageConverter}s depending on what 3rd party
* libraries are available on the classpath.
* </ul>
*
* @author Keith Donald
* @author Juergen Hoeller
* @author Arjen Poutsma
* @author Rossen Stoyanchev
* @author Brian Clozel
* @author Agim Emruli
* @since 3.0
*/
class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
public static final String HANDLER_MAPPING_BEAN_NAME = RequestMappingHandlerMapping.class.getName();
public static final String HANDLER_ADAPTER_BEAN_NAME = RequestMappingHandlerAdapter.class.getName();
public static final String CONTENT_NEGOTIATION_MANAGER_BEAN_NAME = "mvcContentNegotiationManager";
通過閱讀類註釋文件,我們發現這個類主要是用來向工廠中註冊了
- RequestMappingHandlerMapping
- BeanNameUrlHandlerMapping
- RequestMappingHandlerAdapter
- HttpRequestHandlerAdapter
- SimpleControllerHandlerAdapter
- ExceptionHandlerExceptionResolver
- ResponseStatusExceptionResolver
- DefaultHandlerExceptionResolver
上面幾個Bean例項。這幾個類都是用來做什麼的呢?
前兩個是HandlerMapping介面的實現類,用來處理請求對映的。
- 其中第一個是處理@RequestMapping註解的。
中間三個是用來處理請求的。具體點說就是確定呼叫哪個controller的哪個方法來處理當前請求。
- 第一個處理@Controller註解的處理器,支援自定義方法引數和返回值(很酷)。
- 第二個是處理繼承HttpRequestHandler的處理器。
- 第三個處理繼承自Controller介面的處理器。
後面三個是用來處理異常的解析器。
另外還將提供以下支援:
① 支援使用ConversionService例項對錶單引數進行型別轉換;
② 支援使用@NumberFormatannotation、@DateTimeFormat註解完成資料型別的格式化;
③ 支援使用@Valid註解對Java bean例項進行JSR 303驗證;
④ 支援使用@RequestBody和@ResponseBody註解
參考<mvc:annotation-driven/>
標籤詳解:部落格地址