Saturday, April 14, 2012

Spring AOP–Examples

Source Code:Example

Setting Context

<?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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
    <aop:aspectj-autoproxy/>
    <context:component-scan base-package="org.anotes.springexample.aop"/>
</beans>

Before, After, Around (example1)

Objects

public class Person {
    protected String name;

    public void walk(){
        logger.info(name+" is walking");
    }

@Component
@Scope("prototype")
public class Painter extends Person{

    public void paint(){
        logger.info(name+" is painting");
    }

}

@Component
@Scope("prototype")
public class Teacher extends Person {

    public void teach(){
        logger.info(name+" is teaching");
    }
}

Aspect

@Aspect
@Component("aspectExample1")
public class AspectExample {
    protected final Logger logger = LoggerFactory.getLogger(getClass());


    @Pointcut("execution(* org.anotes.springexample.aop.example1.*.walk(..))")
    private void anyWalking() {
    }


    @Pointcut("execution(* org.anotes.springexample.aop.example1.*.*(..)) && bean(teacher)")
    private void teacherMethods() {
    }


    @Pointcut("within(org.anotes.springexample.aop.example1.*))")
    public void inPainterAndTeacherMethods() {
    }


    @Before("anyWalking()")
    public void logBeforeAnyWalking(JoinPoint joinPoint) {
        logger.info("Before walking:{}", joinPoint.getTarget());
    }


    @After("anyWalking()")
    public void logAfterAnyWalking() {
        logger.info("After walking");
    }


    @Before("teacherMethods() && args(param)")
    public void logPainterAndTeacherMethodWithStringArg(String param) {
        logger.info("Teacher Methods:Before methods with String parameter:{}", param);
    }


    @Around("inPainterAndTeacherMethods()")
    public void logAllMethodsPainterAndTeacher(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        logger.info("Around: Before executing:" + proceedingJoinPoint.getSignature());
        proceedingJoinPoint.proceed();
        logger.info("Around: After executing:" + proceedingJoinPoint.getSignature());
    }

}

Lines

Line 5: Define a Pointcut that point to “walk” method of any Class that are in the “example1” package

Line 8: Define a Pointcut that point to all methods of the bean “teacher”

Line 11: Define a Pointcut that point to any method of  any Class that are in the “example1” package

Line 15: Define a Before Advice that will be called before executing any “walk” method

Line 19: Define a After Advice that will be called before executing any “walk” method

Line 23: Define a Before Advice that will be called before executing any method in the “teacher” bean that has at first parameter a String

Line 27: Define a Around Advice that will be called before executing any method in the “painter” and “teacher” bean

Code to test the Advice

public class Main {
    private static final Logger logger = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        String configFiles = "classpath*:/app-context.xml";
        ApplicationContext context = new ClassPathXmlApplicationContext(configFiles);
        example1(context);
    }
    private static void example1(ApplicationContext context) {
        logger.info("EXAMPLE 1 - Before, After, Around ");
        Teacher teacher = context.getBean(Teacher.class);
        teacher.setName("Ross");
        Teacher teacher2 = context.getBean(Teacher.class);
        teacher2.setName("Jhon");
        Painter painter = context.getBean(Painter.class);
        painter.setName("Pedro");
        teacher.walk();
        painter.walk();
    }

Output

