Sunday, 27 April 2014

Creating Animated Pie Chart in Swing

The following program illustrates creating an animated pie chart the rotates smoothly.

You will need JFreeChart library for this. This contains a set of classes that simplify creating pie charts, graphs etc. You don't need to worry about all the jar files, classpath etc. There are only two jar files starting with jfreechart-1.0.17.jar and jcommon words. Here is the download url click on Download jfreechart-1.0.17.zip and in that file, you will find the lib folder. You will find those two jar files which you need to extract and then set them to your classpath. If you are using an IDE, add these jar files to your project. Here, I am just using Notepad.

PieChartExample.java



import javax.swing.*;
import java.awt.*;
import org.jfree.chart.*;
import org.jfree.chart.title.*;
import org.jfree.chart.plot.*;
import org.jfree.data.general.*;
import org.jfree.util.*;
import java.awt.event.*;
class PieChartExample extends JFrame
{
// A static variable represents pie chart angle
static int i=0;

    public PieChartExample()
    {
    setTitle("Pie chart example");
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(400,400);
    setLayout(new GridBagLayout());
    setLocationRelativeTo(null);
    setVisible(true);

    // Create a dataset   
    DefaultPieDataset p=new DefaultPieDataset();

    // Ratio of fruits
    // Apple:Orange:Mango:Guava = 20:30:40:10
    p.setValue("Apple",20);
    p.setValue("Orange",30);
    p.setValue("Mango",40);
    p.setValue("Guava",10);

    // Create a 3D chart with the given title that appears above the chart
    JFreeChart chart=ChartFactory.createPieChart3D("Popular fruits this season",p);

    // Get a ui representation of the pie chart title so that you can customize
    // the font and padding
    TextTitle tt=new TextTitle("Popular fruits this season",new Font("Arial",Font.BOLD,14));

    // Space around the text and between its border
    // top, left, bottom, right
    tt.setPadding(5,5,5,5);
    chart.setTitle(tt);

    // Get the PiePlot object so that you can customize the label font
    final PiePlot3D plot = (PiePlot3D) chart.getPlot();
    plot.setLabelFont(new Font("Arial",Font.PLAIN,12));
   
    // Chart will be drawn on a panel
    ChartPanel panel=new ChartPanel(chart);
   
    // Set some preferred size
    panel.setPreferredSize(new Dimension(350,350));
   
    // Add the panel
    add(panel);

    // Create a timer for animation
    // Executed every 150ms   
    Timer t=new Timer(150,new ActionListener(){
        public void actionPerformed(ActionEvent ae)
        {
            // Set the start angle, this increases everytime
            // timer is executed
            plot.setStartAngle(i++);
        }
    });

    // Start the timer (animation starts!)
    t.start();
    }

    public static void main(String args[])
    {
    SwingUtilities.invokeLater(new Runnable(){
        public void run()
        {
        new PieChartExample();
        }
    });
    }
}

Hope you enjoy this, feel free to share this post.

Tuesday, 22 April 2014

NameMatchMethodPoincut Example in Spring AOP

 
The following example illustrates NameMatchMethodPointcut which is filters methods (to which the advice should be applied to) by name.
If you aren't clear about what is a pointcut, I recommend strongly to read understanding pointcut and advisor and come back here.

Theme of the application

The theme of the application is to illustrate NameMatchMethodPointcut. This application contains a SimpleBean which contains four methods.
  1. ding()
  2. ding(int)
  3. dong()
  4. dong(int)
Now, the theme is to apply advices for those methods with the name ding. You can do it by writing a static pointcut and filter the method in matches(). But you don't need to do that much. Spring provides a class called NameMatchMethodPointcut that filters methods by name. This class will have a method called addMethodName() that takes in the name of the method and filters it based on that. You can add as many method names you want. Now we will be applying the logging advice only for the ding(), ding(int) method.

