Monday, 14 July 2008

Beginning Spring 2 By Dave Minter

Just now i completed reading Beginning Spring 2: From Novice to Professional By Dave Minter

I wanted to share few important points i found from this book.

1) Aspect-Oriented Programming (AOP)

I refered to this article and also this article for getting some basics for Spring-AOP

Almost all Spring developers will want to take advantage of existing AOP libraries in Spring to apply to their own applications. The most typical example of this is the declarative transaction management library. In a conventional Java application, a service layer method’s transaction management might be handled something like this:


public class AccountServiceImpl extends ServiceImpl implements AccountService {

public Account createAccount() {
try {
beginTransaction();
Account account = dao.save(new Account());
commitTransaction();
return account;
} catch( Exception e ) {
rollbackTransaction();
}
}
}

With the use of declarative transaction management, the method implementation can be reduced to this:

@Transactional
public class AccountServiceImpl extends ServiceImpl implements AccountService {
public Account createAccount() {
return dao.save(new Account());
}
}


Instead of duplicating the begin/commit/rollback logic in all of our service layer implementation classes, we use a Spring AOP annotation to declare that a transaction must begin when we enter any of the implementation class’s methods and that it should be committed when they complete. We also accept the default behavior that causes unchecked exceptions emitted by the method to roll back the transaction. The syntax of all this is remarkably compact.

Because Spring provides all of the AOP libraries necessary to carry out the transactional behavior identified by our annotation, no further configuration is required.

2) Spring Web Flow

Spring Web Flow can be seen as a complement to the existing Spring MVC framework, as
it uses the existing view resolvers and a specialized controller to provide its functionality.Web Flow allows you to model your application behavior as a state machine: the application resides in various states, and events are raised to move the application between these states.

3) What Does Spring Provide, in Terms of AOP?

The aim is not to provide the most complete AOP implementation (although Spring AOP is quite capable); it is rather to provide a close integration between AOP implementation and Spring IoC to help solve common problems in enterprise applications."
The Spring Framework Reference Documentation

In order to meet this aim, the Spring framework currently supports a selection of AOP concepts, ranging from pointcuts to advice. This article will show you how to use the following AOP concepts as they are implemented in the Spring framework:

Advice: How to declare before, afterReturning and afterThrowing advice as beans.

Pointcuts: How to declare static pointcut logic to tie everything together in the XML Spring Bean Configuration files.

Advisors: The way to associate pointcut definitions with advice beans.

4) Applying a Method Tracing Aspect

Possibly the most basic stalwart of aspects is the Method Tracing aspect. This passive aspect is about as simple an aspect as you will find, and so is the best place to start when investigating a new implementation of AOP.

A Method Tracing aspect captures calls to, and returns from, methods being traced within a target application and displays this information in some way. In AO, the before and after types of advice are used to capture these types of join points as they can be triggered before and after a method call join point. Using the Spring framework, the before advice for the Method Tracing aspect is declared in the TracingBeforeAdvice class.


public class TracingBeforeAdvice implements MethodBeforeAdvice
{
public void before(Method m, Object[] args, Object target) throws Throwable
{
System.out.println("Hello world! before(by " + this.getClass().getName() + ")");
}
}


public class TracingAfterAdvice implements AfterReturningAdvice
{
public void afterReturning(Object object, Method m, Object[] args, Object target) throws Throwable
{
System.out.println("Hello world! afterReturning(by " + this.getClass().getName() + ")");
}
}


Both classes represent a specific piece of advice by implementing the appropriate advice interface from the Spring framework. Each type of advice specifies that either the before(..) or afterReturning(..) methods are implemented to enable the Spring runtime to notify the advice when an appropriate join point has been reached. It is worth noting that the TracingAfterAdvice actually extends from AfterReturningAdvice, which means that the advice will only be run if the join point that is encountered returns without an exception.

In order to attach the advice to the appropriate join points in your application you must make a few amendments to the springconfig.xml.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<!-- Bean configuration -->
<bean id="businesslogicbean"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>IBusinessLogic</value>
</property>
<property name="target">
<ref local="beanTarget"/>
</property>
<property name="interceptorNames">
<list>
<value>theTracingBeforeAdvisor</value>
<value>theTracingAfterAdvisor</value>
</list>
</property>
</bean>
<!-- Bean Classes -->
<bean id="beanTarget"
class="BusinessLogic"/>

<!-- Advisor pointcut definition for before advice -->
<bean id="theTracingBeforeAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="theTracingBeforeAdvice"/>
</property>
<property name="pattern">
<value>.*</value>
</property>
</bean>

