When to Choose Spring with Willie Wheeler

DZone 's Guide to

When to Choose Spring with Willie Wheeler

· Java Zone ·
Free Resource

DZone 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?

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?

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.

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.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}