Create a project in eclipse

  1. File -> New -> Project -> Java Project
  2. Give the project name spring42 and click Finish 
  3. Now, the project is created.
  4. Under the Project Explorer (in the sidebar) you will see spring42. If you aren't able to see Project Explorer, go to Window menu -> Show view -> Project Explorer.
  5. Right click on the spring42 and click Properties
  6. On the left side, click on Java Build Path.
  7. Select the Libraries tab and then click on Add External Jars
  8. Now, add these jar files starting with: spring-core, aop-alliance, spring-aop, commons-logging
  9. Click on OK and then you are read

To create a class

In the Project Explorer, navigate to spring42 and right click on spring42. Then go to New -> Class and give the name of the class as defined below.
 

Project structure

 
 

SimpleBean.java



package spring42;

public class SimpleBean {

    public void ding()
    {
        System.out.println("Just ding()");
    }
   
    public void ding(int x)
    {
        System.out.println("ding("+x+")");
    }
   
    public void dong()
    {
        System.out.println("Just dong()");
    }
   
    public void dong(int x)
    {
        System.out.println("dong("+x+")");
    }
}

LoggingAdvice.java

This is an around advice which will log a message before and after the method invocation.


package spring42;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class LoggingAdvice implements MethodInterceptor {

private static Log log;
   
    static
    {
        log=LogFactory.getLog(LoggingAdvice.class);
    }
   
    public Object invoke(MethodInvocation mi) throws Throwable
    {
       
    Object val=null;
   
    // Get argument values
    Object[] args=mi.getArguments();
   
    String name=mi.getMethod().getName()+(args.length!=0?"("+args[0]+")":"()");
       
        if(log.isInfoEnabled())
        {
            log.info("Invoking method "+name);
           
            // Invoke the method now
            val=mi.proceed();
           
            log.info("Method execution completed");
        }
   
    return val;
    }
   
}

SpringPrg.java - Main class

This is the main class. In this class, we will create a NameMatchMethodPointcut object and add the method names to which the advice should be applied.


package spring42;

import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.NameMatchMethodPointcut;

public class SpringPrg {

    public static void main(String args[])
    {
        // Create target bean object
        SimpleBean sb=new SimpleBean();
      
        // Create a pointcut that filters methods by name
        NameMatchMethodPointcut pointcut=new NameMatchMethodPointcut();
      
        // The method to which the advice must be applied to
        // must be named ding
        pointcut.addMethodName("ding");
      
        // Create an advice
        Advice advice=new LoggingAdvice();
      
        // Create an advisor which is a combination
        // of pointcut and advice
        Advisor advisor=new DefaultPointcutAdvisor(pointcut,advice);
      
        // Create ProxyFactory
        ProxyFactory pf=new ProxyFactory();
      
        // Set the target bean object
        pf.setTarget(sb);
      
        // Add the advisor
        pf.addAdvisor(advisor);
      
        SimpleBean bean=(SimpleBean)pf.getProxy();
      
        // Advice will be applied to ding()
        bean.ding();
        bean.ding(10);
      
        // Advice will not be applied to dong()
        bean.dong();
        bean.dong(20);
    }
   
}

Output



 Apr 23, 2014 9:03:15 AM spring42.LoggingAdvice invoke
INFO: Invoking method ding()
Just ding()
Apr 23, 2014 9:03:15 AM spring42.LoggingAdvice invoke
INFO: Method execution completed
Apr 23, 2014 9:03:15 AM spring42.LoggingAdvice invoke
INFO: Invoking method ding(10)
ding(10)
Apr 23, 2014 9:03:15 AM spring42.LoggingAdvice invoke
INFO: Method execution completed
Just dong()
dong(20)

As you can see from the above output, there is no information logged before dong() and dong(20)
Also see dynamic pointcut and static pointcut

Monday, 21 April 2014

RowMapper Example in Spring JDBC


The following example illustrates using RowMapper interface to query for data as object. The RowMapper, the name itself says, as every row in a table is represented by an object, for every record that we obtain from the result set, we convert it into corresponding class object.