<!-- Advisor pointcut definition for after advice -->
<bean id="theTracingAfterAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="theTracingAfterAdvice"/>
</property>
<property name="pattern">
<value>.*</value>
</property>
</bean<

<!-- Advice classes -->
<bean id="theTracingBeforeAdvice"
class="TracingBeforeAdvice"/>
<bean id="theTracingAfterAdvice"
class="TracingAfterAdvice"/>

</beans>


The theTracingBeforeAdvisor and theTracingAfterAdvisor advisors are added to the previously declared businesslogicbean. Each advisor potentially intercepts all join points on the beans to which they are attached. The advisors are beans themselves, and their sole job is to tie together pointcut definitions and advice beans. The pointcut definitions in this example are regular expressions specifying the join points of interest within the static object hierarchy.

Since the org.springframework.aop.support.RegexpMethodPointcutAdvisor pointcut advisor is being used in this example, the pointcut logic is specified using a regular expression. The regular expression is used to identify the join points on the public interface to the IBusinessLogic interface. Some simple examples of regular expressions that could have been used to specify different collections of join points on the IBusinessLogic interface are:

.*: This expression selects all join points on the bean or beans to which the advisor has been attached.

./IBusinessLogic/.foo: This expression selects join points on the foo() method on the IBusinessLogic interface only. This will only select join points on the IBusinessLogic interface if it is one of the beans to which the advisor has been attached.

The final bean declarations in the springconfig.xml file specify the classes that implement the advice beans.

5) But what if you want to change the normal behavior of your application? What if you actually want to override a method, for instance? To achieve this you need to use the more active around form of advice.

Simple Example Application as follows


public interface IBusinessLogic
{
public void foo();
}


public class BusinessLogic
implements IBusinessLogic
{
public void foo()
{
System.out.println(
"Inside BusinessLogic.foo()");
}
}

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class MainApplication
{
public static void main(String [] args)
{
// Read the configuration file
ApplicationContext ctx =
new FileSystemXmlApplicationContext(
"springconfig.xml");

//Instantiate an object
IBusinessLogic testObject =
(IBusinessLogic) ctx.getBean(
"businesslogicbean");

// Execute the public
// method of the bean
testObject.foo();
}
}
To completely override a call to the foo() method on an instance of the BusinessLogic class, you need to create some around advice, as shown in the AroundAdvice class.

import org.aopalliance.intercept.MethodInvocation;
import org.aopalliance.intercept.MethodInterceptor;

public class AroundAdvice
implements MethodInterceptor
{
public Object invoke(
MethodInvocation invocation)
throws Throwable
{
System.out.println(
"Hello world! (by " +
this.getClass().getName() +
")");

return null;
}
}


To be used as around advice in Spring, the AroundAdvice class must implement the MethodInterceptor interface and its single invoke(..) method. The invoke(..) method is called whenever a method to be overridden is intercepted. The last step is to change the Spring runtime configuration contained in the application's springconfig.xml file so that the AroundAdvice is applied to your application.



<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<!-- Bean configuration -->
<bean id="businesslogicbean"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>IBusinessLogic</value>
</property>
<property name="target">
<ref local="beanTarget"/>
</property>
<property name="interceptorNames">
<list>
<value>theAroundAdvisor</value>
</list>
</property>
</bean>
<!-- Bean Classes -->
<bean id="beanTarget"
class="BusinessLogic"/>

<!-- Advisor pointcut definition for around advice -->
<bean id="theAroundAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="theAroundAdvice"/>
</property>
<property name="pattern">
<value>.*</value>
</property>
</bean>

<!-- Advice classes -->
<bean id="theAroundAdvice"
class="AroundAdvice"/>

</beans>


The previous example showed that the foo() method in the BusinessLogic class could be entirely overridden by the invoke(..) method in the AroundAdvice class. The original foo() method is not invoked at all by the invoke(..) method. If you actually want to invoke the foo() method from within the around advice, you can use the proceed() method that is available on the MethodInvocation parameter on the invoke(..) method.


public class AroundAdvice
implements MethodInterceptor
{
public Object invoke(
MethodInvocation invocation)
throws Throwable
{
System.out.println(
"Hello world! (by " +
this.getClass().getName() +
")");

invocation.proceed();

System.out.println("Goodbye! (by " +
this.getClass().getName() +
")");

return null;
}
}


6) Refer to this article for a brief introduction to IOC

