CHAPTER1 Springing into action they were primarily used as a model for building user interface widgets.They seemed too simple to be capable of any"real"work.Enterprise developers wanted more. Sophisticated applications often require services such as transaction support,secu rity,and distributed computing-services not directly provided by the JavaBeans spec ification.So in March 1998,Sun published version 1.0 of the Enterprise JavaBeans (EJB)specification.This specification extended the notion of Java components to the erver side,providing much-needed enterprise services,but failed to continue the simplicity of the original JavaBeans specification.Except in name,EJB bears little resemblance to the original JavaBeans specification. Despite the fact that many successful applications have been built based on EJB EJB never achieved its intended purpose:to simplify enterprise application develop- ment.It's true that EJB's declarative programming model simplifies many infrastruc- tural aspects of development,such as transactions and security.But in a different way EJBs complicate development by mandating deployment descriptors and plumbing code (home and remote/local interfaces).Over time,many developers became disen- chanted with EJB.As a result,its popularity has waned in recent years,leaving many developers looking for an easier way. Today,Java component development has returned to its roots.New programming techniques including aspect-oriente ed programming(AOP)and depende y injectior (DI),are giving JavaBeans much of the power previously reserved for EJBs.These tech nust you resort to writing an unwieldy EJB component when a simple JavaBean will suffice. In fairness,even EJBs have evolved to promote a POJO-based programming model. Employing ideas such as DI and AOP the latest EJB specification is significantly sim pler than its predecessors.But for many developers,this move is too little,too late.By the time the EJB 3 specification had entered the scene,other POJO-based develop ment frameworks had already established themselves as de facto standards in the Java communitv. Leading the charge for lightweight POJO-based development is the Spring Frame- work,which we'll explore throughout this book.In this chapter,we'll explore the Spring Framework at a high level,giving you a taste of what Spring is about.This chap- ter will give you a good idea of the types of problems Spring solves,and will set the stage for the rest of the book.First things first-let's find out what Spring is all about. 11 Simplifying Java development Spring is an open source framework,originally created by Rod Johnson and described in his book Expert One-on-One:2EE Design and Development.Spring was created to address the complexity of enterprise application development,and makes it possible to use plain-vanilla JavaBeans to achieve things that were previously only possible with EJBs.But Spring's usefulness isn't limited to server-side development.Any Java applica- tion can benefit from Spring in terms of simplicity,testability,and loose coupling
4 CHAPTER 1 Springing into action they were primarily used as a model for building user interface widgets. They seemed too simple to be capable of any “real” work. Enterprise developers wanted more. Sophisticated applications often require services such as transaction support, security, and distributed computing—services not directly provided by the JavaBeans specification. So in March 1998, Sun published version 1.0 of the Enterprise JavaBeans (EJB) specification. This specification extended the notion of Java components to the server side, providing much-needed enterprise services, but failed to continue the simplicity of the original JavaBeans specification. Except in name, EJB bears little resemblance to the original JavaBeans specification. Despite the fact that many successful applications have been built based on EJB, EJB never achieved its intended purpose: to simplify enterprise application development. It’s true that EJB’s declarative programming model simplifies many infrastructural aspects of development, such as transactions and security. But in a different way, EJBs complicate development by mandating deployment descriptors and plumbing code (home and remote/local interfaces). Over time, many developers became disenchanted with EJB. As a result, its popularity has waned in recent years, leaving many developers looking for an easier way. Today, Java component development has returned to its roots. New programming techniques, including aspect-oriented programming (AOP) and dependency injection (DI), are giving JavaBeans much of the power previously reserved for EJBs. These techniques furnish plain-old Java objects (POJOs) with a declarative programming model reminiscent of EJB, but without all of EJB’s complexity. No longer must you resort to writing an unwieldy EJB component when a simple JavaBean will suffice. In fairness, even EJBs have evolved to promote a POJO-based programming model. Employing ideas such as DI and AOP, the latest EJB specification is significantly simpler than its predecessors. But for many developers, this move is too little, too late. By the time the EJB 3 specification had entered the scene, other POJO-based development frameworks had already established themselves as de facto standards in the Java community. Leading the charge for lightweight POJO-based development is the Spring Framework, which we’ll explore throughout this book. In this chapter, we’ll explore the Spring Framework at a high level, giving you a taste of what Spring is about. This chapter will give you a good idea of the types of problems Spring solves, and will set the stage for the rest of the book. First things first—let’s find out what Spring is all about. 1.1 Simplifying Java development Spring is an open source framework, originally created by Rod Johnson and described in his book Expert One-on-One: J2EE Design and Development. Spring was created to address the complexity of enterprise application development, and makes it possible to use plain-vanilla JavaBeans to achieve things that were previously only possible with EJBs. But Spring’s usefulness isn’t limited to server-side development. Any Java application can benefit from Spring in terms of simplicity, testability, and loose coupling. Licensed to Christian Cederquist <chrisman@kaus.dk>
Simplifying Java development A BEAN BY ANY OTHER NAME...Although Spring uses the words bean and ecification to the letter.A Spring component can be any type of.in this book.I assume the loose definition of JavaBean,which is synonymous with POJO. As you'll see throughout this book,Spring does many things.But at the root of almost everything Spring provides are a few foundational ideas,all focused on Spring's fun- damental mission:Spring simplifies Java development. That's a bold statement!A lot of frameworks claim to simplify something or other. But Spring aims to simplify the broad subject of Java development.This begs for more explanation.How does Spring simplify Java development? To back up its attack on Java complexity,Spring employs four key strategies .Lightweight and minimally invasive development with plain old Java objects (POIOs) .Loose coupling through dependency injection and interface orientatior .Declarative programming through aspects and common conventions ed ction through aspects and templates Almost everything Spring does can be traced back to one or more of these four strate- gies.Throughout the rest of this chapter.I'll expand on each of these ideas,showing concrete examples of how Spring makes good on its promise to simplify Java develop- ment.Let's start with seeing how Spring remains minimally invasive by encouraging POJO-oriented development. 111 Unleashing the power of POJOs If you've been doing Java development for long,you've probably seen (and may have even worked with)frameworks that lock you in by forcing you to extend one of their classes or implement one of their interfaces.The classic example is that of an EJB 2-era stateless session bean.As you can see from this trivial HelloWorldBean,the EJB 2 spec- ification made some rather heavy demands: Listing 1.1 EJB 2.1 forced you to implement methods that weren't needed. package com.habuma.ejb.session import iavax.eib.SessionBean: import javax.ejb.Sessioncontext; public class HelloWorldBean implements SessionBean public void ejbActivate(){ public void ejbRemove()(
Simplifying Java development 5 A BEAN BY ANY OTHER NAME... Although Spring uses the words bean and JavaBean liberally when referring to application components, this doesn’t mean that a Spring component must follow the JavaBeans specification to the letter. A Spring component can be any type of POJO. In this book, I assume the loose definition of JavaBean, which is synonymous with POJO. As you’ll see throughout this book, Spring does many things. But at the root of almost everything Spring provides are a few foundational ideas, all focused on Spring’s fundamental mission: Spring simplifies Java development. That’s a bold statement! A lot of frameworks claim to simplify something or other. But Spring aims to simplify the broad subject of Java development. This begs for more explanation. How does Spring simplify Java development? To back up its attack on Java complexity, Spring employs four key strategies: Lightweight and minimally invasive development with plain old Java objects (POJOs) Loose coupling through dependency injection and interface orientation Declarative programming through aspects and common conventions Boilerplate reduction through aspects and templates Almost everything Spring does can be traced back to one or more of these four strategies. Throughout the rest of this chapter, I’ll expand on each of these ideas, showing concrete examples of how Spring makes good on its promise to simplify Java development. Let’s start with seeing how Spring remains minimally invasive by encouraging POJO-oriented development. 1.1.1 Unleashing the power of POJOs If you’ve been doing Java development for long, you’ve probably seen (and may have even worked with) frameworks that lock you in by forcing you to extend one of their classes or implement one of their interfaces. The classic example is that of an EJB 2–era stateless session bean. As you can see from this trivial HelloWorldBean, the EJB 2 specification made some rather heavy demands: package com.habuma.ejb.session; import javax.ejb.SessionBean; import javax.ejb.SessionContext; public class HelloWorldBean implements SessionBean { public void ejbActivate() { } public void ejbPassivate() { } public void ejbRemove() { } Listing 1.1 EJB 2.1 forced you to implement methods that weren’t needed. Why are these methods needed? Licensed to Christian Cederquist <chrisman@kaus.dk>
6 CHAPTER1 Springing into action pubiic void stsesonContext(onContext ctx) EJB core public string sayHello()( business logic return "Hello World": The sessionBean interface would let you hook into the EJB's lifecycle by implement- ing several lifecycle callback methods(those methods that start with ).Or I should rephrase that to say that the sessionBean interface would force you to hook into the EJB's lifecycle,even if you didn't need to.The bulk of the code in HelloworldBean is there solely for the sake of the framework.This raises the question:who's working for whom? EJB 2 wasn't alone when it came to being invasive.Other popular frameworks such as the earlier versions of Struts,WebWork,and Tapestry imposed themselves upon otherwise simple Java classes.These heavyweight frameworks forced developers to write classes that were littered with unnecessary code,locked into their framework, and were often difficult to write tests against. Spring avoids(as much as possible)littering your application code with its APl Spring almost never forces you to implement a Spring-specific interface or extend a Spring-specific class.Instead,the classes in a Spring-based application often have no indication that they're being used by Spring.At worst,a class may be annotated with one of Spring's annotations,but is otherwise a POJO. To illustrate,if the HelloWorldBean class shown in listing 1.1 were to be rewritten to function as a Spring managed bean,it might look like this Listing 1.2 Spring doesn't make any unreasonable demands on HelloWorldBean. package com.habuma.spring; public class HelloWorldBean This is all you public string sayHello()( needed return "Hello World"; Isn't that better?Gone are all of those noisy lifecycle methods.HelloWorldBean doesn't implement,extend,or even import anything from the Spring APL.Hello- WorldBean is lean,mean,and in every sense of the phrase,a plain-old Java object. Despite their simple form,POJOs can be powerful.One of the ways Spring empow ers POJOs is by assembling them using dependency injection.Let's see how depen- dency injection can help keep application objects decoupled from each other. 11.2 Injecting dependencies The phrase dependency injection may sound intimidating,conjuring up notions of a complex programming technique or design pattern.But as it turns out,DI isn't nearly
6 CHAPTER 1 Springing into action public void setSessionContext(SessionContext ctx) { } public String sayHello() { return "Hello World"; } public void ejbCreate() { } } The SessionBean interface would let you hook into the EJB’s lifecycle by implementing several lifecycle callback methods (those methods that start with ejb). Or I should rephrase that to say that the SessionBean interface would force you to hook into the EJB’s lifecycle, even if you didn’t need to. The bulk of the code in HelloWorldBean is there solely for the sake of the framework. This raises the question: who’s working for whom? EJB 2 wasn’t alone when it came to being invasive. Other popular frameworks such as the earlier versions of Struts, WebWork, and Tapestry imposed themselves upon otherwise simple Java classes. These heavyweight frameworks forced developers to write classes that were littered with unnecessary code, locked into their framework, and were often difficult to write tests against. Spring avoids (as much as possible) littering your application code with its API. Spring almost never forces you to implement a Spring-specific interface or extend a Spring-specific class. Instead, the classes in a Spring-based application often have no indication that they’re being used by Spring. At worst, a class may be annotated with one of Spring’s annotations, but is otherwise a POJO. To illustrate, if the HelloWorldBean class shown in listing 1.1 were to be rewritten to function as a Spring managed bean, it might look like this. package com.habuma.spring; public class HelloWorldBean { public String sayHello() { return "Hello World"; } } Isn’t that better? Gone are all of those noisy lifecycle methods. HelloWorldBean doesn’t implement, extend, or even import anything from the Spring API. HelloWorldBean is lean, mean, and in every sense of the phrase, a plain-old Java object. Despite their simple form, POJOs can be powerful. One of the ways Spring empowers POJOs is by assembling them using dependency injection. Let’s see how dependency injection can help keep application objects decoupled from each other. 1.1.2 Injecting dependencies The phrase dependency injection may sound intimidating, conjuring up notions of a complex programming technique or design pattern. But as it turns out, DI isn’t nearly Listing 1.2 Spring doesn’t make any unreasonable demands on HelloWorldBean. EJB core business logic This is all you needed Licensed to Christian Cederquist <chrisman@kaus.dk>
Simplifying Java development as complex as it sounds.By applying DI in your projects,you'll find that your code will become significantly simpler,easier to understand,and easier to test Any nontrivial application (pretty much anything more complex than a Hello World example)is made up of two or more classes that collaborate with each other to perform some business logic.Traditionally,each object is responsible for obtaining its own references to the objects it collaborates with (its dependencies).This can lead to highly coupled and hard-to-test code. For example,consider the Knight class shown next Listing 1.3 A DamselRescuingKnight can only embark on RescueDamselQuests. package com.springinaction.knights: public class DamselRescuingKnight implements Knight private RescueDamselQuest quest; public DamselRescuingknight()( quest new RescueDamselQuest () public void embarkOnQuest()throws QuestException quest.embark(): As you can see,DamselRescuingKnight creates its own quest,a RescueDamselQuest, within the constructor.This makes a DamselRescuingKnight tightly coupled to a RescueDamselQuest and severely limits the knight's quest-embarking repertoire.If a damsel needs rescuing,this knight's there.But if a dragon needs slaying or a round table needs...well...rounding,then this knight's going to have to sit it out. What's more,it'd be terribly difficult to write a unit test for DamselRescuing- Knight.In such a test,you'd like to be able to assert that the quest's embark()method is called when the knight's embarkonQuest()is called.But there's no clear way to accomplish that here.Unfortunately,DamselRescuingknight will remain untested. Coupling is a two-headed beast.On one hand,tightly coupled code is difficult to test,difficult to reuse,difficult to understand,and typically exhibits"whack-a-mole" bug behavior(fixing one bug results in the creation of one or more new bugs).On the other hand.a certain amount of coupling is necessary-completely uncoupled code doesn't do anything.In order to do anything useful,classes need to know about each other somehow.Coupling is necessary,but should be carefully managed. With DL,on the other hand,objects are given their dependencies at creation time by some third party that coordinates each object in the system.Objects aren't expected to create or obtain their dependencies-dependencies are injected into the objects that need them. To illustrate this point,let's look at Braveknight in the following listing,a knight that's not only brave,but is capable of embarking on any kind of quest that comes along
Simplifying Java development 7 as complex as it sounds. By applying DI in your projects, you’ll find that your code will become significantly simpler, easier to understand, and easier to test. Any nontrivial application (pretty much anything more complex than a Hello World example) is made up of two or more classes that collaborate with each other to perform some business logic. Traditionally, each object is responsible for obtaining its own references to the objects it collaborates with (its dependencies). This can lead to highly coupled and hard-to-test code. For example, consider the Knight class shown next. package com.springinaction.knights; public class DamselRescuingKnight implements Knight { private RescueDamselQuest quest; public DamselRescuingKnight() { quest = new RescueDamselQuest(); } public void embarkOnQuest() throws QuestException { quest.embark(); } } As you can see, DamselRescuingKnight creates its own quest, a RescueDamselQuest, within the constructor. This makes a DamselRescuingKnight tightly coupled to a RescueDamselQuest and severely limits the knight’s quest-embarking repertoire. If a damsel needs rescuing, this knight’s there. But if a dragon needs slaying or a round table needs… well…rounding, then this knight’s going to have to sit it out. What’s more, it’d be terribly difficult to write a unit test for DamselRescuingKnight. In such a test, you’d like to be able to assert that the quest’s embark() method is called when the knight’s embarkOnQuest() is called. But there’s no clear way to accomplish that here. Unfortunately, DamselRescuingKnight will remain untested. Coupling is a two-headed beast. On one hand, tightly coupled code is difficult to test, difficult to reuse, difficult to understand, and typically exhibits “whack-a-mole” bug behavior (fixing one bug results in the creation of one or more new bugs). On the other hand, a certain amount of coupling is necessary—completely uncoupled code doesn’t do anything. In order to do anything useful, classes need to know about each other somehow. Coupling is necessary, but should be carefully managed. With DI, on the other hand, objects are given their dependencies at creation time by some third party that coordinates each object in the system. Objects aren’t expected to create or obtain their dependencies—dependencies are injected into the objects that need them. To illustrate this point, let’s look at BraveKnight in the following listing, a knight that’s not only brave, but is capable of embarking on any kind of quest that comes along. Listing 1.3 A DamselRescuingKnight can only embark on RescueDamselQuests. Tightly coupled to RescueDamselQuest Licensed to Christian Cederquist <chrisman@kaus.dk>
CHAPTER1 Springing into action Listing 1.4 A BraveKnight is flexible enough to take on any Quest he's given package com.springinaction.knights; public class Braveknight implements Knight private Quest quest; public Braveknight(Quest quest)( this.questquest; —Quest is injected public void embarkonQuest()throws QuestException quest.embark(): 1 As vou can see.unlike DamselRescuingKnight.BraveKnight doesn't create his own quest Instead,he's given a quest at construction time asa constructor argument.This is a type of dependency injection known as constructor injection What's more,the quest he's given is typed as Quest,an interface that all quests implement.So Braveknight could embark on a RescueDamselQuest,a slayDragon- Quest,a MakeRoundTableRounderQuest,or any other Quest implementation he's given. The point here is that Braveknight isn't coupled to any specific implementation of Quest.It doesn't matter to him what kind of quest he's asked to embark upon,so long as it implements the Quest interface.That's the key benefit of DI-loose coupling.If an object only knows about its dependencies by their interface(not by their implemen tation or how they're instantiated),then the dependency can be swapped out with a different implementation without the depending object knowing the difference. One of the most common ways that a dependency will be swapped out is with a mock implementation during testing.You were unable to adequately test Damsel- RescuingKnight due to tight coupling,but you can easily test BraveKnight by giving it a mock implementation of Quest,as shown next Listing 1.5 To test BraveKnight,you'll inject it with a mock Quest. package com.springinaction.knights import static org.mockito.Mockito.*; import org.junit.Test; public class BraveKnightTest bubiievo2ggntsnoundebarkoe0aest0throwueQuetECeo pu Quest uE. k(Quest Create mock Quest BraveKnight knight =new BraveKnight(mockQuest); Inject mock Ques knight.embarkonQuest(); verify(mockQuest,times(1)).embark();
8 CHAPTER 1 Springing into action package com.springinaction.knights; public class BraveKnight implements Knight { private Quest quest; public BraveKnight(Quest quest) { this.quest = quest; } public void embarkOnQuest() throws QuestException { quest.embark(); } } As you can see, unlike DamselRescuingKnight, BraveKnight doesn’t create his own quest. Instead, he’s given a quest at construction time as a constructor argument. This is a type of dependency injection known as constructor injection. What’s more, the quest he’s given is typed as Quest, an interface that all quests implement. So BraveKnight could embark on a RescueDamselQuest, a SlayDragonQuest, a MakeRoundTableRounderQuest, or any other Quest implementation he’s given. The point here is that BraveKnight isn’t coupled to any specific implementation of Quest. It doesn’t matter to him what kind of quest he’s asked to embark upon, so long as it implements the Quest interface. That’s the key benefit of DI—loose coupling. If an object only knows about its dependencies by their interface (not by their implementation or how they’re instantiated), then the dependency can be swapped out with a different implementation without the depending object knowing the difference. One of the most common ways that a dependency will be swapped out is with a mock implementation during testing. You were unable to adequately test DamselRescuingKnight due to tight coupling, but you can easily test BraveKnight by giving it a mock implementation of Quest, as shown next. package com.springinaction.knights; import static org.mockito.Mockito.*; import org.junit.Test; public class BraveKnightTest { @Test public void knightShouldEmbarkOnQuest() throws QuestException { Quest mockQuest = mock(Quest.class); BraveKnight knight = new BraveKnight(mockQuest); knight.embarkOnQuest(); verify(mockQuest, times(1)).embark(); } } Listing 1.4 A BraveKnight is flexible enough to take on any Quest he’s given Listing 1.5 To test BraveKnight, you’ll inject it with a mock Quest. Quest is injected Create mock Quest Inject mock Quest Licensed to Christian Cederquist <chrisman@kaus.dk>