Brief view of the RowMapper interface

This interface contains only one method mapRow() which is as follows:

public Object mapRow(ResultSet rs, int rowNum);

You should write a class, which we call mapper class that implements this interface and provide bod for this method. This method should return the corresponding object which contains the data in that row.

Theme of the application

The theme of the application is to query for a particular record by sno. This application revolves around a student table that contains three columns sno, sname, age.

Project structure

spring50
          |_ jdbcContext.xml
          |_ spring50
                         |_ Student.java
                         |_ Student.class
                         |_ StudentDao.java
                         |_ StudentDao.class
                         |_ StudentMapper.java
                         |_ StudentMapper.class
                         |_ SpringPrg.java
                         |_ SpringPrg.class

jdbcContext.xml

This file contains two bean definitions. One pointing to the datasource object that contains details about database connection and the other is the dao class.


<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.2.xsd">

        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
            <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
            <property name="username" value="scott"/>
            <property name="password" value="tiger"/>
        </bean>

        <bean id="studentDao" class="spring50.StudentDao">
            <property name="datasource" ref="dataSource"/>
        </bean>

</beans>

Student.java

This bean class presents the table student in the database.

package spring50;

public class Student
{
private int sno;
private String sname;
private int age;

    public Student()
    {

    }

    public Student(int sno,String sname,int age)
    {
        this.sno=sno;
        this.sname=sname;
        this.age=age;
    }

    public void setSno(int sno)
    {
        this.sno=sno;
    }

    public int getSno()
    {
        return sno;
    }

    public void setSname(String sname)
    {
        this.sname=sname;
    }

    public String getSname()
    {
        return sname;
    }

    public void setAge(int age)
    {
        this.age=age;
    }

    public int getAge()
    {
        return age;
    }

    public String toString()
    {
        return sno+" "+sname+" "+age;
    }
}

StudentDao.java



package spring50;

import javax.sql.*;
import org.springframework.jdbc.core.JdbcTemplate;

public class StudentDao
{
private DataSource datasource;
private JdbcTemplate jdbcTemplate;

private String findBySno;
   
    {
        findBySno="select *from student where sno=?";
    }

    public void setDatasource(DataSource datasource)
    {
        this.datasource=datasource;
        jdbcTemplate=new JdbcTemplate(datasource);
    }

    public DataSource getDataSource()
    {
        return datasource;
    }

    public Student findBySno(int sno)
    {
        return jdbcTemplate.queryForObject(findBySno,new Object[]{sno},new StudentMapper());
    }

}

This class takes in datasource with the help of which it will create a JdbcTemplate object. This JdbcTemplate object is used to perform database operations. 
 
findBySno(int sno): This method returns the object that contains the details of a student with a particular sno. Here, we have used the method queryForObject() 
 
queryForObject(String sqlQuery, Object[] paramValues, RowMapper mapper) The first is the select command, next is the parameter values i.e. the values that should be put in place of ? in the command. Here there is only one ? and value that should be placed is sno. Next, is the StudentMapper class that you will see below. This method returns the Student object that contains the details queried from the database.


StudentMapper.java





package spring50;

import org.springframework.jdbc.core.*;
import java.sql.*;

public class StudentMapper implements RowMapper<Student>
{
    public Student mapRow(ResultSet rs,int rowNum) throws SQLException
    {
        Student st=new Student();
        st.setSno(rs.getInt("sno"));
        st.setSname(rs.getString("sname"));
        st.setAge(rs.getInt("age"));

        return st;
    }
}

Here, we will make use of the getInt(), getString() to get the details of that particular column in the row.


SpringPrg.java



package spring50;

import org.springframework.context.support.GenericXmlApplicationContext;

public class SpringPrg
{
    public static void main(String args[])
    {
        GenericXmlApplicationContext gc=new GenericXmlApplicationContext("classpath:jdbcContext.xml");

        StudentDao st=gc.getBean("studentDao",StudentDao.class);

        // find by sno
        Student student=st.findBySno(101);

        System.out.println(student);
    }
}
 