7) The IoC pattern uses three different approaches in order to achieve this decoupling of control of services from your components: Type 1, Type 2, and Type 3.

Type 1: Interface Injection
This was how most J2EE implementations worked. Your components explicitly conformed to a set of interfaces, with associated configuration metadata, in order to allow the framework to manage them correctly.

Type 2: Setter Injection
External metadata is used to configure how your components can be interacted with. In part one you saw how your Spring component could be configured using a springconfig.xml file using exactly this type of IoC approach.

Type 3: Constructor Injection

Your components are registered with the framework, including the parameters to be used when the components are constructed, and the framework provides instances of the component with all of the specified facilities applied

8) This article provides brief introduction for Implementing crosscutting concerns using Spring 2.0 AOP.

Below is one Logging example


public class MyLoggingAspect
{
public Object log(ProceedingJoinPoint call) throws Throwable
{
System.out.println("from logging aspect: entering method [" +call.toShortString()+"] with param:"+call.getArgs()[0]);
Object point = call.proceed();
System.out.println("from logging aspect: exiting method [" + call.toShortString() + "with return as:" +point);
return point;
}

}


The above LoggingAspect class merely needs to be registered with Spring 2.0 as a regular Spring bean. Further, we need to register the LoggingAspect bean in the Spring configuration file as a Spring AOP aspect. This includes specifying the pointcut expression and the aspect's advice type. The configuration for the pointcut, including the pointcut expression [execution(* jw_01_aop.MyService*.*(..)) ], is shown in the listing below. The advice configuration, also shown below, specifies "around" as the advice type. Other advice types, such as before and after, are also possible. The advice specification also includes the Java aspect class's method to which the aspect will be applied. In this case it is the method log.

<bean id="LoggingAspect"  class = "jw_01_aop.MyLoggingAspect"/>
<aop:config>
...
...
...
<aop:aspect ref="LoggingAspect">
<aop:pointcut id="myCutLogging"
expression="execution(* jw_01_aop.MyService*.*(..))"/>
<aop:around pointcut-ref="myCutLogging" method="log"/>
</aop:aspect>
</aop:config>



9) JavaLobby provides a good article about Spring AOP.

Also Martin Fowler coined Dependency Injection Term in his blog

10) Another example implementation with Spring is given at this site

11) The flexibility the DAO design pattern provides is attributed primarily to a best practice for object design: Program to Interface. This principle states that concrete objects must implement an interface that is used in the caller program rather than the concrete object itself. Therefore, you can easily substitute a different implementation with little impact on client code.

12) This yet another article describe Spring With AOP

Basic concepts of AOP

AOP a.k.a. Aspect Oriented Programming attempt to aid programmers in separation of concerns, specifically cross-cutting concerns. Procedures, packages, classes, and methods all help programmers encapsulate concerns into single entities. But some concerns defy these forms of encapsulation. We call these cross-cutting concerns, because they cut across many modules in a program. It could be some code scattered or tangled, making it harder to understand and maintain. It is scattered when one concern (like in this case, it is event routing) is spread over a number of modules (e.g., classes and methods). That means to change event dispatching can require modifying all affected modules.

The code has lost its elegance and simplicity because the various new concerns have become tangled with the basic functionality (sometimes called the business logic concern). Transactions, Messaging, security, and logging all exemplify cross-cutting concerns.

AOP attempts to solve this problem by allowing the programmer to express cross-cutting concerns in stand-alone modules called aspects. Aspects can contain advice (code joined to specified points in the program) and inter-type declarations (structural members added to other classes). For example, a security module can include advice that performs a security check before accessing a bank account. The pointcut defines the times (join points) that a bank account can be accessed, and the code in the advice body defines how the security check is implemented. That way, both the check and the places can be maintained in one place. Further, a good pointcut can anticipate later program changes, so if another developer creates a new method to access the bank account, the advice will apply to the new method when it executes. The leading AOP implementations are AspectJ , AspectWorkz, Spring AOP etc.

Spring AOP is implemented in pure Java. There is no need for a special compilation process. AspectJ requires special compilation process. Spring AOP does not need to control the class loader hierarchy, and is thus suitable for use in a J2EE web container or application server. Spring 2.0 provides tighter integration with AspectJ.

Separation of concerns is a key principle to developing Service Oriented Architectures. It needs to be applied both at the architectural and implementation level respectively.

13) Below are the points from Chapter 3 and 4th i want to share from the book Spring Enterprise Applications

