解决要点:
一、In short, the context loaded by the ContextLoaderListener (generally from applicationContext.xml) is the parent of the context loaded by the DispatcherServlet (generally from *-servlet.xml). If you have the bean with the @Async method declared/component-scanned in both contexts, the version from the child context (DispatcherServlet) will override the one in the parent context (ContextLoaderListener). I verified this by excluding that component from component scanning in the *-servlet.xml -- it now works as expected.
要点:注意component-scan里面扫包不要重复扫。