Here we pass in the sno to the findBySno() method and get the object as result.
 

Tuesday, 15 April 2014

Spring JdbcTemplate Example to Insert, Update


The following example illustrates using JdbcTemplate in Spring JDBC. This is an introductory example to the Spring JDBC module.

Theme of the application

The theme of the application is to illustrate the JdbcTemplate class. This class is the heart of the Spring JDBC module because it contains methods with which you will perform insert, update, delete, select operations.

In this example, we will insert a student record, update record details. We will have a bean class called Student that will have three columns sno, sname and age. The table student will also contain sno, sname and age columns.

In this example we will be using Oracle 11g Database Release 2 and 4th driver.

Brief view of JdbcTemplate

The JdbcTemplate class' constructor takes a datasource object. A datasource points to a database. It is used to get connection to the database. DriverManagerDataSource is an implementation of javax.sql.DataSource that takes 4 properties namely
  1. driverClassName - Name of the driver class used to connect to database. Here, Type 4 driver - oracle.jdbc.driver.OracleDriver
  2. url - URL to connect to the database.
  3. username
  4. password
Now, the JdbcTemplate knows the database it has to connect to. Using the methods in this class, we will perform database operations.

Create a project in eclipse

  1. File -> New -> Project -> Java Project
  2. Give the project name spring49 and click Finish 
  3. Now, the project is created.
  4. Under the Project Explorer (in the sidebar) you will see spring49. If you aren't able to see Project Explorer, go to Window menu -> Show view -> Project Explorer.
  5. Right click on the spring49 and click Properties
  6. On the left side, click on Java Build Path.
  7. Select the Libraries tab and then click on Add External Jars
  8. Now, add these jar files starting with: spring-core, spring-beans, spring-context, spring-aop, spring-jdbc, spring-tx, spring-expression, ojdbc6.jar or ojbdc14.jar, commons-logging
  9. Click on OK and then you are read

To create a class

In the Project Explorer, navigate to spring49 and right click on spring49. Then go to New -> Class and give the name of the class as defined below.
 

To create xml file

In the Project Explorer, navigate to spring49 and right click on src under spring49. Then go to New -> Other. Type xml file in the box and hit enter and give the name jdbcContext.xml
 

jdbcContext.xml

This file contains two bean definitions. One pointing to the datasource object that contains details about database connection and the other is the dao class.


<beans     xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jdbc="http://www.springframework.org/schema/jdbc"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                            http://www.springframework.org/schema/jdbc
                            http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd">

        <!-- Create datasource and give connection properties -->
        <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
            <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
            <property name="username" value="scott"/>
            <property name="password" value="tiger"/>
        </bean>

        <!-- Create the dao object and pass the datasource to it -->
        <bean id="studentDao" class="spring49.StudentDao">
            <property name="datasource" ref="datasource"/>
        </bean>

</beans>

Student.java - Bean

This bean class presents the table student in the database.


package spring49;

public class Student
{
private int sno;
private String sname;
private int age;

    public Student()
    {

    }

    public Student(int sno,String sname,int age)
    {
        this.sno=sno;
        this.sname=sname;
        this.age=age;
    }

    public void setSno(int sno)
    {
        this.sno=sno;
    }

    public void setSname(String sname)
    {
        this.sname=sname;
    }

    public void setAge(int age)
    {
        this.age=age;
    }

    public int getSno()
    {
        return sno;
    }

    public String getSname()
    {
        return sname;
    }

    public int getAge()
    {
        return age;
    }

    public String toString()
    {
        return sno+" "+sname+" "+age;
    }
}

StudentDao.java - Operations done here

This is the heart class because the operations are done here.


package spring49;

import javax.sql.*;
import org.springframework.jdbc.core.*;

public class StudentDao
{
private DataSource datasource;
private JdbcTemplate jdbcTemplate;
private String insertSql,updateSql;

