The main reason you'd want to use Java based container initialization is when you want to register Spring managed Servlet, Filter, and XxxListener objects.
For example, when you want to register a ServletContextListener, you specify
<listener>
com.your.listeners.MyListener
</listener>
in the deployment descriptor. The container takes that fully qualified class name and uses reflection to find the corresponding Class object which it instantiates to get an instance. In other words, the object is uniquely managed by the container. You can't have Spring inject fields easily.
On the other hand, with a ServletContainerInitializer, or the corresponding Spring class, you can specify Servlet, Filter, or Listener beans in your Spring context (either through XML or @Configuration classes) and register those Spring-managed instances directly through the ServletContext.
Note that there are still some configurations for which you need to use the deployment descriptor.