            aop.Main EXAMPLE 1 - Before, After, Around  [INFO ]
aspect.AspectExample Teacher Methods:Before methods with String parameter:Ross [INFO ]
aspect.AspectExample Around: Before executing:void org.anotes.springexample.aop.example1.Person.setName(String) [INFO ]
aspect.AspectExample Around: After executing:void org.anotes.springexample.aop.example1.Person.setName(String) [INFO ]
aspect.AspectExample Teacher Methods:Before methods with String parameter:Jhon [INFO ]
aspect.AspectExample Around: Before executing:void org.anotes.springexample.aop.example1.Person.setName(String) [INFO ]
aspect.AspectExample Around: After executing:void org.anotes.springexample.aop.example1.Person.setName(String) [INFO ]
aspect.AspectExample Around: Before executing:void org.anotes.springexample.aop.example1.Person.setName(String) [INFO ]
aspect.AspectExample Around: After executing:void org.anotes.springexample.aop.example1.Person.setName(String) [INFO ]
aspect.AspectExample Before walking:org.anotes.springexample.aop.example1.Teacher@1989b5 [INFO ]
aspect.AspectExample Around: Before executing:void org.anotes.springexample.aop.example1.Person.walk() [INFO ]
    example1.Teacher Ross is walking [INFO ]
aspect.AspectExample After walking [INFO ]
aspect.AspectExample Around: After executing:void org.anotes.springexample.aop.example1.Person.walk() [INFO ]
aspect.AspectExample Before walking:org.anotes.springexample.aop.example1.Painter@c3c315 [INFO ]
aspect.AspectExample Around: Before executing:void org.anotes.springexample.aop.example1.Person.walk() [INFO ]
    example1.Painter Pedro is walking [INFO ]
aspect.AspectExample After walking [INFO ]
aspect.AspectExample Around: After executing:void org.anotes.springexample.aop.example1.Person.walk() [INFO ]

Introductions / Mixins (example2)

Objects

public interface Resource {
     public void setContent(String content);
     public String getContent();

}
@Component
@Scope("prototype")
public class ResourceImpl implements Resource{
    protected final Logger logger = LoggerFactory.getLogger(getClass());

    private String content;
    @Override
    public void setContent(String content) {
        this.content=content;
        logger.info("Current Content:"+content);
    }

public interface Lockable {
    boolean isLocked();
    void lock();
    void unlock();
}
public class LockableImpl implements Lockable {
    private boolean lock = false;

    @Override
    public boolean isLocked() {
        return lock;
    }

    @Override
    public void lock() {
        lock= true;
    }

    @Override
    public void unlock() {
        lock =false;
    }
}

Aspect

@Aspect
@Component("aspectExample2")
public class AspectExample {
    protected final Logger logger = LoggerFactory.getLogger(getClass());


    @DeclareParents(value = "org.anotes.springexample.aop.example2.Resource*", defaultImpl = LockableImpl.class)
    private Lockable lockableSupport;


    @Pointcut("execution(* org.anotes.springexample.aop.example2.Resource.setContent(..))")
    private void settingContent() {
    }


    @Around("settingContent() && this(lockable)")
    private void onSettingContent(ProceedingJoinPoint joinPoint, Lockable lockable) throws Throwable {
        logger.info("Before Setting Content on Resource. Locked:" + lockable.isLocked());
        if (!lockable.isLocked()) {
            joinPoint.proceed();
            logger.info("After Setting Content:");
        } else {
            logger.info("The resource is locked so it is not possible to set its content");
        }
    }
}

Lines

Line 5: Define that the beans which class name begin with “Resource” and are in the example2 package will implement the “Lockable” interface and the default implementation will be provided by “LockableImpl” class

Line 7: Define a Pointcut that point to the “setContent” method of the beans of type Resource

Line 10: Define a Around Advice that will be called before executing the method “setContent” also the bean will be sent as a parameter implementing the Lockable interface

Code to test the introduction

public class Main {
    private static final Logger logger = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        String configFiles = "classpath*:/app-context.xml";
        ApplicationContext context = new ClassPathXmlApplicationContext(configFiles);
        example1(context);
example2(context);
    }

