Simplifying Java development Here you're using a mock object framework known as Mockito to create a mock implementation of the Quest interface.With the mock object in hand,you ed into create a new instance of BraveKnight.injecting the mock Quest via the constructor.After calling the embarkonQuest()method,you ask Mockito to ver- ify that the mock Quest's embark()method was called exactly once. INJECTING A QUEST INTO A KNIGHT Now that your BraveKnight class is written in such a way that you can give him anv quest vou want. cy injection involves givine an obiect its how can you specify which Quest to give him? dependencies as opposed to an object The act of creating associations between appli- having to acquire those dependencies cation components is commonly referred to as wir on its own. ing.In Spring,there are many ways to wire components together,but a common approach has always been via XML.The following listing shows a simple Spring config- uration file,knights.xml,that gives a Braveknight a slayDragonQuest. Listing 1.6 Injecting a slayDragonQuest into a Braveknight with Spring xsi_nttp:/ 20010 .org/sche xsi:schemaLocation=http://www.springframework ora/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd*> kbean id='knightclass="com.springinaction.knights.Braveknight"> <constructor-arg ref="quest"/ </bean> Inject quest bean m.springinaction.knights.slayDragonQuest./> </beans> Create SlayDragonQuest This is a simple app roach to wiring beans in Spring.Don't concern yourself too much with the details right now.We'll dig more into Spring configuration and see what's going on when we get to chapter 2.We'll also look at other ways that we can wire beans in Spring Now that you've declared the relationship between Braveknight and a Quest,you need to load up the XML configuration file and kick off the application. SEEING IT WORK In a Spring application,an application context loads bean definitions and wires them together.The Spring application context is fully responsible for the creation of and wiring of the objects that make up the application.Spring comes with several imple- mentations of its application context,each primarily differing only in how they load their configuration
Simplifying Java development 9 Here you’re using a mock object framework known as Mockito to create a mock implementation of the Quest interface. With the mock object in hand, you create a new instance of BraveKnight, injecting the mock Quest via the constructor. After calling the embarkOnQuest() method, you ask Mockito to verify that the mock Quest’s embark() method was called exactly once. INJECTING A QUEST INTO A KNIGHT Now that your BraveKnight class is written in such a way that you can give him any quest you want, how can you specify which Quest to give him? The act of creating associations between application components is commonly referred to as wiring. In Spring, there are many ways to wire components together, but a common approach has always been via XML. The following listing shows a simple Spring configuration file, knights.xml, that gives a BraveKnight a SlayDragonQuest. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="knight" class="com.springinaction.knights.BraveKnight"> <constructor-arg ref="quest" /> </bean> <bean id="quest" class="com.springinaction.knights.SlayDragonQuest" /> </beans> This is a simple approach to wiring beans in Spring. Don’t concern yourself too much with the details right now. We’ll dig more into Spring configuration and see what’s going on when we get to chapter 2. We’ll also look at other ways that we can wire beans in Spring. Now that you’ve declared the relationship between BraveKnight and a Quest, you need to load up the XML configuration file and kick off the application. SEEING IT WORK In a Spring application, an application context loads bean definitions and wires them together. The Spring application context is fully responsible for the creation of and wiring of the objects that make up the application. Spring comes with several implementations of its application context, each primarily differing only in how they load their configuration. Listing 1.6 Injecting a SlayDragonQuest into a BraveKnight with Spring Inject quest bean Create SlayDragonQuest Figure 1.1 Dependency injection involves giving an object its dependencies as opposed to an object having to acquire those dependencies on its own. Licensed to Christian Cederquist <chrisman@kaus.dk>
CHAPTER1 Springing into action Because the beans in knights.xml are declared in an XML file,an appropriate choice for application context might be classPathxmlApplicationcontext.This Spring context implementation loads the Spring context from one or more XML files located in the application's classpath.The main()method in the following listing uses classPathxmlApplicationcontext to load knights.xml and to get a reference to the Knight obiect. Listing 1.7 KnightMain.java loads the Spring context containing a knight. package com.springinaction.knights; public static void main(string[]args)( ApplicationContext context new classPathxmlApplicationcontext (*knights.xml); conespring Knight knight =(Knight)context.getBean("knight"); Get knight knight.embarkonQuest(); Use knight bean Here the main()method creates the Spring application context based on the knights.xml file.Then it uses the application context as a factory to retrieve the bean whose ID is knight.With a reference to the Knight object,it calls the embarkonQuest ( unaware of the fact that it's dealing with Braveknight.Only the knights.xml file knows for sure what the implementations are And with that you have a quick introduction to dependency injection.You'll see a lot more DI throughout this book.But if you want even more dependency injection,I encourage you to have a look at Dhanji R.Prasanna's Dependency Injection,which cov ers DI in fine detail But now let's have a look at another of Spring's Java-simplifying strategies:declara- tive programming through aspects 11.3 Applying aspects Although DI makes it possible to tie software components together loosely,aspect oriented programming enables you to capture functionality that's used throughout your application in reusable components. Aspect-oriented programming is often defined as a technique that promotes sepa- ration of concerns within a software system.Systems are composed of several compo- nents,each responsible for a specific piece of functionality.Often these compone also carry additional responsibility beyond their core functionality.System services such as logging,transaction management,and security often find their way into
10 CHAPTER 1 Springing into action Because the beans in knights.xml are declared in an XML file, an appropriate choice for application context might be ClassPathXmlApplicationContext. This Spring context implementation loads the Spring context from one or more XML files located in the application’s classpath. The main() method in the following listing uses ClassPathXmlApplicationContext to load knights.xml and to get a reference to the Knight object. package com.springinaction.knights; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class KnightMain { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("knights.xml"); Knight knight = (Knight) context.getBean("knight"); knight.embarkOnQuest(); } } Here the main() method creates the Spring application context based on the knights.xml file. Then it uses the application context as a factory to retrieve the bean whose ID is knight. With a reference to the Knight object, it calls the embarkOnQuest() method to have the knight embark on the quest that it was given. Note that this class knows nothing about which type of Quest our hero has. For that matter, it’s blissfully unaware of the fact that it’s dealing with BraveKnight. Only the knights.xml file knows for sure what the implementations are. And with that you have a quick introduction to dependency injection. You’ll see a lot more DI throughout this book. But if you want even more dependency injection, I encourage you to have a look at Dhanji R. Prasanna’s Dependency Injection, which covers DI in fine detail. But now let’s have a look at another of Spring’s Java-simplifying strategies: declarative programming through aspects. 1.1.3 Applying aspects Although DI makes it possible to tie software components together loosely, aspectoriented programming enables you to capture functionality that’s used throughout your application in reusable components. Aspect-oriented programming is often defined as a technique that promotes separation of concerns within a software system. Systems are composed of several components, each responsible for a specific piece of functionality. Often these components also carry additional responsibility beyond their core functionality. System services such as logging, transaction management, and security often find their way into Listing 1.7 KnightMain.java loads the Spring context containing a knight. Load Spring context Get knight bean Use knight Licensed to Christian Cederquist <chrisman@kaus.dk>
Simplifying Java development components whose core responsibility is something else.These system services are commonly referred to as cross-cutting concerns because they tend to cut across multiple components in a system. By spreading these concerns across multiple components,you introduce two levels of complexity to your code .The code that implements the systemwide concerns is duplicated across multi ple components.This means that if you need to change how those concerns work,you'll need to visit multiple components.Even if you've abstracted the concern to a separate module so that the impact to your components is a single method call,that method call is duplicated in multiple places. .Your components are littered with code that isn't aligned with their core func tionality.A method to add an entry to an address book should only be con- cerned with how to add the address and not with whether it's secure or transactional. Figure 1.2 illustrates this complexity.The business objects on the left are too inti- mately involved with the system services.Not only does each object know that it's being logged,secured,and involved in a transactional context,but also each object is responsible for performing those services for itself. AOP makes it possible to modularize these services and then apply them declaratively to the components that they should affect.This results in components that are more cohesive and that focus on their own specific concerns,completely ignorant of any sys tem services that may be involved.In short,aspects ensure that POJOs remain plain. It may help to think of aspects as blankets that cover many components of an appli cation,as illustrated in figure 1.3.At its core,an application consists of modules that implement business functionality.With AOP,you then cover your core application with layers of functionality.These layers can be applied declaratively throughout your application in a flexible manner without your core application even knowing they ctic Figure 1.2 Calls to systemwide concemns such as logging and security are often scattered about in modules where those concerns are not their primary concer
Simplifying Java development 11 components whose core responsibility is something else. These system services are commonly referred to as cross-cutting concerns because they tend to cut across multiple components in a system. By spreading these concerns across multiple components, you introduce two levels of complexity to your code: The code that implements the systemwide concerns is duplicated across multiple components. This means that if you need to change how those concerns work, you’ll need to visit multiple components. Even if you’ve abstracted the concern to a separate module so that the impact to your components is a single method call, that method call is duplicated in multiple places. Your components are littered with code that isn’t aligned with their core functionality. A method to add an entry to an address book should only be concerned with how to add the address and not with whether it’s secure or transactional. Figure 1.2 illustrates this complexity. The business objects on the left are too intimately involved with the system services. Not only does each object know that it’s being logged, secured, and involved in a transactional context, but also each object is responsible for performing those services for itself. AOP makes it possible to modularize these services and then apply them declaratively to the components that they should affect. This results in components that are more cohesive and that focus on their own specific concerns, completely ignorant of any system services that may be involved. In short, aspects ensure that POJOs remain plain. It may help to think of aspects as blankets that cover many components of an application, as illustrated in figure 1.3. At its core, an application consists of modules that implement business functionality. With AOP, you can then cover your core application with layers of functionality. These layers can be applied declaratively throughout your application in a flexible manner without your core application even knowing they Course service Billing service Student service Instructor service Content service Logging module Security module Transaction manager Figure 1.2 Calls to systemwide concerns such as logging and security are often scattered about in modules where those concerns are not their primary concern. Licensed to Christian Cederquist <chrisman@kaus.dk>
CHAPTER 1 Springing into action Transaction manager hanc Figure 1.3 Using AOP, Billing service systemwide co ncems blanket the ey impact. om nts to focus on their specific business functionality. exist.This is a powerful concept,as it keeps the security,transaction,and logging con- cerns from littering the application's core business logic. To demonstrate how aspects can be applied in Spring,let's revisit the knight exam- ple,adding a basic Spring aspect to the mix. AOP IN ACTION Anyone who knows anything about knights only knows about them because their deeds were chronicled in song by the musically inclined storytellers known as min- strels.Let's suppose that you want to record the comings and goings of your Brave- Knight using the services of a minstrel.The following shows the Minstrel class you might use. Listing 1.8 A Minstrel is a musically inclined logging system of medieval times package com.springinaction.knights I) 2 public void singAfterQuest(){ Called after quest System.out.printin( "Tee hee he;The brave knight did embark on a quest!") As you can see,Minstrel is a simple class with two methods.The singBeforeQuest() method is intended to be invoked before a knight embarks on a quest,and the sing- AfterQuest()method should be invoked after the knight has completed a quest.It should be simple to work this into your code,so let's make the appropriate tweaks to Braveknight to use the Minstrel.The following listing shows a first attempt
12 CHAPTER 1 Springing into action exist. This is a powerful concept, as it keeps the security, transaction, and logging concerns from littering the application’s core business logic. To demonstrate how aspects can be applied in Spring, let’s revisit the knight example, adding a basic Spring aspect to the mix. AOP IN ACTION Anyone who knows anything about knights only knows about them because their deeds were chronicled in song by the musically inclined storytellers known as minstrels. Let’s suppose that you want to record the comings and goings of your BraveKnight using the services of a minstrel. The following shows the Minstrel class you might use. package com.springinaction.knights; public class Minstrel { public void singBeforeQuest() { System.out.println("Fa la la; The knight is so brave!"); } public void singAfterQuest() { System.out.println( "Tee hee he; The brave knight did embark on a quest!"); } } As you can see, Minstrel is a simple class with two methods. The singBeforeQuest() method is intended to be invoked before a knight embarks on a quest, and the singAfterQuest() method should be invoked after the knight has completed a quest. It should be simple to work this into your code, so let’s make the appropriate tweaks to BraveKnight to use the Minstrel. The following listing shows a first attempt. Listing 1.8 A Minstrel is a musically inclined logging system of medieval times Transaction manager Course service Student service Instructor service Billing service Content service Logging module Security module Figure 1.3 Using AOP, systemwide concerns blanket the components that they impact. This leaves the application components to focus on their specific business functionality. Called before quest Called after quest Licensed to Christian Cederquist <chrisman@kaus.dk>
Simplifying Java development Listing1.9 A Braveknight that must call Minstelmethods package com.springinaction.knights; public class Braveknight implements Knight public Braveknight(Quest quest,Minstrel minstrel)( this cost this.minstrel minstrel; public void emba arkonQuest ( Should knight ue minstrel.singAfterQuest() That should do the trick.But something doesn't seem right here.Is it really within the knight's range of concern to manage his minstrel?It seems to me that a minstrel should just do his job without the knight asking him to do so.After all,that's the min strel's job-to sing about the knight's endeavors.Why should the knight have to keep reminding the minstrel to do his job? Furthermore,because the knight needs to know about the minstrel,you're forced to inject the Minstrel into the Braveknight.This not only complicates the Brave- Knight's code,but also makes me wonder if you'd ever want a knight who didn't have a minstrel.What if the Minstrel is null?Should we introduce some null-checking logic to cover that case? Your simple Braveknight class is starting to get more complicated and would become more so if you were to handle the nullMinstrel scenario.But using AOP,you can declare that the minstrel should sing about a knight's quests and free the knight from having to deal with the Minstrel methods directly. To turn Minstrel into an aspect,all you need to do is declare it as one in the Spring configuration file.Here's the updated knights.xml file,revised to declare Minstrel as an aspect Listing 1.10 Declaring the Minstrel as an aspect <?xml version="1.0"encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" im:ap-p://w0r9/20/cmtace /beans/spri 9 httn://un g-beans-3.0.xsd http://www.springframework.ora/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> sbean id-*knight" cascompinginaction.knights.Braveknight /beonstructor-arg ref=quest
Simplifying Java development 13 package com.springinaction.knights; public class BraveKnight implements Knight { private Quest quest; private Minstrel minstrel; public BraveKnight(Quest quest, Minstrel minstrel) { this.quest = quest; this.minstrel = minstrel; } public void embarkOnQuest() throws QuestException { minstrel.singBeforeQuest(); quest.embark(); minstrel.singAfterQuest(); } } That should do the trick. But something doesn’t seem right here. Is it really within the knight’s range of concern to manage his minstrel? It seems to me that a minstrel should just do his job without the knight asking him to do so. After all, that’s the minstrel’s job—to sing about the knight’s endeavors. Why should the knight have to keep reminding the minstrel to do his job? Furthermore, because the knight needs to know about the minstrel, you’re forced to inject the Minstrel into the BraveKnight. This not only complicates the BraveKnight’s code, but also makes me wonder if you’d ever want a knight who didn’t have a minstrel. What if the Minstrel is null? Should we introduce some null-checking logic to cover that case? Your simple BraveKnight class is starting to get more complicated and would become more so if you were to handle the nullMinstrel scenario. But using AOP, you can declare that the minstrel should sing about a knight’s quests and free the knight from having to deal with the Minstrel methods directly. To turn Minstrel into an aspect, all you need to do is declare it as one in the Spring configuration file. Here’s the updated knights.xml file, revised to declare Minstrel as an aspect. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <bean id="knight" class="com.springinaction.knights.BraveKnight"> <constructor-arg ref="quest" /> </bean> Listing 1.9 A BraveKnight that must call Minstrel methods Listing 1.10 Declaring the Minstrel as an aspect Should knight manage its own Minstrel? Licensed to Christian Cederquist <chrisman@kaus.dk>