If you create and close the ApplicationContext properly the LifecycleProcessor should handle the shutdown for you. How did you create the context (best practice would be to use a ContextLoaderListener and/or a DispatcherServlet)? How did you attempt to shutdown Tomcat?
Something to try: whack up the debug level and look for a log during shutdown like this:
If you don't see that then the context isn't closing. If you do then there may be something more interesting going on.
DEBUG [org.springframework.beans.factory.support.DisposableBeanAdapter] - <Invoking destroy() on bean with name 'org.springframework.scheduling.config.ScheduledTaskRegistrar#0'>
Something else to try: load the same application context in a unit test, and verify the behaviour. Post the test if it doesn't shutdown cleanly.