14 CHAPTER1 Springing into action <bean id="quest" class=*com.springinaction.knights.SlayDragonQuest"/> <bean ids"minstrel class="com.springinaction.knights.Minstrel./> op:aspect ref="minstrel'> ooeas6naca2ii·maroneaoatl-p Pomtcut <aop:before pointcut-ref=embark* method="singBeforeQuest"/> Declare before advice <aop:after pointcut-ref="embark' method='singAfterQuest/> Declare after advice </beans> Here you're using Spring's aop configuration namespace to declare that the Minstrel bean is an aspect.First,you had to declare the Minstrel as a bean.Then you refer to that bean in the <aop:aspect>element.Defining the aspect further,you declare (using <aop:before>)that before the embarkonQuest()method is executed,the Min- strel's singBeforeQuest()should be called.This is called before advice.And you (using <aop:after>)declare that the singAfterQuest()method should be called after embarkonQuest()has executed.This is known as after advice. In both cases,the pointcut-ref aturibute refers to a pointcut named embark.This pointcut is defined in the preceding <pointcut>element with an expression attri- bute set to select where the advice should be applied.The expression syntax is AspectI's pointcut expression language Don't worry if you don't know Aspect]or the details of how Aspect]pointcut pressions are written.We'll talk more about Spring AOP later in chapter 4.For now it's enough to know that you've asked Spring to call the Minstrel's singBefore Quest()and singAfterQuest()methods before and after the Braveknight embarks on a quest. That's all there is to it!With a tiny bit of XML,you've just turned Minstrel into a Spring aspect.Don't worry if this doesn't make complete sense yet-you'll see plenty more examples of Spring AOP in chapter 4 that should help clear this up.For now there are two important points to take away from this exampl First,Minstrel is still a POJO-nothing about it indicates that it's to be used as an aspect.Instead Minstrel became an aspect when we declared it as such in the Spring context. Second,and most important,Minstrel can be applied to the Braveknight without the Braveknight needing to explicitly call on it.In fact,Braveknight remains com- pletely una are of the Minstrel's existence. I should also point out that although you used some Spring magic to turn Min- strel into an aspect,it was declared as a Spring <bean>first.The point here is that
14 CHAPTER 1 Springing into action <bean id="quest" class="com.springinaction.knights.SlayDragonQuest" /> <bean id="minstrel" class="com.springinaction.knights.Minstrel" /> <aop:config> <aop:aspect ref="minstrel"> <aop:pointcut id="embark" expression="execution(* *.embarkOnQuest(..))" /> <aop:before pointcut-ref="embark" method="singBeforeQuest"/> <aop:after pointcut-ref="embark" method="singAfterQuest"/> </aop:aspect> </aop:config> </beans> Here you’re using Spring’s aop configuration namespace to declare that the Minstrel bean is an aspect. First, you had to declare the Minstrel as a bean. Then you refer to that bean in the <aop:aspect> element. Defining the aspect further, you declare (using <aop:before>) that before the embarkOnQuest() method is executed, the Minstrel’s singBeforeQuest() should be called. This is called before advice. And you (using <aop:after>) declare that the singAfterQuest() method should be called after embarkOnQuest() has executed. This is known as after advice. In both cases, the pointcut-ref attribute refers to a pointcut named embark. This pointcut is defined in the preceding <pointcut> element with an expression attribute set to select where the advice should be applied. The expression syntax is AspectJ’s pointcut expression language. Don’t worry if you don’t know AspectJ or the details of how AspectJ pointcut expressions are written. We’ll talk more about Spring AOP later in chapter 4. For now it’s enough to know that you’ve asked Spring to call the Minstrel’s singBeforeQuest() and singAfterQuest() methods before and after the BraveKnight embarks on a quest. That’s all there is to it! With a tiny bit of XML, you’ve just turned Minstrel into a Spring aspect. Don’t worry if this doesn’t make complete sense yet—you’ll see plenty more examples of Spring AOP in chapter 4 that should help clear this up. For now, there are two important points to take away from this example. First, Minstrel is still a POJO—nothing about it indicates that it’s to be used as an aspect. Instead Minstrel became an aspect when we declared it as such in the Spring context. Second, and most important, Minstrel can be applied to the BraveKnight without the BraveKnight needing to explicitly call on it. In fact, BraveKnight remains completely unaware of the Minstrel’s existence. I should also point out that although you used some Spring magic to turn Minstrel into an aspect, it was declared as a Spring <bean> first. The point here is that Declare Minstrel bean Define pointcut Declare before advice Declare after advice Licensed to Christian Cederquist <chrisman@kaus.dk>
Simplifying Java development 6 you can do anything with Spring aspects that you can do with other Spring beans,such even more practical things.As you'll see later,Spring AOP can be employed to provide services such as declarative transactions(chapter 6)and security(chapter 9). But for now,let's look at one more way that Spring simplifies Java development. 1.1.4 Eliminating boilerplate code with templates Have you ever written some code and then felt like you'd already written the same code before?That's not deja vu,my friend.That's boilerplate code-the code that you often have to write over and over again to accomplish common and otherwise simple tasks. Unfortunately,there are a lot of places where Java APls involve a bunch of boiler plate code.A common example of boilerplate code can be seen when working with JDBC to query data from a database.For example,if you've ever worked with JDBC before,then you've probably written something similar to the following Listing 1.11 Many Java APIs,such as JDBC,involve writing a lot of boilerplate code. public Employee getEmployeeById(long id)( Connection conn null; try conn dataSource.getConnection(); lastname,salary from"+ stmt.seti (1.id): Select employee rs stmt.executeQuery(); p18y8eetaa1Ye0 empioyeeme (rtame)) employee.setLastName(rs.getstring("lastname)); employee.setsalary(rs.getBigDecimal(salary")): finally if(rs !null) Clean up mess try( SQLException e)(} if(stmt !null)( try stmt.close();
Simplifying Java development 15 you can do anything with Spring aspects that you can do with other Spring beans, such as injecting them with dependencies. Using aspects to sing about knights can be fun. But Spring’s AOP can be used for even more practical things. As you’ll see later, Spring AOP can be employed to provide services such as declarative transactions (chapter 6) and security (chapter 9). But for now, let’s look at one more way that Spring simplifies Java development. 1.1.4 Eliminating boilerplate code with templates Have you ever written some code and then felt like you’d already written the same code before? That’s not déjà vu, my friend. That’s boilerplate code—the code that you often have to write over and over again to accomplish common and otherwise simple tasks. Unfortunately, there are a lot of places where Java APIs involve a bunch of boilerplate code. A common example of boilerplate code can be seen when working with JDBC to query data from a database. For example, if you’ve ever worked with JDBC before, then you’ve probably written something similar to the following. public Employee getEmployeeById(long id) { Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = dataSource.getConnection(); stmt = conn.prepareStatement( "select id, firstname, lastname, salary from " + "employee where id=?"); stmt.setLong(1, id); rs = stmt.executeQuery(); Employee employee = null; if (rs.next()) { employee = new Employee(); employee.setId(rs.getLong("id")); employee.setFirstName(rs.getString("firstname")); employee.setLastName(rs.getString("lastname")); employee.setSalary(rs.getBigDecimal("salary")); } return employee; } catch (SQLException e) { } finally { if(rs != null) { try { rs.close(); } catch(SQLException e) {} } if(stmt != null) { try { stmt.close(); Listing 1.11 Many Java APIs, such as JDBC, involve writing a lot of boilerplate code. Select employee Create object from data What should be done here? Clean up mess Licensed to Christian Cederquist <chrisman@kaus.dk>
CHAPTER1 Springing into action catch(SOLException e)f) if(conn !null)( try eption e)(} 1 return null; As you can see,this JDBC code queries the database for an employee's name and sal ary.But I'll bet you had to look hard to see that.That's because the small bit of code that's specific to querying for an employee is buried in a heap of JDBC ceremony.You first have to create a connection,then a statement,and then finally you can query for the results.And,to appease JDBC's anger,you must catch SQLException,a checked exception,even tho g the re's not a lot you can do if it's thrown Finally,after all is said and done,you have to clean up the mess,closing down the connection,statement,and result set.This could also stir JDBC's anger.Therefore you must catch SOLException here as well. What's most notable about listing 1.11 is that much of it is the exact same code that you'd write for pretty much any JDBC operation.Little of it has anything to do with querying for an employee,and much of it is JDBC boilerplate JDBC's not alone in the boilerplate code business.Many activities often require similar boilerplate code.JMS,JNDI,and the consumption of REST services often involve a lot of commonly repeated code Spring seeks to eliminate boilerplate code by encapsulating it in templates. Spring's JdbeTemplate makes it possible to perform database operations without all of the ceremony required by traditional JDBC. For example,using Spring's simpleJdbcTemplate (a specialization of Jdbc- Template that takes advantage of Java 5 features),the getEmployeeById()method can be rewritten so that its focus is on the task of retrieving employee data and not catering to the demands of the JDBC API.The following shows what such an updated getEmployeeById()method might look like Listing 112 Templates let your code focus on the task at hand. public Employee getEmployeeById(long id) select id, firstname, lastname,salary " SQL query public Employee mapRow(Resultset rs, int rowNum)throws SQLException Employee employee new Employee(); ing("firstname"))
16 CHAPTER 1 Springing into action } catch(SQLException e) {} } if(conn != null) { try { conn.close(); } catch(SQLException e) {} } } return null; } As you can see, this JDBC code queries the database for an employee’s name and salary. But I’ll bet you had to look hard to see that. That’s because the small bit of code that’s specific to querying for an employee is buried in a heap of JDBC ceremony. You first have to create a connection, then a statement, and then finally you can query for the results. And, to appease JDBC’s anger, you must catch SQLException, a checked exception, even though there’s not a lot you can do if it’s thrown. Finally, after all is said and done, you have to clean up the mess, closing down the connection, statement, and result set. This could also stir JDBC’s anger. Therefore you must catch SQLException here as well. What’s most notable about listing 1.11 is that much of it is the exact same code that you’d write for pretty much any JDBC operation. Little of it has anything to do with querying for an employee, and much of it is JDBC boilerplate. JDBC’s not alone in the boilerplate code business. Many activities often require similar boilerplate code. JMS, JNDI, and the consumption of REST services often involve a lot of commonly repeated code. Spring seeks to eliminate boilerplate code by encapsulating it in templates. Spring’s JdbcTemplate makes it possible to perform database operations without all of the ceremony required by traditional JDBC. For example, using Spring’s SimpleJdbcTemplate (a specialization of JdbcTemplate that takes advantage of Java 5 features), the getEmployeeById() method can be rewritten so that its focus is on the task of retrieving employee data and not catering to the demands of the JDBC API. The following shows what such an updated getEmployeeById() method might look like. public Employee getEmployeeById(long id) { return jdbcTemplate.queryForObject( "select id, firstname, lastname, salary " + "from employee where id=?", new RowMapper<Employee>() { public Employee mapRow(ResultSet rs, int rowNum) throws SQLException { Employee employee = new Employee(); employee.setId(rs.getLong("id")); employee.setFirstName(rs.getString("firstname")); Listing 1.12 Templates let your code focus on the task at hand. SQL query Map results to object Licensed to Christian Cederquist <chrisman@kaus.dk>
Containing your beans employee.setLastName(rs.getstring(lastname)); employee.setsalary(rs.getBigDecimal("salary)); return employee id): Jaha7 As you can see,this new version of getEmployeeById()is much simpler and acutely focused on selecting an employee from the database.The template's queryFor- object()method is given the SQLquery,a RowMapper(for mapping result set data to a domain object),and zero or more query parameters.What you don't see in get- EmployeeById()is any of the JDBC boilerplate from before.It's all handled internal to the template. I've shown you how Spring attacks complexity in Java development using POJO- oriented development,dependency injection,AOP,and templates.Along the way I showed you how to configure beans and aspects in XML-based configuration files.But how do those files get loaded?And what are they loaded into?Let's look at the Spring container,the place where your application's beans will reside. 1.2 Containing your beans Ina Spring-based application,your application objects will live within the Spring con tainer.As illustrated in figure 1.4,the container will create the objects,wire them together,configure them,and manage their complete lifecycle from cradle to grave (or new to finalize(),as the case may be). In the next chapter,you'll see how to configure Spring to know what objects it you grasp how your objects will be managed. The container is at the core of the Spring Framework.Spring's container uses dependency injection(DI)to manage the components that make up an application. This includes creating associations between collaborating components.As such,these objects are cleaner and easier to understand,support reuse,and are easy to unit test. Figure 1.4 In a Spring application, objects are created,wired together and live within the Spring containe
Containing your beans 17 employee.setLastName(rs.getString("lastname")); employee.setSalary(rs.getBigDecimal("salary")); return employee; } }, id); } As you can see, this new version of getEmployeeById() is much simpler and acutely focused on selecting an employee from the database. The template’s queryForObject() method is given the SQL query, a RowMapper (for mapping result set data to a domain object), and zero or more query parameters. What you don’t see in getEmployeeById() is any of the JDBC boilerplate from before. It’s all handled internal to the template. I’ve shown you how Spring attacks complexity in Java development using POJOoriented development, dependency injection, AOP, and templates. Along the way I showed you how to configure beans and aspects in XML-based configuration files. But how do those files get loaded? And what are they loaded into? Let’s look at the Spring container, the place where your application’s beans will reside. 1.2 Containing your beans In a Spring-based application, your application objects will live within the Spring container. As illustrated in figure 1.4, the container will create the objects, wire them together, configure them, and manage their complete lifecycle from cradle to grave (or new to finalize(), as the case may be). In the next chapter, you’ll see how to configure Spring to know what objects it should create, configure, and wire together. First, it’s important to get to know the container where your objects will be hanging out. Understanding the container helps you grasp how your objects will be managed. The container is at the core of the Spring Framework. Spring’s container uses dependency injection (DI) to manage the components that make up an application. This includes creating associations between collaborating components. As such, these objects are cleaner and easier to understand, support reuse, and are easy to unit test. Specify query parameter Spring container Figure 1.4 In a Spring application, objects are created, wired together, and live within the Spring container. Licensed to Christian Cederquist <chrisman@kaus.dk>
18 CHAPTER1 Springing into action There's no single Spring container.Spring comes with several container implementa tions that can be categorized into two distinct types.Bean factories (defined by the org.springframework.beans.factory.BeanFactory interface)are the simplest of containers,providing basic support for DI.Application contexts (defined by the org.springframework.context.Applicationcontext interface)build on the notion of a bean factory by providing application framework services,such as the ability to resolve textual me sages from a properties file and the ability to publish application events to interested event listeners. Although it's possible to work with Spring using either bean factories or application tion contexts and not spend any more time talking about bean factories. 12.1 Working with an application context Spring comes with several flavors of application context.The three that you'll most likely encounter are classPathxmlApplicationcontext-Loads a context definition from an XML file located in the classpath,treating context definition files as classpath resources. FilesystemXmlApplicationcontext-Loads a context definition from an XML file in the file system. XmlWebApplicationcontext-Loads context definitions from an XML file con- tained within a web application. We'll talk more about xmlWebApplicationcontext in chapter 7 when we discuss web based Spring applications.For now,let's simply load the application context from the file system using FilesystemxmlApplicationcontext or from the classpath using classPathXmlApplicationContext. Loading an application context from the file system or from the classpath is similar to how you load beans into a bean factory.For example,here's how you'd load a File- SystemXmlApplicationcontext: Similarly,you can load an application context from within the application's classpath using ClassPathXmlApplicationContext: Applicationcontext context new classPathxmlApplicationcontext (*foo.xml); The difference between using FilesystemxmlApplicationcontext and classPath- foo.xml in a specific location within the file system,whereas classPathxml- Applicationcontext will look for foo.xml anywhere in the classpath (including JAR files)
18 CHAPTER 1 Springing into action There’s no single Spring container. Spring comes with several container implementations that can be categorized into two distinct types. Bean factories (defined by the org.springframework.beans.factory.BeanFactory interface) are the simplest of containers, providing basic support for DI. Application contexts (defined by the org.springframework.context.ApplicationContext interface) build on the notion of a bean factory by providing application framework services, such as the ability to resolve textual messages from a properties file and the ability to publish application events to interested event listeners. Although it’s possible to work with Spring using either bean factories or application contexts, bean factories are often too low-level for most applications. Therefore, application contexts are preferred over bean factories. We’ll focus on working with application contexts and not spend any more time talking about bean factories. 1.2.1 Working with an application context Spring comes with several flavors of application context. The three that you’ll most likely encounter are ClassPathXmlApplicationContext—Loads a context definition from an XML file located in the classpath, treating context definition files as classpath resources. FileSystemXmlApplicationContext—Loads a context definition from an XML file in the file system. XmlWebApplicationContext—Loads context definitions from an XML file contained within a web application. We’ll talk more about XmlWebApplicationContext in chapter 7 when we discuss webbased Spring applications. For now, let’s simply load the application context from the file system using FileSystemXmlApplicationContext or from the classpath using ClassPathXmlApplicationContext. Loading an application context from the file system or from the classpath is similar to how you load beans into a bean factory. For example, here’s how you’d load a FileSystemXmlApplicationContext: ApplicationContext context = new FileSystemXmlApplicationContext("c:/foo.xml"); Similarly, you can load an application context from within the application’s classpath using ClassPathXmlApplicationContext: ApplicationContext context = new ClassPathXmlApplicationContext("foo.xml"); The difference between using FileSystemXmlApplicationContext and ClassPathXmlApplicationContext is that FileSystemXmlApplicationContext will look for foo.xml in a specific location within the file system, whereas ClassPathXmlApplicationContext will look for foo.xml anywhere in the classpath (including JAR files). Licensed to Christian Cederquist <chrisman@kaus.dk>