    {
        insertSql="insert into student values(?,?,?)";
        updateSql="update student set sname=?,age=?, where sno=?";
    }

    public void setDatasource(DataSource datasource)
    {
        this.datasource=datasource;
        jdbcTemplate=new JdbcTemplate(datasource);
    }

    public void insert(Student st)
    {
        jdbcTemplate.update(insertSql,new Object[]{st.getSno(),st.getSname(),st.getAge()});
    }

    public void update(Student st)
    {
        jdbcTemplate.update(updateSql,new Object[]{st.getSname(),st.getAge(),st.getSno()});
    }

}

This class takes in datasource with the help of which it will create a JdbcTemplate object. This JdbcTemplate object is used to perform database operations.

insert(Student st) This method inserts the given student object into the database. For this, we will use the update() method which takes two parameters. The first being the SQL (the command) and the next is the parameters with which the question marks should be replaced with (in order).
Note that, the statement is similar to that as you have seen in PreparedStatement where the question marks are replaced with the corresponding arguments. The same applies here.

update(Student st) This is also the same as above, but the command is changed to updateSql and the order of the question marks is different, so is the order of the elements in the Object[].

Instead of using setInt(), setString() etc, this way is more precise. So this is an advantage with JdbcTemplate over PreparedStatement.

SpringPrg.java - Main class



 package spring49;

import org.springframework.context.support.GenericXmlApplicationContext;

public class SpringPrg
{
    public static void main(String args[])
    {
        GenericXmlApplicationContext gc=new GenericXmlApplicationContext("classpath:jdbcContext.xml");

        StudentDao st=(StudentDao)gc.getBean("studentDao");

        // To insert data
        st.insert(new Student(101,"Rama",20));
        st.insert(new Student(102,"Siva",22));
    }
}

Sunday, 13 April 2014

Dynamic Pointcut Example in Spring AOP

The following example illustrates using a dynamic pointcut. The difference between a static pointcut is that, in dynamic pointcut you can filter the method call instead of just the method. For example, you can apply the advice to ding(10); but not ding(20); In simple words, here you will get access to the argument values.
To achieve this, the dynamic pointcut is called every time the method is invoked because every time it is invoked, the argument value might change.

Theme of the application

The theme of the application is to illustrate a simple dynamic pointcut. Here, the method for which the advice will be applied is ding(). The prototype of this method is as follow

public void ding(int x);

This method takes an int parameter and prints the value. Now, an around advice is applied to it.
This advice contains the code that logs two messages. One message is printed before the method is invoked and the other after the method is invoked.
Now, we will be writing a pointcut to let the advice apply to only when the value passed to ding() is other than 100.

Create a project in eclipse

  1. File -> New -> Project -> Java Project
  2. Give the project name spring41 and click Finish 
  3. Now, the project is created.
  4. Under the Project Explorer (in the sidebar) you will see spring41. If you aren't able to see Project Explorer, go to Window menu -> Show view -> Project Explorer.
  5. Right click on the spring41 and click Properties
  6. On the left side, click on Java Build Path.
  7. Select the Libraries tab and then click on Add External Jars
  8. Now, add these jar files starting with: spring-core, aop-alliance, spring-aop, commons-logging
  9. Click on OK and then you are read

To create a class

In the Project Explorer, navigate to spring41 and right click on spring41. Then go to New -> Class and give the name of the class as defined below.
 

Project structure 


 

SimpleBean.java

This is the target bean class that contains the method ding() for which the advice is wrapped.


package spring41;

public class SimpleBean {

    public void ding(int x)
    {
        System.out.println("The value is "+x);
    }
   
}
 

MySimpleAdvice.java - Around advice 



