When to Choose Spring with Willie Wheeler
Join the DZone community and get the full member experience.
Join For FreeDZone recently caught up with Willie Wheeler, author of Spring in Practice (Manning) and long time Java consultant. In this interview, Willie provides an overview of the Spring portfolio of projects, including the Spring Framework and provides some guidance on when Spring is a good choice – and when it is not. While Spring has provided tremendous productivity gains for enterprise development, “there are certain incongruities between the Spring of yesterday and Spring today,” according to Wheeler.DZone: Could
you introduce yourself, and give us a little background into your experience
with Spring?
Wheeler: Gladly. I'm Willie Wheeler, and I work as a solutions architect at a large
company in the higher education industry. I've been using Java for twelve years
and Spring for five, with a focus on web application development.
DZone: For those who haven't heard about it
could you give a big picture overview of both the Spring Framework, and the
Spring Portfolio?
Wheeler: The Spring Framework is a general framework for developing enterprise applications. Like JEE, it tries to achieve a clean break between app and infrastructure code so app developers can focus on app development. Technically, the framework's most salient features are its lightweight container, its POJO-based component model, its use of dependency injection for application wiring and its many glue APIs for integrating third-party services.
The Spring Portfolio is a larger set of offerings built around the core framework. It comprises the core framework itself, along with more focused frameworks targeting things like security, page flow, batch jobs and enterprise integration.
Roughly speaking, the core framework contains those parts of the portfolio applicable to a wider variety of development contexts, and it tends to focus on leveraging third-party solutions as opposed to providing entirely new ones. There are some counterexamples to that schema (e.g., Portlet support is a counterexample to the former and Spring Web MVC is a counterexample to the latter), but by and large I think it's accurate.
Spring in general reflects and promotes some key philosophical values, such as simplicity, non-invasiveness and the idea that you can deploy honest-to-goodness enterprise apps in a servlet container (e.g., Tomcat). With respect to the third item in particular, there was a time where this was a direct challenge to the J2EE/EJB orthodoxy, and the view that all you needed was a servlet container was something like a heresy. Nowadays it's commonly understood, and Rod Johnson and Spring can rightly claim the credit for that disruptive shift in thinking.
DZone: What did Spring do right? At least in the early days?
Wheeler: Spring has done a lot of things right, both technically and in terms of strategy for building a community of users.
Most fundamental
was the technical insight that enterprise development could be much simpler
than the model Sun and the app server vendors were promoting with J2EE and EJB
2.x. The point was unobvious at the time, especially since EJB was officially
blessed by Sun. People often explained Sun's technical approach in terms of
non-technical concerns like building a market for app servers, and common sense
dictates that such forces were probably at work. But I don't think it necessary
to ascribe ulterior motives to Sun or the app server vendors to understand why
they promoted J2EE and EJB. J2EE and EJB 2.x were honest attempts to move
infrastructure out of the app, and there were things like XDoclet to make EJB
development less burdensome. In the end Spring simply offered a better
technical approach.
Another thing Spring did right was offer an alternative to Sun's top-down,
vendor-driven model of platform development. Java has from the start enjoyed a
vibrant open source community. But Sun seemed more inclined to compete against
such efforts (e.g., JSR 47 vs. log4j) instead of embracing and leveraging them.
Spring took a more bottom-up approach, incorporating many of the open source
libraries that people were already using. This created some goodwill toward
Spring, and additionally provided a powerful bootstrap that allowed Spring to
position itself rather quickly as a viable alternative to EJB.
The most important open source library in this regard was Hibernate. Spring's
POJO-centric component model was a promising replacement for the heavy EJB
component model. But Spring didn't itself have a persistence model to replace
EJB's CMP and CMR facilities. POJO-friendly Hibernate plugged that gap. With
Spring and Hibernate together you could throw EJB 2.x out the window, and a lot
of us did just that.
DZone: Have they continued along the right road, or do you think
they have deviated slightly?
Wheeler: Overall I think Spring has continued along the right road, but that statement
needs some unpacking.
To me, "being on the right road" means correctly balancing the often competing demands of simplicity and sustainability. The tension arises because sustainability involves growing the platform, but after a certain point people start saying, "Wow, this thing is big and complicated."
Spring strikes the balance in at least a few ways. First, additions to the portfolio are generally consistent with the goal of simplifying enterprise development. Some additions, such as Grails and Roo, target simplicity itself in a domain-neutral fashion. Others, such as Spring Batch and Spring Integration, apply Spring concepts to specific technical domains, decreasing the complexity of working within those domains. Non-core projects are isolated from the core to keep the core simple and clean.
Second, with each release Spring introduces evolutionary improvements aimed at simplifying the framework itself. For instance, Spring addressed the "too much XML" complaint with component annotations, component scanning, namespace-based configuration DSLs, JavaConfig, convention over configuration and (as of Spring 3) a new AnnotationConfigApplicationContext.
Finally, Spring limits complexity by using common patterns throughout the portfolio, such as dependency injection, templates, configuration DSLs and so forth.
Having said all that, there are certain incongruities between the Spring of yesterday and Spring today. Ultimately these admit of a charitable reading, but they're noteworthy in any case.
The most glaring is that Spring initially positioned itself in a way that was hostile toward the self-serving influence that vendors often have on technical specifications, and hostile in particular toward the idea that one needs application servers to run enterprise applications. But now SpringSource is an OSGi app server vendor, and it's unclear what to make of that.
Another early value that Spring appears to have abandoned, at least partially, is the disinclination to invent new solutions or (worse) reinvent the wheel where open source solutions are available. Spring Web MVC, Spring's REST support and Spring Integration, for instance, seem to be clear instances of reinventing the wheel. To be sure they're interesting reinventions, and I like all three, but they directly compete with other efforts.
I mentioned that it's possible to interpret these developments charitably. As regards the change in attitude about app servers, it might be that the real objection was specifically aimed at EJB-based app servers and the vendor environment around that particular technology. It's possible that OSGi app servers are a difference that makes a difference. It will be interesting to see where this goes over the coming years.
Regarding the invention of new solutions, I don't see how SpringSource has much of a choice. Spring has been so successful (witness JSRs 299 and 330) that frameworks expressing the basic technical concepts (lightweight containers, POJO component models, dependency injection) are in my view slowly moving toward standardization and commoditization. While there will always be differences between dependency injection frameworks, the core framework and approach are not going to be the sources of differentiation that they once were. Instead that differentiation will come in part from more focused frameworks, tools and services built on top of the core.
DZone: So, let's say I'm a developer who's heard all the hype
"Use Spring". Before I dive right in, could you explain when I might
use Spring?
Wheeler: Spring is useful for enterprise apps, and also for non-enterprise apps that use
enterprise technologies like JDBC, Hibernate, web services, JavaMail and so
forth.
Spring is architecturally helpful. It works as advertised in the area of
separating business logic from infrastructure, and it explicitly supports the
standard n-tiered approach to enterprise application development (@Controller,
@Service, @Repository, Spring Web MVC, DAO and ORM support, etc.). The POJO
component model is clean.
Spring integrates nicely with many open source projects, both major and minor.
Spring's emphasis on declarative and convention-based programming do a nice job
of helping keep your codebase trim.
Spring's transaction support is extremely useful in cases where you want to use
transactional resources outside of an application server or even servlet
container context. It allows you to define transactional semantics (e.g.,
propagation behavior, isolation, rollback behavior, etc.) in a declarative way
instead of programmatically.
Spring's POJOs and dependency injection strongly support code testability.
The core framework is well documented, and most of the portfolio is at least
reasonably documented. Moreover there's a strong community for support. So
Spring is great if you expect those sorts of things from your application
development frameworks.
DZone: And then, when would Spring be the wrong
option?
Wheeler: Spring has a bit of a learning curve, so if you or your team don't have time to
absorb some new concepts and APIs then Spring might be a poor choice.
Spring might be overkill if you're building something fairly small, or if you're
already using other frameworks that already handle the core infrastructural
concerns.
DZone: This one is a big ask - could you give
an overview of each of the Spring portfolio products?
Wheeler: Sure. I think that would be very helpful to a lot of people.
Spring Framework:
This is the core
framework upon which most of the other pieces sit. The main features as I've
mentioned are a lightweight IoC container, a POJO-based component model and
then APIs for integrating with many third-party libraries. The Spring Framework
provides support for AOP, validation, DAOs, JDBC, ORM, transactions, web MVC,
RESTful web services, portlets, object/XML mapping and testing, among other
things.
Spring Batch:
Framework for building
and running batch applications.
Spring BlazeDS Integration:
Supports
Adobe's BlazeDS, which allows Flex clients to communicate with Java backends
using the binary Action Message Format (AMF) protocol. This is an alternative
to using HTTP services, RESTful web services and SOAP web services, each of
which Flex also supports.
Spring Dynamic Modules for OSGi:
Simplifies the development of OSGi-enabled Spring applications.
Spring Faces:
Part of Spring Web
Flow. Supports the use of JSF as a Spring Web MVC view technology.
Spring Groovy & Grails:
Productivity platform based on the popular Ruby on Rails. Groovy is a dynamic
Java-based language, and as such it integrates nicely with Java, allowing
access to Java class libraries. Grails is analogous to the Rails web framework.
Spring IDE:
Eclipse plug-in to make Spring
development easier. Has some nice features, including support for creating
application context configuration files (so you don't have to remember all the
namespaces) and bean graph visualization. You can organize separate Spring
config files into a set and then generate a graph for the entire set, which is
nice.
Spring Integration:
Framework for
building messaging infrastructures for enterprise integration efforts. Based on
the Enterprise Integration Patterns
book by Hohpe and Woolf. Interesting application of the dependency injection
approach because you use DI to build a single horizontal pipes-and-filters
integration layer instead of the standard vertical approach of wiring layers
together.
Spring JavaConfig:
Allows you to
configure the IoC container using Java @Configuration classes instead of XML.
Nice if you don't like using XML to configure your container, though the amount
of XML involved has been steadily shrinking with each release, even without
JavaConfig. And in Spring 3 most of JavaConfig has moved into the core
framework itself.
Spring JavaScript:
Part of Spring
Web Flow. Provides a common interface to JavaScript-based UI libraries, though
I think that Dojo is currently the only library that has a mapping.
Spring LDAP:
Template-based library
to simplify working with LDAP repositories.
Spring .NET:
A .NET version of the
Spring Framework. Not a straight port, and not intended to support direct ports
of apps from Java to .NET. Instead the point is to make available to .NET
developers many of the same concepts that Spring brought to Java.
Spring Rich Client Project:
Framework for developing Swing-based rich clients using Spring.
Spring Roo:
Minimally-invasive
productivity tool to allow you to build Spring apps very quickly using code
generation and a command line interface. Designed to be useful throughout the
development lifecycle.
Spring Security:
Rebranding and
elaboration of the Acegi security framework. Lots of support for web
applications, though it isn't limited to web apps. Strong support for
authentication, authorization (role-based, group-based and ACL-based) and
channel security. They've used convention over configuration to simplify what
was formerly a challenging configuration.
Spring Web Flow:
Web framework that
builds upon Spring Web MVC by supporting page flows. Page flows are a common
way to support multistep user tasks like registrations, applications,
e-commerce checkouts and so forth. Spring Web Flow allows developers to model
such flows explicitly and to maintain conversational state across the flow.
Spring Web Services:
Framework
for building contract-first SOAP web services. Does not support RESTful web
services, which are instead supported by Spring Web MVC.
Spring Extensions:
SpringSource-sponsored community contributions. Includes projects like Spring
Python, Spring ActionScript and Spring JCR.
SpringSource dm Server:
OSGi-based
Java application server, based on the Eclipse Equinox OSGi container and Spring
Dynamic Modules. Supports more granular deployments and more efficient use of
system resources. Also helps avoid "JAR hell" issues.
SpringSource tc Server:
Enhanced
version of the Apache Tomcat servlet container. Enhancements center around
server administration, application management and advanced diagnostics.
SpringSource ERS:
The SpringSource
Enterprise Ready Server, which is an enhanced bundling of the Apache web server
and the Tomcat servlet container.
SpringSource Hyperic HQ:
Network and
web application monitoring and management. Supports virtualization and cloud
environments. Has open source and enterprise editions.
SpringSource Hyperic IQ:
Provides
reporting around Hyperic HQ data. Provides web ops and business views.
SpringSource Cloud Foundry:
Supports
deploying Spring and Grails apps to Amazon EC2. Competes for example with
Google App Engine.
DZone: Out of all the Spring products, which is
your favourite to work with?
Wheeler: Of the several that I've actually used, I think Spring Integration wins the
"most fun" award. Using it feels a lot like playing with Legos, since
there's lots of snapping this or that together.
But overall my favorite is probably Spring Web MVC, especially with all the new
features they've added in Spring 3. My web tier is just so much smaller with
Spring Web MVC than it was, say, with Struts 1.x. I like the flexibility around
method signatures, the new support for JSR 303 bean validation and the view
architecture. I really like the new REST support as well.
DZone: What are your opinions on the growth of
SpringSource?
Wheeler: SpringSource looks good to me. They're doing a nice job aligning themselves
with important trends in infrastructure, including cloud services,
infrastructure management and automation, green data centers and large-scale,
high availability deployments. I expect to see significant growth in all of
those areas over the next several years.
Strategically SpringSource is leveraging its investment, expertise and good
name in software frameworks to build a new and related capability in
infrastructure and ops. There's a lot of potential here since the
infrastructure trends I just mentioned are largely software-driven. The Hyperic
and Cloud Foundry acquisitions support this direction, and the pairup with
VMware makes sense too. SpringSource has considerable software expertise to
offer, and VMware will be able to help SpringSource overcome some of the
challenges associated with being a fairly new entrant into this space.
DZone: Do you think they have become enough of
a significant player in the JCP?
Wheeler: With SpringSource on the executive committee I would guess so, but I don't
follow the JCP especially closely.
DZone: Could you give an overview on what's new
in Spring 3.0?
Wheeler: Yes, I would be
happy to. There's a lot of new and valuable stuff.
API updated to Java 5:
The API and
framework code has been updated to take advantage of Java 5 language features,
such as generics, annotations and varargs. (And so Spring 3 requires Java 5.)
Spring 3 is compatible with Java 6, J2EE 1.4 and JEE 5.
Early support for JEE 6:
Supports
JSF 2.0 and JPA 2.0. Also supports JSR 303 (Bean Validation), JSR 330
(Dependency Injection for Java) and the @Async annotation.
JSR 303 bean validation:
Spring Web
MVC supports automatic form bean validation using JSR 303 bean validation.
Basically you use a @Valid annotation to indicate that a given form bean needs
to be validated before it makes it into the request handler method. Hibernate
Validator 4 provides a reference implementation of JSR 303.
JSR 330 dependency injection:
Spring 3 supports the standardized JSR 330 dependency injection annotations.
For example, now you can use the standard @Inject annotation instead of the
Spring-specific @Autowired annotation.
Spring Expression Language:
The core
now includes a new Spring Expression Language (SpEL) that's similar to Unified
EL but more powerful. SpEL allows you to refer to bean properties or else
environment properties using a #{...} syntax. SpEL is the basis for expression
languages throughout the portfolio. For example Spring Security and Spring Web
Flow will be using SpEL.
Key JavaConfig annotations moved to
core:
Key JavaConfig annotations now live in the core framework, including
@Configuration, @Bean, @DependsOn, @Primary, @Lazy, @Import and @Value. This is
consistent with the overall trend toward minimizing XML configuration. The @Value
annotation in particular is useful in conjunction with SpEL. You can use it to
inject configuration into component-scanned beans (e.g.,
@Value("#{viewNames.itemDetailsViewName}") to inject a view name into
a controller), which was clumsy to do prior to Spring 3.
A new
AnnotationConfigApplicationContext:
This supports annotation-driven,
XML-free programmatic configuration. It works both with @Component-style
annotations and with JavaConfig's @Configuration-style annotations.
Spring Web MVC namespace:
There's
now a new mvc configuration namespace for simplifying Spring Web MVC
configuration.
New Spring Web MVC annotations:
Spring
3 has some useful new annotations, including @CookieValue, @RequestHeader and
@RequestBody among several others.
REST support:
Spring Web MVC now
directly supports REST, both on the service side and on the client side. On the
service side, the REST support includes not only RESTful web services but just
RESTful design in general, including requests for plain old HTML pages. This is
based on some new annotations, views and view resolvers. On the client side,
there's a new RestTemplate class that supports the template method pattern in
much the same way that other Spring templates do. There's also a new
HttpMessageConverter abstraction, along with several implementations, for
converting client-provided payloads into objects.
OXM:
Object/XML mapping has
moved out of the Spring Web Services project into the core.
New views and ContentNegotiatingViewResolver:
There are some new views supporting Atom feeds, RSS feeds, XML
marshalling and JSON. There's also a new ContentNegotiatingViewResolver that
allows for view resolution based either on an Accept header or else the URL's
extension (.html, .xml, .xls, etc.). Very handy because you can easily use a
single handler method to process a request independently of the desired view
type, and then resolve to the correct view afterward.
Portlet 2.0 support:
Spring Web MVC
now supports the Portlet 2.0 API spec (JSR 286). Spring 2.5 supported the
Portlet 1.0 spec (JSR 168).
Custom shortcut annotations:
Spring 3 allows you to use meta-annotations to define custom annotations to
represent one or more other component annotations. For example, my service
beans almost always have the @Service annotation, along with a specific
configuration of @Transactional. I can define a new shortcut annotation,
@MyService, that automatically includes the @Service and @Transactional
annotations when I use it.
Converter and formatter SPIs:
Spring 3 introduces a new converter SPI to replace JavaBeans PropertyEditors.
It also includes a formatter SPI, which is like the converter SPI, but it
focuses on conversion to and from text (i.e. printing and parsing). Spring 3
also includes several implementations for both the converter and formatter
SPIs. Data binding and SpEL are based on the new converter and formatter SPIs.
Task scheduling:
There are now
new TaskScheduler and Trigger abstractions to complement the existing
TaskExecutor abstraction. There is a CronTrigger implementation to allow
scheduling by way of cron expressions. There's also a new task namespace for
configuring TaskExecutors and TaskSchedulers.
Embedded database support:
There's a new jdbc namespace that includes support for embedded databases,
including HSQL, H2 and Derby. These can be pointed at DDL and DML scripts so
that they're populated in a consistent fashion at startup. This supports a more
lightweight approach during development, and also provides a nice tool for
testing data access objects as well. You can also create embedded databases
programmatically.
JUnit 3.8 framework deprecated:
The Spring TestContext framework replaced the JUnit 3.8 framework for
integration testing in Spring 2.5. As of Spring 3, the JUnit 3.8 framework for
integration testing is officially deprecated.
Opinions expressed by DZone contributors are their own.
Comments