    private static void example2(ApplicationContext context) {
        logger.info("EXAMPLE 2 - Using Introductions ");
        Resource resource = context.getBean(Resource.class);
        resource.setContent("String resource 1");
        Lockable lockable = (Lockable) resource;
        lockable.lock();
        resource.setContent("String resource 2");
        lockable.unlock();
        resource.setContent("String resource 3");
    }


}

Output

aspect.AspectExample Before Setting Content on Resource. Locked:false [INFO ]
example2.ResourceImpl Current Content:String resource 1 [INFO]
aspect.AspectExample After Setting Content: [INFO ]
aspect.AspectExample Before Setting Content on Resource. Locked:true [INFO ]
aspect.AspectExample The resource is locked so it is not possible to set its content [INFO ]
aspect.AspectExample Before Setting Content on Resource. Locked:false [INFO ]
example2.ResourceImpl Current Content:String resource 3 [INFO ]
aspect.AspectExample After Setting Content: [INFO]

Spring Expression Language (SpEL).

Getting properties file

<util:properties id="settings" location="classpath:settings.properties"/>

Accesing a value in properties

<property name="accessToken" value="#{settings['twitter.accessToken']}"/>

systemEnvironment and systemProperties

In addition to reading properties from a <util:properties>-declared collection, Spring makes two special selections of properties available to SpEL:  systemEnvironment and systemProperties.
systemEnvironment contains all of the environment variables on the machine running the application. It’s just a java.util.Properties collection, so the square braces can be used to access its members by their key. For example, we can inject the user’s region into a bean property like this:

<property name="userRegion" value="#{ systemProperties['user.region'] }"/>

Selecting Collection Members

Let’s say that you want to narrow the list of cities down to only those whose population is greater than 100,000. One way to do this is to wire the entire cities bean into a property and place the burden of sifting out the smaller cities on the receiving bean. But with SpEL, it’s a simple matter of using a selection operator (.?[]) when doing the wiring:

<property name="bigCities" value="#{cities.?[population gt 100000]}"/>

SpEL also offers two other selection operators, .^[] and .$[] , for selecting the first and last matching items (respectively) from a collection. For example, to select the first big city from cities:

<property name="aBigCity" value="#{cities.^[population gt 100000]}"/>

No ordering is done on the collection prior to selection, so the City representing Chicago would be wired into the aBigCity property. Likewise, the City object representing El Paso could be selected as follows:

<property name="aBigCity" value="#{cities.$[population gt 100000]}"/>

Projecting Collections

Collection projection involves collecting a particular property from each of the members of a collection into a new collection. SpEL’s projection operator (.![]) can do exactly that.
For example, suppose that instead of a list of City objects, what you want is just a list of String objects containing the names of the cities. To get a list of just the city names, you could wire a cityNames property like this:

<property name="cityNames" value="#{cities.![name]}"/>

But projection isn’t limited to projecting a single property. With a slight change to the previous example, you can get a list of city and state names:

<property name="cityNames" value="#{cities.![name + ', ' + state]}"/>

To bring collection selection and projection together. Here’s how you might wire a list of only big city names into the cityNames property:

<property name="cityNames" value="#{cities.?[population gt 100000].![name + ', ' + state]}"/>

Autowiring

Spring 3 supports a few different annotations for autowiring:

Spring’s own @Autowired annotation
The @Inject annotation from JSR-330
The @Resource annotation from JSR-250

Using expressions with annotation injection

As long as you’re using annotations to autowire bean references into your Spring beans, you may want to also use annotations to wire simpler values. Spring 3.0 introduced @Value, a new wiring annotation that lets you wire primitive values such as int, boolean, and String using annotations.

The @Value annotation is simple to use but, as you’ll soon see, is also powerful. To use it, annotate a property, method, or method parameter with @Value and pass in a String expression to be wired into the property. For example:

@Value("Eruption")
private String song;

Here we’re wiring a String value into a String property. But the String parameter passed into @Value is just an expression—it can evaluate down to any type and thus @Value can be applied to just about any kind of property.

As it turns out, simple values aren’t where @Value shines. Instead, @Value finds its power with SpEL expressions. Recall that SpEL lets you dynamically evaluate complex expressions, at runtime, into values to be wired into bean properties. That makes @Value a powerful wiring option. For example, rather than hardcoding a static value into the song property, let’s use SpEL to pull a value from a system property:

@Value("#{systemProperties.myFavoriteSong}")
private String song;

Wednesday, April 11, 2012

Growing Object Oriented Software, Guided by Tests–Extracts

Source: Growing Object Oriented Software, Guided by Tests

Roles, Responsibilities, Collaborators

We try to think about objects in terms of roles, responsibilities, and collaborators, as best described by Wirfs-Brock and McKean.