package spring41;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MySimpleAdvice implements MethodInterceptor {

// Create a log object
private static Log log;

    static
    {
        // Create the log object
        log=LogFactory.getLog(MySimpleAdvice.class);
    }
   
    public Object invoke(MethodInvocation mi) throws Throwable
    {
    // Print the method call
    String name=mi.getMethod().getName()+"("+mi.getArguments()[0]+")";
   
    Object val=null;
   
        if(log.isInfoEnabled())
        {
            // log the detail
            log.info("Invoking method "+name);
           
            // call the method
            val=mi.proceed();
           
            // print method is invoked
            log.info("Method is invoked.");
        }
   
    // return val
    return val;
    }
   
}
 

SimpleDynamicPointcut.java

This class defines to which the advice should be applied.


package spring41;

import java.lang.reflect.Method;

import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.DynamicMethodMatcherPointcut;

public class SimpleDynamicPointcut extends DynamicMethodMatcherPointcut {

    // Filter the target class first
    @Override
    public ClassFilter getClassFilter() {
        return new ClassFilter(){
            @Override
            public boolean matches(Class<?> cls)
            {
                // Only SimpleBean class, not other classes
                return cls.getName().endsWith("SimpleBean");
            }
        };
    }

    @Override
    public boolean matches(Method method, Class<?> cls, Object[] args) {
      
        // Filter the method name, only for ding()
        // advice should be applied
        if(!method.getName().equals("ding")) return false;
      
        // Get the first argument
        int x=(Integer)args[0];
      
        // If x!=100 then it matches, else doesn't
        return x!=100;
    }

}
 
First, the getClassFilter() method is executed first and next matches() is executed. Here as you can see, the last argument is args which is of type Object[]. These are argument values passed to the method in order.

SpringPrg.java - Main class



package spring41;

import org.springframework.aop.Advisor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;

public class SpringPrg {

    public static void main(String args[])
    {
        // Create target bean object
        SimpleBean sb=new SimpleBean();
       
        // Create the pointcut object
        SimpleDynamicPointcut pointcut=new SimpleDynamicPointcut();
       
        // Create advice object
        MySimpleAdvice advice=new MySimpleAdvice();
        Advisor advisor=new DefaultPointcutAdvisor(pointcut,advice);

        // Create ProxyFactory
        ProxyFactory pf=new ProxyFactory();
       
        // Set the target object
        // Only methods in this object will be filtered
        pf.setTarget(sb);
       
        // Add the advisor
        pf.addAdvisor(advisor);
       
        // Get the proxied object
        SimpleBean bean=(SimpleBean)pf.getProxy();
       
        // Logging will be displayed
        // since x!=100
        bean.ding(10);
        bean.ding(101);
       
        // logging will not be displayed
        bean.ding(100);
    }
   
}

When you call ding(10) and ding(101) the advice will be applied, but not for ding(100).

Output



Apr 13, 2014 1:25:28 PM spring41.MySimpleAdvice invoke
INFO: Invoking method ding(10)
The value is 10
Apr 13, 2014 1:25:28 PM spring41.MySimpleAdvice invoke
INFO: Method is invoked.
Apr 13, 2014 1:25:28 PM spring41.MySimpleAdvice invoke
INFO: Invoking method ding(101)
The value is 101
Apr 13, 2014 1:25:28 PM spring41.MySimpleAdvice invoke
INFO: Method is invoked.
The value is 100

Also see method static pointcut example

Saturday, 12 April 2014

Static Pointcuts Example in Spring AOP


The following example illustrates creating a simple static pointcut in Spring AOP. As said in this post, a pointcut is a piece of code that decides for which methods the advice should be applied to.

A static pointcut is a type of point cut which filters methods on the basis of their name, the type of arguments, their class name etc but not by the values of the arguments passed to that method.

Theme of the application

The theme of the application is to illustrate a simple static pointcut. This pointcut defines that the advice should only be applied to a certain method. Here, that method is ding().
The ding() method contains a statement to print is a.
The advice is an around advice i.e. some statements are executed before method invocation and some after method invocation. Now, the statement before calling ding() is Rama and the statement after calling ding() is boy.
Altogether print, Rama is a boy as output. This is a simple program that will better explain a simple static point cut.