a) In AOP jargon, the implementation of a cross-cutting concern is called an advice.

b) Spring AOP supports only method invocations as join points

c) Spring AOP supports four advice types that each represents a specific scenario for advice implementations:

Around advice: Controls the execution of a join point. This type is ideal for advice that needs to control the execution of the method on the target object.

Before advice: Is executed before the execution of a join point. This type is ideal for advice that needs to perform an action before the execution of the method on the target object.

After advice: Is executed after the execution of a join point. This type is ideal for advice that needs to perform an action after the execution of the method on the target object.

Throws advice: Is executed after the execution of a join point if an exception is thrown. This type is ideal for advice that needs to performan action when the execution of the method on the target object has thrown an exception

d) AspectJ is a simple and practical extension to the Java programming language that adds to Java aspect-oriented programming (AOP) capabilities. AOP allows developers to reap the benefits of modularity for concerns that cut across the natural units of modularity. In objectoriented programs like Java, the natural unit of modularity is the class. In AspectJ, aspects modularize concerns that affect more than one class.

The following pointcut selects all static and instance methods named relax, regardless of their arguments,return type, or classes:

execution(* relax(..))

e) The @Aspect annotation on the class declaration turns this class into an aspect declaration.It can now hold pointcut declarations and advice/pointcut combinations.


Example

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MessagePrintingAspect {
@Before("execution(* startMatch(..))")
public void printMessageToInformMatchStarts() {
System.out.println("Attempting to start tennis match!");
}
}


This simply declare this aspect as a bean declaration in xml file



g) Selecting on Argument Types

You can also select on the argument declarations of methods. Listing 4-42 shows pointcuts that
narrow down the selection to the following:
• All methods without arguments
• All methods with one argument, regardless of its type
• All methods with one java.lang.String argument
• All methods with java.lang.String as the first argument and zero or more other arguments
• All methods with java.lang.String as the second argument and zero or more other
arguments

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class SystemPointcutsAspect {

@Pointcut("execution(* *())")
public void allMethodsWithoutArguments() {}

@Pointcut("execution(* *(*))")
public void allMethodsWithOneArgumentRegarlessOfType() {}

@Pointcut("execution(* *(java.lang.String))")
public void allMethodsWithOneArgumentOfTypeString() {}

@Pointcut("execution(* *(java.lang.String,..))")
public void
allMethodsWithFirstArgumentOfTypeStringAndZeroOrMoreOtherArguments() {}

@Pointcut("execution(* *(*,java.lang.String,..))")
public void
allMethodsWithSecondArgumentOfTypeStringAndZeroOrMoreOtherArguments () {}
}

14) The basic container for your Spring application is a BeanFactory. As the name implies, this is a class that is responsible for manufacturing bean instances and then configuring their dependencies. A Spring bean can be any Java object, although generally we will be referring to standard Java beans.

15) Aspect-oriented programming (AOP) is a technique that allows for implementation of generic behavior that does not fit well into the object-oriented model. Managing transactions is a good example of this sort of problem; we could build a set of classes to integrate into our object model to manage transactions, but the resulting implementation would be specific to our system.

Logging, auditing, and security can also present problems of this sort. For example, an auditing system may need to keep track of the users invoking certain methods on the data access objects. However, the user information may not be directly available at these points in the implementation, and altering the application so that the credentials are passed around the system appropriately will tie the application inextricably to the auditing implementation and complicate the design. Problems of this type that cut across various parts of the object model are described as cross-cutting concerns.

16) Below are my definitions of few AOP keywords.

Cross-cutting concern: A problem that applies to parts of the object model that are not conveniently related, or that are not related in an object-oriented manner. For example,a problem that applies to method return values in general, rather than to the methods of a single class, is not an object-oriented problem as such.

Pointcut: A rule for matching the parts of the object model that the functionality will be applied to. This is analogous to the rule defining when a database trigger would apply.

Aspect: A package of functionality providing the cross-cutting requirements. A set of triggers for auditing database access would be analogous to an AOP aspect for auditing.

Advice: The implementation of functionality that will be applied. This is analogous to the implementation of a database trigger.


About the Author

Dave Minter has adored computers since he was small enough to play in the boxes they came in. He built his first PC from discarded, faulty, and obsolete components, and considers that to be the foundation of his career as an integration consultant. Dave is based in London, where he helps large and small companies build systems that "just work." He co-authored Building Portals with the Java Portlet API and Pro Hibernate 3.

Hope this explanation helps if any.

No comments: