Spring supports two methods of dependency injection: constructor injection and setter injection. Guice (in comparison) favours constructor injection. I prefer constructor injection too. It means objects can't be instatiated in an invalid state (assuming you enforce preconditions) whereas with setter injection you have to rely on lifecycle methods (eg @PostConstruct) to enforce that.
With Java-based Spring configuration you create instances rather than define dependencies in terms of classes (as Guice does it). This is a problem for constructor injection but not for setter injection.
This means when you create an instance to satisfy a dependency you need to explicitly supply all the constructor arguments. Spring would otherwise figure out setter injection.
With Guice you associate classes instead so you don't need to explicitly call a constructor with all the arguments. For Java-based configuration IMHO Guice is much better in this regard.
Also, Java-based Spring configuration relies on the cglib library, which may or may not be a problem in certain environments (eg its not officially supported on AppEngine but in my experience works fine for this).
So if you like constructor injection you have two options: component scanning or XML.
Component scanning is slow. Too slow. For even a small number of objects (<100) I've reduced startup times from ~30 seconds to ~10 seconds just by switching to explicit construction.
XML is really the best choice here. One thing you may not realize is you don't need to specify all the dependencies in XML (setter or constructor). You simply do a definition like:
<bean class="com.example.Foo" />
and public class Foo {
@Inject
public class Foo(Bar bar, AnotherBar anotherBar) { ... }
}
and Spring will figure it out.IMHO this is far better than Spring's Java-based configuration.
EDIT: to clarify, @Inject here is JSR330 DI annotations [1] so java.named.Inject not com.google.inject.Inject. As that page notes Guice now supports either form.