Linkedin Reddit 0 0 email

The State of Spring

Most of my professional Java projects over the past decade have been based on Spring or JEE. Both platforms are growing a bit long in the tooth, and suffer from different problems. JEE has changed quite dramatically over the years, but is still judged on issues deprecated since EJB 2.x. A lot of people still refer to JEE as “J2EE”, even though the name change was 8 years ago!

Spring has grown as well, but that community seems loathe to deprecate anything. Although a modern Spring application can be quite contemporary and clean, most applications that I see are still riddled with XML config and outdated design choices. Spring may have been arguably superior to JEE in 2006, but the problem is that many developers haven’t kept up-to-date with either platform since then.

Spring and JEE are still the gold standards for large-scale, large-team enterprise Java development. However, as the Java community matures, it hasn’t maintained the same innovation or excitement it had a decade ago. Which perhaps is an inevitable part of maturity.

Other languages and frameworks have therefore emerged to challenge the status quo. Java was probably the most popular language for personal projects when I was in undergrad, but younger developers today seem to devote more personal focus on Python, JavaScript, and the revolving door of fad languages discussed on Hacker News. The most influential web framework of the previous decade was clearly Rails, and the Ruby-based Sinatra has spawned a proliferation of micro-frameworks over the past five years.

Groovy and Grails, the Java world’s initial answer to Ruby and Rails, can now be found even in conservative enterprise shops. Newer JVM-based frameworks go much further. Rather than merely slapping an easy wrapper around JEE and Spring API’s, the Play framework starts from scratch… discarding even such fundamentals as the Java servlet model. Vert.x is inspired by the Node.js style, and targets Java developers interested in experimenting with other languages.

The bottom line is that Spring hasn’t been seen as an exciting source of innovation for some time now. Developers still use it, especially for legacy applications… but increasingly they use it in greenfield development because they have to, not because they enthusiastically choose to. I can’t remember the last time I spoke with a developer using Spring in a personal project, rather than Play or some other platform altogether.

The Need for a Better Bootstrap

This is a shame, because Spring is an incredibly powerful tool… once you get it setup. Spring Data JPA gives you easy relational database management without writing DAO classes… once you get it setup. Other libraries in the Spring Data portfolio provide similar hooks into major NoSQL datastores… once you get it setup. There is config-driven access to AMQP message queues, enterprise integration, and robust batch processing with little or no code… once you get it setup. You can easily connect with API’s for the major social networks, in a web application or from an Android app… once you get it setup. Then there’s Spring Security… but let’s not even talk about setting up Spring Security!

Bootstrapping a Spring application can be painful. Part of this is due to the sheer size and growth rate of the portfolio. Is it really worth using Spring Data JPA, if you’ve already invested your time learning the core JdbcTemplate and Hibernate/JPA wrappers? What is the difference between Spring Data REST and Spring HATEOAS?

The other complicating factor is that Spring seldom deprecates anything, and offers little opinion or guidance. So if you search online for examples, or help troubleshooting a problem, older links with older approaches remain at the top of the search results. This is a large part of why XML-based config is still so common, even though annotation-based config is easier to maintain. Instead of using a clean template system like Thymeleaf or Velocity, most Spring apps still use JSP with JSTL despite this being deprecated and stagnant. There is something to said for familiarity, but escaping cruft is why Spring rose to challenge JEE in the first place.

Innovative drive never ceased among SpringSource developers themselves. Five years ago, they introduced Spring Roo, a rapid development system inspired by the Rails command line tool. Roo allows developers to quickly bootstrap a new Spring application, and create elements such as web controllers or JPA entities through a comand-line console.

However, for non-trivial use, the learning curve is almost as steep as building an application by hand. Perhaps even more so, since you still need to understand the underlying elements. Many developers were put off by the annotations and AspectJ files that Roo litters throughout your codebase to perform its magic. Although Roo is advertised as being easy to remove once you’re up and running, the reality is that removal is a major and tedious undertaking. Moreover, once you do convert the AspectJ stuff to plain Java, you lose the ability to use the magic command line tool. Roo is an interesting system created by talented developers, but never really caught on.

Along Comes Spring Boot

Spring Boot is the next-generation attempt at easy Spring setup. There is an optional command-line tool of sorts, for testing small prototypes written in Groovy. However, Spring Boot is not an automatic code generation tool. Rather, it’s essentially a plugin for your build system (Maven and Gradle are supported).