Create a project in eclipse

  1. File -> New -> Project -> Java Project
  2. Give the project name spring39 and click Finish 
  3. Now, the project is created.
  4. Under the Project Explorer (in the sidebar) you will see spring39. If you aren't able to see Project Explorer, go to Window menu -> Show view -> Project Explorer.
  5. Right click on the spring39 and click Properties
  6. On the left side, click on Java Build Path.
  7. Select the Libraries tab and then click on Add External Jars
  8. Now, add these jar files starting with: spring-core, aop-alliance, spring-aop, commons-logging
  9. Click on OK and then you are read

To create a class

In the Project Explorer, navigate to spring39 and right click on spring39. Then go to New -> Class and give the name of the class as defined below.

Project structure





SimpleBean.java

This class contains the method ding() for which the advice will be applied. This is the target bean class.


package spring39;

public class SimpleBean {

    public void ding()
    {
        System.out.print("is a");
    }
   
    public void dong()
    {
        System.out.println("is not");
    }
   
}

SimpleAdvice.java - Around advice

This is the class that contains the advice code that will be applied.


package spring39;

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

// A sample around advice
public class SimpleAdvice implements MethodInterceptor{

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
       
        // Statement before method exeuction
        System.out.print("Rama ");
       
        // This method is used to proceed to next before/around advice (if any)
        // otherwise, method is called simply
        Object val=mi.proceed();
       
        // Statement after method execution
        System.out.print(" boy");
       
        // Return the val, that indidates
        // that the method is invoked successfully
        // Next intercept will be proceeded if the val is returned
        return val;
    }

}

SimpleAdvice is the only advice defined in this example, so mi.proceed() invokes the method. Note that the invoke() method is called only for those methods that satisfy the pointcut below.

SimpleStaticPointcut.java



package spring39;

import java.lang.reflect.Method;

import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcut;

// A point cut defines methods for which the advice should be applied to
public class SimpleStaticPointcut extends StaticMethodMatcherPointcut {

    // Filters classes, this is executed first
    @Override
    public ClassFilter getClassFilter() {
        return new ClassFilter(){
           
            @Override
            public boolean matches(Class<?> cls) {
                // Only if the name of the class ends with SimpleBean
                return cls.getName().endsWith("SimpleBean");
            }
           
        };
    }

    // After matching the class, now lets go to the
    // methods in that class
    @Override
    public boolean matches(Method method, Class<?> cls) {
       
        // Only if the method name equals ding
        return (method.getName().equals("ding"));
    }

}

Here, first the class on whose object the method is called, is filtered. So getClassFilter() is first called. If the ClassFilter code decides to execute the method on that class. Then the matches() method is executed.

The matches() method is executed once for every method no matter how many times it is called. When the matches() is executed for a method, its value is cached i.e. whether that method is as specified in the matches().

Here, the code returns that only method with name ding() is allowed. Therefore, the invoke() method in the advice class is called only when ding() is called. So the advice is applied only for ding() but not for dong().

Now, ding() matches the pointcut, so its value is true. Next, dong() doesn't match the pointcut, so matches() will return false for dong(). Both these values are cached.

 First, matches() method is called on all the methods when you call getProxy() method. Next, again it is called when you call those methods the first time only. After, that no matter how many times you call those methods, matches() will not be called.

SpringPrg.java - Main class



package spring39;

import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;

public class SpringPrg {