  • An object is an implementation of one or more roles;
  • a role is a set of related responsibilities;
  • and a responsibility is an obligation to perform a task or know information.
  • A collaboration is an interaction of objects or roles (or both).

Sometimes we step away from the keyboard and use an informal design technique that Wirfs-Brock and McKean describe, called CRC cards (Candidates, Responsibilities, Collaborators). The idea is to use low-tech index cards to explore the potential object structure of an application, or a part of it. These index cards allow us to experiment with structure without getting stuck in detail or becoming too attached to an early solution.

Tell, Don’t Ask

We have objects sending each other messages, so what do they say? Our experience is that the calling object should describe what it wants in terms of the role that its neighbor plays, and let the called object decide how to make that happen.

This is commonly known as the “Tell, Don’t Ask” style or, more formally, the Law of Demeter. Objects make their decisions based only on the information they hold internally or that which came with the triggering message; they avoid navigating to other objects to make things happen. Followed consistently, this style produces more flexible code because it’s easy to swap objects that play the same role. The caller sees nothing of their internal structure or the structure of the rest of the system behind the role interface.

Designing for Maintainability

We grow our systems a slice of functionality at a time. As the code scales up, the only way we can continue to understand and maintain it is by structuring the functionality:

  • into objects,
  • objects into packages,
  • packages into programs,
  • and programs into systems.

We use two principal heuristics to guide this structuring:

Separation of concerns

When we have to change the behavior of a system, we want to change as little code as possible. If all the relevant changes are in one area of code, we don’t have to hunt around the system to get the job done. Because we cannot predict when we will have to change any particular part of the system, we gather together code that will change for the same reason. For example, code to unpack messages from an Internet standard protocol will not change for the same reasons as business code that interprets those messages, so we partition the two concepts into different packages.

Higher levels of abstraction

The only way for humans to deal with complexity is to avoid it, by working at higher levels of abstraction. We can get more done if we program by combining components of useful functionality rather than manipulating variables and control flow; that’s why most people order food from a menu in terms of dishes, rather than detail the recipes used to create them.

Encapsulation and Information Hiding

We want to be careful with the distinction between “encapsulation” and “information hiding.” The terms are often used interchangeably but actually refer to two separate, and largely orthogonal, qualities:

Encapsulation

Ensures that the behavior of an object can only be affected through its API. It lets us control how much a change to one object will impact other parts of the system by ensuring that there are no unexpected dependencies between unrelated components.

Information hiding

Conceals how an object implements its functionality behind the abstraction of its API. It lets us work with higher abstractions by ignoring lower-level details that are unrelated to the task at hand.

We’re most aware of encapsulation when we haven’t got it. When working with badly encapsulated code, we spend too much time tracing what the potential effects of a change might be, looking at where objects are created, what common data they hold, and where their contents are referenced.

Object Peer Stereotypes

We have objects with single responsibilities, communicating with their peers through messages in clean APIs, but what do they say to each other?

We categorize an object’s peers (loosely) into three types of relationship. An object might have:

Dependencies

Services that the object requires from its peers so it can perform its responsibilities. The object cannot function without these services. It should not be possible to create the object without them. For example, a graphics package will need something like a screen or canvas to draw on—it doesn’t make sense without one.

Notifications

Peers that need to be kept up to date with the object’s activity. The object will notify interested peers whenever it changes state or performs a significant action. Notifications are “fire and forget”; the object either knows nor cares which peers are listening. Notifications are so useful because they decouple objects from each other. For example, in a user interface system, a button component promises to notify any registered listeners when it’s clicked, but does not know what those listeners will do. Similarly, the listeners expect to be called but know nothing of the way the user interface dispatches its events.

Adjustments

Peers that adjust the object’s behavior to the wider needs of the system. This includes policy objects that make decisions on the object’s behalf (the Strategy pattern) and component parts of the object if it’s a composite. For example, a Swing JTable will ask a TableCellRenderer to draw a cell’s value, perhaps as RGB (Red, Green, Blue) values for a color. If we change the renderer, the table will change its presentation, now displaying the HSB (Hue, Saturation, Brightness) values.

Interface and Protocol

An interface describes whether two components will fit together, while a protocol describes whether they will work together.