One one level, the plugin provides facilities for testing and deploying a Spring application. With the command: mvn spring-boot:run, Maven launches your application on port 8080. This is similar to the Maven Jetty plugin, which has become a popular way to test Java web applications in other frameworks. Also, Spring Boot lets you package up an application in a standalone JAR file, with a full Tomcat server embedded. This clearly takes a page from the Play framework’s deployment model (although you can still build traditional WAR files too).

Spring Boot’s main benefit, however, is configuring resources based on what it finds in your classpath. If your Maven POM includes JPA dependencies and a PostgreSQL driver, then Spring Boot will setup a persistence unit based on PostgreSQL. If you’ve added a web dependency, then you get Spring MVC configured with sensible defaults.

Speaking of sensible defaults, Spring Boot actually has opinions! You may not always agree with the defaults, but at least it offers defaults. If you want persistence, but don’t specify anything else, then Spring Boot configures Hibernate as a JPA provider with an HSQLDB database. If you’re bootstraping a web application, but don’t specify anything else, then Spring Boot configures a view resolver for the Thymeleaf template system.

Spring Boot doesn’t actually generate code, but bootstrapping a new application is as simple as creating a POM file with these elements:

... <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.0.0.RC3</version> </parent> ... <properties> <start-class>com.mypackage.Application</start-class> <java.version>1.7</java.version> </properties> ... <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.3.174</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> ... <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> ...

… and a main Java class like this:

@Configuration @EnableAutoConfiguration @ComponentScan @PropertySource("classpath:application.properties") public class Application { @Bean MyCustomService myCustomService() { return new MyCustomService(""); } public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run(Application.class, args); System.out.println("Let's inspect the beans provided by Spring Boot:"); String[] beanNames = ctx.getBeanDefinitionNames(); Arrays.sort(beanNames); for (String beanName : beanNames) { System.out.println(beanName); } } }

For the most part, changing a default involves changing the classpath. Notice in the POM snippet above that I’ve added a dependency on the H2 database. Spring Boot will see this, and configure my JPA persistence unit for H2 rather than the HSQLDB default. If you wanted to use Jetty instead of Tomcat as the embedded server, then just add a Jetty dependency.

Opinionated defaults are a good thing, though. Newer developers can get up and running quickly, and then replace defaults as they learn about other options… rather than having to research all the options for everything before they can even get started.

Ready for Prime Time?

Spring Boot is in “incubation”, and at the time of this writing is still one or two release candidates away from version 1.0.0. It won’t be meant for production until it’s promoted to full project status, and so it’s not fair to judge whether you should be using Spring Boot in production today. However, it is fair to look at the velocity of its progress so far, and consider whether it’s worth exploring for personal applications, or professional projects that won’t go to production for awhile.

I’ve been exploring Spring Boot for about a month now in a personal project, a web application for tracking diet and exercise (source code on GitHub). Spring Boot has leaped through two significant version updates during that brief time. Although I’ve only had to make minor changes with each update, I have had to make changes both times.

Kudos to the Spring Boot team for providing a GitHub repo with around two-dozen sample projects. However, the examples lag behind the current version of Spring Boot. Moreover, each sample showcases a very specific feature, in a “Hello world” manner. It’s been surprisingly tricky to combine multiple features into one non-trivial app (although this has improved over the past month). The core Spring Framework offers an 800-page developer’s guide, of higher quality than most commercial books. Spring Boot documentation, however, consists of about a dozen pages of random notes thrown together.

With the current lack of documentation, it’s often unclear which defaults Spring Boot is using… much less how to tweak or replace them. Also, while I chided many developers at the beginning of this article for not keeping up with the times, the truth is that some of Spring Boot’s defaults expose me as guilty too. I was not previously familiar with Thymeleaf, the default view template system. My impression so far is that it has a steeper learning curve than Velocity or FreeMarker. Spring Boot’s opinions give valuable guidance to newer developers just starting out, but may frustrate seasoned developers who are resistant to change.

Conclusion

All of this being said, I think that Spring Boot is the real deal. I would not try to use it for a professional project in production today, but I think it’s worth exploring now for personal development and side projects. When Spring Boot graduates to full project status and solidifies, and when it gets the same level of documentation as other Spring projects, then I believe it will make little sense to continue bootstrapping Spring projects manually. It will also reduce the complexity and cruft that makes newer frameworks so tempting in comparison.

What’s more, Spring Boot really guides the way toward good modern Spring development practices. If you have been sticking with familiar approaches, and not keeping up with the times because of how complex bootstrapping new Spring applications can be, then Spring Boot provides a great benefit as a teaching tool. Even if you’re not using Spring Boot in production just yet, it will improve your Spring knowledge and skills right now.