    public static void main(String args[])
    {
        // Create target bean object
        SimpleBean sb=new SimpleBean();
       
        // Create a point cut that is static
        // a point cut defines which method(s) on
        // the target object should the advice be
        // applied to
        Pointcut p=new SimpleStaticPointcut();
       
        // An advice is the code that is a cross-cutting
        // concern
        Advice advice=new SimpleAdvice();
       
        // An advisor is a combination of advice and point cut
        // i.e. it defines to whom the advice should be given
        // and also the advice to be given
        Advisor advisor=new DefaultPointcutAdvisor(p,advice);
       
        // Create a ProxyFactory object
        ProxyFactory pf=new ProxyFactory();
       
        // Add the advisor
        // With this you are adding both the advice
        // and to which methods that should be applied
        pf.addAdvisor(advisor);
               
        // Set the target object
        pf.setTarget(sb);

        // Get the bean that is wrapped with advice
        SimpleBean bean=(SimpleBean)pf.getProxy();

        // call the proxied methods
        bean.ding();
       
        // a new line to separate both lines
        System.out.println();
       
        // call dong (advice will not be applied
        // to this method) as defined in the point cut
        bean.dong();
    }
   
}

Output



Rama is a boy
is not

Wednesday, 9 April 2014

Understanding Pointcut and Advisor in Spring AOP

Understanding pointcut and advisor in Spring

The following post teaches you the what is a point cut and advisor in Spring AOP.

What is a pointcut?

A point cut is a piece of code that decides for which methods the advice should be applied. In the previous examples, you have seen before, after and around advices. All of those advises apply for all the methods in the target object.
However, there may be some cases in which you might want the advice to apply only for certain methods. Then a point cut will be helpful.

What is an advisor?

You know what is an advice, it is nothing more than a piece of code that should be executed before or after or around the method but that should not be written in the body of the method.
You know the general meaning of an advisor, the one who advises. Usually the one who advises both gives the advice and tells how to apply it. In a similar way, the advisor in Spring AOP also gives the advice as well as tells for which method(s) the advice should be applied.
In more simple words, an advisor is an object pointing to a point cut and an advice.

In the previous examples, you have seen how we have added an advice using the addAdvice() method of the ProxyFactory class. Here, the advice is applied to all the methods in the target object. Now, we want to filter methods for which the advice should be applied. To do so, we define a point cut.
Instead of adding an advice using the addAdvice() method which applies advice to all the methods, we use the addAdvisor() method which takes in an Advisor object that defines what advice should be applied and to whom it should be applied.

Now whenever you execute a method on the target object, the condition is checked (i.e. whether the method matches the given condition a.k.a point cut). If the condition is satisfied, then the advice is applied to that method.

The Pointcut interface

The Pointcut interface represents a Point cut. This interface contains two methods.
  1. ClassFilter getClassFilter();
  2. MethodMatcher getMethodMatcher();
You will be writing a class that implements this interface and should provide body for these methods in order to create a pointcut. However, there are also some classes that implement this interface which you can extend or use directly to create pointcuts. We will talk about them later. Let me explain the two methods.

The first method should written a ClassFilter object. This filters the class of the target object. The ClassFilter contains a single method
  1. boolean matches(Class cls)
You will need to implement this method and using the Class parameter passed to this method, you will filter the class. For example, you might write this code in matches()

return (cls.getName().equals("MyBean"));

This matches only the class named MyBean.

The next method is MethodMatcher. This matches the method. For example, you will want to filter the method by its name. The MethodMatcher interface contains three methods.
  1. boolean isRuntime()
  2. boolean matches(Method method, Class targetClass)
  3. boolean matches(Method method, Class targetClass, Object[] args)
Now, here we will have to discuss about two types of point cuts. Let's talk about them later. But for now, we will discuss last two methods.

The first method takes in two parameters that Method and Class with which you can filter the methods. For example, using this method you can filter methods by name, their class, the no. of arguments, the types of arguments.

The second method is the same as above method, but you can filter the method by the values passed to the method too. For example, consider a method foo(int x)

Now, you might want the advice to be applied to foo(10) but not foo(20) or foo(anyValueOtherThanTen)
Then, in such cases this will be helpful.
You might have a doubt, if the matches has the Class parameter, then why do we need getClassFilter(). The answer is that, while checking whether an advice should be applied to a method, the getClassFilter() method is executed first before the getMethodMatcher() because if first, the target class satisfies the given condition, then go for checking the method. If the class doesn't, then the there is no need of checking if the method satisfies. This saves a lot of time.