Let's now look back over what we've learned so far, and discuss some guidelines that will help you succeed in your Spring-based projects.
The original motivation for Spring was to simplify J2EE development. It does this by providing sophisticated configuration management services that remove the need for developers to write their own lookup code; by providing an AOP framework that provides declarative services to POJOs; and by abstracting developers from complex J2EE APIs. Together, this enables a POJO programming model, in which POJOs typically don't need to call enterprise services explicitly, but can do so by accessing well- defined interfaces, with no "implicit" dependencies such as JNDI.
To enjoy maximum benefit from this approach, you should never write any JNDI or other lookups; use fewer singletons and custom factories; and have no need for ad hoc configuration techniques such as parsing your own XML documents or parameterizing objects from Properties files. The core of Spring is one powerful, extensible factory to end all factories.
The Spring approach is also beneficial in non-J2EE environments. Spring's Dependency Injection and AOP capabilities are equally relevant in J2SE applications. All nontrivial applications tend to need some externalization of configuration, and using a container such as Spring is a much better approach than ad hoc approaches. Spring's JDBC and other data access capabilities are also valuable in non-J2EE environments, as is its integration with numerous popular products and APIs that can be used in a range of scenarios.
Spring can provide a consistent architectural backbone in both J2EE and non-J2EE (even client-side or standalone) applications. Spring largely decouples your application code from its runtime environment, meaning that you can maximize code reuse and enjoy a consistent programming model wherever your code executes.