Friday, March 20, 2015

Pointcut with args()

There can be errors difficult to catch if you do not define the pointcut precisely specially with the args(name)

we are using args() to catch the JoinPoint with argumets.

Eg: we write a Pontcut to catch setter for Circle.java

----------------------------------------------------------------------------------------
package org.aop.service;

import org.aop.model.Circle;
import org.aop.model.Triangle;

public class ShapeService {

 private Circle circle;
 private Triangle triangle;

 public Circle getCircle() {
  return circle;
 }

 public void setCircle(Circle circle) {
  this.circle = circle;
 }

 public Triangle getTriangle() {
  return triangle;
 }

 public void setTriangle(Triangle triangle) {
  this.triangle = triangle;
 }

}

----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
package org.aop.model;

public class Circle {

 private String name;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

}

----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);


shapeService.getCircle().setName("dummy name");
}

}

----------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------
package org.aop.aspect;

import org.aop.model.Circle;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoginAspect {



@Before("argumentMethods(name)")
public void secondAdvice(String name) {
System.out.println("Second advice executed."+ name);
}



@Pointcut("args(name)")
public void argumentMethods(String name) {
}

}


----------------------------------------------------------------------------------------

As shown above we have pointcut argumentMethods

----------------------------------------------------------------------------------------
@Pointcut("args(name)")
public void argumentMethods(String name) {
}
----------------------------------------------------------------------------------------

it is used in the advice = secondAdvice

----------------------------------------------------------------------------------------
 @Before("argumentMethods(name)")
 public void secondAdvice(String name) {
 System.out.println("Second advice executed."+ name);
 }
----------------------------------------------------------------------------------------

If any case we forget include parameter "name", there will be exception.It's exception in initializing the beans. Because of this simple thing, all initialization fails.

eg: we remove the name parameter from advice method
Note : parameter  missing name in the secondAdvice
----------------------------------------------------------------------------------------
 @Before("argumentMethods(name)")
public void secondAdvice() {
System.out.println("Second advice executed.");
}
----------------------------------------------------------------------------------------

exception will be
----------------------------------------------------------------------------------------
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'triangle' defined in class path resource [spring.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: warning no match for this type name: name [Xlint:invalidAbsoluteTypeName]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
at org.aop.main.AppMain.main(AppMain.java:9)
Caused by: java.lang.IllegalArgumentException: warning no match for this type name: name [Xlint:invalidAbsoluteTypeName]
at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:209)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:196)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:185)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:166)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:208)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:262)
at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:294)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:118)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:88)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:69)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:359)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1518)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
... 11 more


Join Point and Pointcut

Here we try to understand few keywords used in aspect oriented programming, AOP.
Joinpoint, PointCut and Advice

Aspect
This is a cross cutting concern over the object model in the program which can be used to modularization.
eg :Logging , Transaction Management , Security

JoinPoint
Point where we apply our aspect concept. Or Point during the execution of method.
JoinPoint term used from Object perspective , or in simple term used to show where our aspect concept

PointCut
The predicate which matches the JoinPoint is called Pointcut.

Advice
Action done by Aspect in the Joint is called Advice.

To give you more understanding.
Let's take Java, OOP class Circle.java with one attribute name. It has getter and setter.
We need to apply logging to getName and SetName
Two methods are show below with bold letters.

getName() and setName(String name) are tow JoinPoints.
Note : JoinPoint is in the Java OOP class
--------------------------------------------------------------------------------------

package org.aop.model;

public class Circle {

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
System.out.println("Circle set name =" + name);
}

}

----------------------------------------------------------------------------------------------


The  to make logging. We are not using OOP.
now we are in AOP. So define Aspect.
Our Aspect name is "LogginAspect"
to make it Aspect, we annotate with @Aspect
So here after, The Aspect is taken care with the Spring FrameWork.
This is form of modularization.

LoginAspect.java
----------------------------------------------------------------------------------------------
package org.aop.aspect;

import org.aspectj.lang.annotation.Aspect;


@Aspect
public class LoginAspect {

}

----------------------------------------------------------------------------------------------


We have defined the Aspect, LoginAspect
Now we need to define the what we need to do(Advice) in the JoinPoint(The method we are going to add logging - logging is the action we are doing)

We define Advice inside the Aspect.
Aspect can have more than one advice.
Let's define our Advice in the Aspect - LoginAspect
To define Advice, we define a method.
As we need to add a log statement let's name it as loginAdvice
so the Advice method would like

----------------------------------------------------------------------------------------------
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

----------------------------------------------------------------------------------------------

Above shows the whole body of the advice.
To go through from the beginning, once again

public  - access modifier - access for whole world
void - return type - no return
loginAdvice() -  name of the advice "loginAdvice" with no parameters. we can have parameters if needed
Inside the method , you have sysout , the logging part

System.out.println("Login advice run::get method called");


But we have a problem

Now we have the JoinPoint - The Circle.java  - two methods
Aspect - LoginAspect.java
inside LoginAspect.java we have defined the method loginAdvice 
But with this Advice does not become complete. Still incomplete

How the Advice know the methods it should apply the advice.
In simple, how the advice bind to the JoinPoint.

We need to give the Joinpoint to advice, or we need to tell the advice
hey.. this is where you need to do your work.

We have to give it as pattern, as are going to apply the advice to all methods

Note: We are using aspectj dependency, not spring aspect. aspectj has more options, where we can add aspects/advice not only to methods , but also to fields
eg: Circle has attribute "name" and a getter and a setter
with aspectj ,  you can trace all three, including the attribute/filed "name".
If you use spring aspect, then you can't take attribute/filed "name"


So let's back in to our scenario.
We need to tell the advice, this is your method-JoinPoint you need to look at and do the work

The predicate , or the pattern is called the ''Pointcut"

There are various ways to write the Pointcut using pattern.

To match all the methods, our predicate will be

"within(org.aop.model.Circle"

This tell the Advice, to match all the methods within the Circle object.

But when we need to program the advice, we have to tell the type of the advice
That is Before, After  etc.
Before  - Advice runs before at JoinPoint
After - Advice runs after exit anyway at JoinPoint
After Returning - Advice runs after JoinPoint normal completion
After Throwing - Advice runs when method exit throwing an exception
Around - Advice runs surrounding the JoinPoint

In our case, we decide to run the Advice Before at the JoinPoint

So our Advice will look like below

----------------------------------------------------------------------------------------------
@Before("within(org.aop.model.Circle)")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

----------------------------------------------------------------------------------------------

Note:

@Before  - type of the advice - tell run before at the JoinPoint , this is part of Advice

"within(org.aop.model.Circle)"  - this is the PointCut , it is given withing quotes.

So after all your Aspect will look like below


----------------------------------------------------------------------------------------------
package org.aop.aspect;

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


@Aspect
public class LoginAspect {

@Before("within(org.aop.model.Circle)")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

}

----------------------------------------------------------------------------------------------

So if you run the program, output will be as below

========================================================
Circle set name =Circle name
Login advice run::get method called
Circle name
========================================================


Output has three lines

Line 1 : Circle set name =Circle name
    This comes as a result of the bean definition. We are setting value for name in the circle object


 <bean name="circle" class="org.aop.model.Circle">
  <property name="name" value="Circle name"></property>
 </bean>

and we have a sysout defined inside the setter method in Circle.java

public void setName(String name) {
this.name = name;
System.out.println("Circle set name =" + name);
}

Line 2 : Login advice run::get method called

This line come from the Aspect. This is what we have applied
our loginAdvice method or as a result of the action from the loginAdvice
above code line/ log statement (here we have used sysout) added

@Before("within(org.aop.model.Circle)")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}


As we have defined Advice as Before , it executes before at the JoinPoint "public String getName() "
To make sure we have called the getName , we are printing the output if it-this print after the advice action in line 3

Line 3: Circle name

This is coming from our main method. we execute getName and print the output.


Out Main method / test code

AppMain .java
----------------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);


System.out.println(shapeService.getCircle().getName());

}

}

----------------------------------------------------------------------------------------------
POM.XML  this include more dependencies , more than needed

----------------------------------------------------------------------------------------

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.test</groupId>
 <artifactId>AOP</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <name>AOP</name>
 <description>Aspect Oriented Programming</description>

 <properties>
  <jdk.version>1.6</jdk.version>
  <spring.version>3.2.8.RELEASE</spring.version>
  <spring.security.version>3.2.3.RELEASE</spring.security.version>
  <jstl.version>1.2</jstl.version>
  <javax.servlet.version>3.1.0</javax.servlet.version>
  <mysql.connector.version>5.1.30</mysql.connector.version>
 </properties>

 <dependencies>
  <!-- Spring 3 dependencies -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <!-- spring jdbc -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-jdbc</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <!-- Spring Security -->
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-web</artifactId>
   <version>${spring.security.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-config</artifactId>
   <version>${spring.security.version}</version>
  </dependency>

  <!-- AOP -->
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjrt</artifactId>
   <version>1.7.3</version>
  </dependency>

  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.6.11</version>
  </dependency>

  <!-- connect to mysql -->
  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>${mysql.connector.version}</version>
  </dependency>


 </dependencies>
</project>
----------------------------------------------------------------------------------------

spring.xml  - bean definition , this include Triangle and ShapeService
----------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

 <aop:aspectj-autoproxy />

 <bean name="triangle" class="org.aop.model.Triangle">
  <property name="name" value="Traingle name"></property>
 </bean>

 <bean name="circle" class="org.aop.model.Circle">
  <property name="name" value="Circle name"></property>
 </bean>

 <bean name="shapeService" class="org.aop.service.ShapeService"
  autowire="byName"></bean>

 <bean name="loginAspect" class="org.aop.aspect.LoginAspect"></bean>

</beans>
----------------------------------------------------------------------------------------
Triangle.java
----------------------------------------------------------------------------------------
package org.aop.model;

public class Triangle {
 private String name;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
}

----------------------------------------------------------------------------------------
ShapeService .java
----------------------------------------------------------------------------------------
package org.aop.service;

import org.aop.model.Circle;
import org.aop.model.Triangle;

public class ShapeService {

 private Circle circle;
 private Triangle triangle;

 public Circle getCircle() {
  return circle;
 }

 public void setCircle(Circle circle) {
  this.circle = circle;
 }

 public Triangle getTriangle() {
  return triangle;
 }

 public void setTriangle(Triangle triangle) {
  this.triangle = triangle;
 }

}

----------------------------------------------------------------------------------------

Continue Story..............

We have not defined the pointcut seperately.
we can define sperate Pointcut  with annotation @Pointcut

so our Pointcut will look like below

----------------------------------------------------------------------------------------
@Pointcut("within(org.aop.model.Circle)")
public void allCircleMethods() {
}

----------------------------------------------------------------------------------------

Note : we had to make dummy method. we need dummy method to hold the PointCut. we will be using the name of the dummy method name in the Pointcut to reference the Pointcut.
So new advice will look like

----------------------------------------------------------------------------------------
@Before("allCircleMethods()")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

----------------------------------------------------------------------------------------

So after change Our Aspect will look as

----------------------------------------------------------------------------------------
package org.aop.aspect;

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

@Aspect
public class LoginAspect {

@Before("allCircleMethods()")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}


@Pointcut("within(org.aop.model.Circle)")
public void allCircleMethods() {
}

}
---------------------------------------------------------------------------------------



Now to get a more better Idea, understanding we can use the JoinPoint provided by the aspecj and see the actual joint point.
We can define parameter for advice of type JoinPoint and print it. This will call toString() and print method -JoinPoint matching Pointcut

New Aspect and Out will be as follows

---------------------------------------------------------------------------------------
package org.aop.aspect;

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

@Aspect
public class LoginAspect {

@Before("allCircleMethods()")
public void loginAdvice(JoinPoint joinPoint) {
System.out.println(joinPoint);
}

@Pointcut("within(org.aop.model.Circle)")
public void allCircleMethods() {
}

}

---------------------------------------------------------------------------------------

OutPut
====================================================

Circle set name =Circle name
execution(String org.aop.model.Circle.getName())
Circle name

====================================================

Note :
at Line 2 , it is printing the value of JoinPoint , we have change the advice to print the JoinPoint , instead of just sysout.

We can see the target object as well, it will the Circle object

---------------------------------------------------------------------------------------
package org.aop.aspect;

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

@Aspect
public class LoginAspect {

@Before("allCircleMethods()")
public void loginAdvice(JoinPoint joinPoint) {
System.out.println(joinPoint.getTarget());
}


@Pointcut("within(org.aop.model.Circle)")
public void allCircleMethods() {
}

}
---------------------------------------------------------------------------------------

OutPut
====================================================

Circle set name =Circle name
org.aop.model.Circle@3f130f01
Circle name

====================================================



Line 2: Target object Circle is printed.



As above shown, you can get the target object from getTarget() and you can cast to needed Object and use it as needed in side advice.

eg : we are using Circle object
it will look as follows

---------------------------------------------------------------------------------------
@Before("allCircleMethods()")
public void loginAdvice(JoinPoint joinPoint) {
Circle circle =(Circle)joinPoint.getTarget();
              //do something
}
---------------------------------------------------------------------------------------


Thursday, March 19, 2015

Write few Pointcuts with wild cards

We are using same code in
http://cgenit.blogspot.com/2015/03/create-simple-maven-app-to-test-and.html with some modifications

We have made a simple applicatioon to test and run the AOP concept.
Here we have taken the logging aspect as a cross cutting concern.
Created LoginAspect.java and made it aspect using @Aspect and written advice using
@Before("execution(public String getName())")
The two object classes we have used is Circle and Triangle, where both having simple attribute name with getter and setter.
So we need to log it whenever the getter called.
We have created ShapeService class to get the object, for better standard way to present.
AppMain.java is used to test the application.

Pom.xml and spring.xml does not have any changes
We are changing LoginAspect.java - @Aspect class and test code changes with AppMain.java

Now here 
1. We won't to write a PointCut to execute logging for all the methods in the Circle object.
We are writing
@Pointcut("execution(* * org.aop.model.Circle.*(..))")
for any access modifier
any return type
only Circle class
all the methods
with any parameter

@Pointcut("execution(* * org.aop.model.Circle.*(..))")

public void allCircleMethods(){}


But this is not much readable , we have better way of writing this
more readable way. using  within

I have commented other methods
-------------------------------------------------------------------------------

package org.aop.aspect;

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

@Aspect
public class LoginAspect {

// @Before("allGetters()")
// public void loginAdvice() {
// System.out.println("Login advice run::get method called");
// }
//
// @Before("allGetters()")
// public void secondAdvice() {
// System.out.println("Second advice executed.");
// }


@Before("allCircleMethods()")
public void allCircleAdvice() {
System.out.println("All circle executed.");
}


// @Pointcut("execution(public * *get*())")
// public void allGetters(){}

@Pointcut("within(org.aop.model.Circle)")
public void allCircleMethods(){}



}






--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);

System.out.println(shapeService.getTriangle().getName());
System.out.println(shapeService.getCircle().getName());
}


}

--------------------------------------------------------------------------------
output Now : Note = No advice run for Triangle
===============================================================
Traingle name
All circle executed.
Circle name



===============================================================


2. Modify for all methods in the package 
just replace Circle with star


@Pointcut("within(org.aop.model.*)")

public void allCircleMethods(){}

output Now : Note =  advice run for Triangle
===============================================================
All circle executed.
Traingle name
All circle executed.
Circle name




===============================================================


3. There are few matches with Pointcut
eg: args()

4. You can combine Poincuts
First let's look at output before combining
we are running only get method for Circle.

--------------------------------------------------------------------------------
package org.aop.aspect;

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

@Aspect
public class LoginAspect {

@Before("allGetters()")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

@Before("allGetters()")
public void secondAdvice() {
System.out.println("Second advice executed.");
}

@Before("allCircleMethods()")
public void allCircleAdvice() {
System.out.println("All circle executed.");
}

@Pointcut("execution(public * *get*())")
public void allGetters() {
}

@Pointcut("within(org.aop.model.Circle)")
public void allCircleMethods() {
}


}


--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);

// System.out.println(shapeService.getTriangle().getName());
System.out.println(shapeService.getCircle().getName());
}


}

--------------------------------------------------------------------------------

output Now : 
===============================================================
Login advice run::get method called
Second advice executed.
All circle executed.
Login advice run::get method called
Second advice executed.
Circle name


===============================================================


Now combine with &&

@Before("allGetters() && allCircleMethods()")
public void loginAdvice() {
System.out.println("Login advice run::get method called");

}


output after combinig with && 
===============================================================
Second advice executed.
All circle executed.
Login advice run::get method called
Second advice executed.
Circle name


===============================================================

Now combine with ||
@Before("allGetters() || allCircleMethods()")
public void loginAdvice() {
System.out.println("Login advice run::get method called");

}


output after combinig with || 
===============================================================
Login advice run::get method called
Second advice executed.
All circle executed.
Login advice run::get method called
Second advice executed.
Circle name


===============================================================

pointcut and wild cards

Below is the code used to explain the logics
http://cgenit.blogspot.com/2015/03/create-simple-maven-app-to-test-and.html

We have made a simple applicatioon to test and run the AOP concept.
Here we have taken the logging aspect as a cross cutting concern.
Created LoginAspect.java and made it aspect using @Aspect and written advice using
@Before("execution(public String getName())")
The two object classes we have used is Circle and Triangle, where both having simple attribute name with getter and setter.
So we need to log it whenever the getter called.
We have created ShapeService class to get the object, for better standard way to present.
AppMain.java is used to test the application.

POM.XML  this include more dependencies , more than needed

----------------------------------------------------------------------------------------

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>AOP</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>AOP</name>
<description>Aspect Oriented Programming</description>

<properties>
<jdk.version>1.6</jdk.version>
<spring.version>3.2.8.RELEASE</spring.version>
<spring.security.version>3.2.3.RELEASE</spring.security.version>
<jstl.version>1.2</jstl.version>
<javax.servlet.version>3.1.0</javax.servlet.version>
<mysql.connector.version>5.1.30</mysql.connector.version>
</properties>

<dependencies>
<!-- Spring 3 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>

<!-- spring jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>

<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>

<!-- AOP -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.3</version>
</dependency>

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
</dependency>

<!-- connect to mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.version}</version>
</dependency>


</dependencies>
</project>
----------------------------------------------------------------------------------------

spring.xml  - bean definition
----------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

<aop:aspectj-autoproxy />

<bean name="triangle" class="org.aop.model.Triangle">
<property name="name" value="Traingle name"></property>
</bean>

<bean name="circle" class="org.aop.model.Circle">
<property name="name" value="Circle name"></property>
</bean>

<bean name="shapeService" class="org.aop.service.ShapeService"
autowire="byName"></bean>

<bean name="loginAspect" class="org.aop.aspect.LoginAspect"></bean>

</beans>
----------------------------------------------------------------------------------------

Circle.java
----------------------------------------------------------------------------------------
package org.aop.model;

public class Circle {

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}

----------------------------------------------------------------------------------------
Triangle.java
----------------------------------------------------------------------------------------
package org.aop.model;

public class Triangle {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

----------------------------------------------------------------------------------------
ShapeService .java
----------------------------------------------------------------------------------------
package org.aop.service;

import org.aop.model.Circle;
import org.aop.model.Triangle;

public class ShapeService {

private Circle circle;
private Triangle triangle;

public Circle getCircle() {
return circle;
}

public void setCircle(Circle circle) {
this.circle = circle;
}

public Triangle getTriangle() {
return triangle;
}

public void setTriangle(Triangle triangle) {
this.triangle = triangle;
}

}

----------------------------------------------------------------------------------------
LoginAspect .java
----------------------------------------------------------------------------------------
package org.aop.aspect;

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

@Aspect
public class LoginAspect {

@Before("execution(public String getName())")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

}

--------------------------------------------------------------------------------------------------------------------------
AppMain .java
--------------------------------------------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);

System.out.println(shapeService.getTriangle().getName());
}

}

------------------------------------------------------------------------------------------------------------

output Now
===============================================================
Login advice run::get method called
Traingle name


===============================================================


1. Need to limit only for specific class / object get method.
Above aspect's advice, the action taken is executed for each get method.
Limit only for circle getmethod();

we give the path to the method inside execution()

package org.aop.aspect;

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

@Aspect
public class LoginAspect {

@Before("execution(public String org.aop.model.Circle.getName())")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

}

Output for main method
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);

System.out.println(shapeService.getCircle().getName());
}

}


Output
===============================================================
Login advice run::get method called
Circle name
===============================================================

Let's execute this for Triangle as well to get confirm
===============================================================
Traingle name
===============================================================


2. give a wild card. Execute for any getMethod

package org.aop.aspect;

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

@Aspect
public class LoginAspect {

@Before("execution(public String *get*())")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

}

-----------------
Main class
-----------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);

System.out.println(shapeService.getTriangle().getName());
System.out.println(shapeService.getCircle().getName());
}

}



output
===============================================================
Login advice run::get method called
Traingle name
Login advice run::get method called
Circle name

===============================================================

4. Next try with any return type and any parameter 
to test we put a parameter for getter for circle


------------------------------
package org.aop.model;

public class Circle {
private String name;

public String getName(String s) {
return name;
}

public void setName(String name) {
this.name = name;
}

}
-------------------------------------

package org.aop.aspect;

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

@Aspect
public class LoginAspect {
@Before("execution(public * *get*(*))")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

}
-------------------------------
in execution
1. first we have public - access modifier
2. *  pink star for any return type
3. * black star for any package structure and class 
4. * Next star for any method start fro get prefix
5. * Next, red star for any parameter 
--------------------------------

So the output will be - Note: For triangle get method advice / action logging not executing. It does not have parameter
===============================================================
Traingle name
Login advice run::get method called
Circle name
===============================================================

5. If we change the circle get for two parameters,
there won't be any executing advice, logging action

package org.aop.model;

public class Circle {
private String name;

public String getName(String s,String ss) {
return name;
}

public void setName(String name) {
this.name = name;
}

}

----------------------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);

System.out.println(shapeService.getTriangle().getName());
System.out.println(shapeService.getCircle().getName("s","ss"));
}

}
-------------------------------------------------------------------------------------

output
===============================================================
Traingle name
Circle name

===============================================================


6. How to make it for any parameter. use two dots(..) elipse instead of star (*)
Here Circle getter has three parameters

-------------------------------------------------------------------------------------
package org.aop.aspect;

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

@Aspect
public class LoginAspect {
@Before("execution(public * *get*(..))")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

}

-------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------
package org.aop.model;

public class Circle {
private String name;

public String getName(String s,String ss,String sss) {
return name;
}

public void setName(String name) {
this.name = name;
}

}

-------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);

System.out.println(shapeService.getTriangle().getName());
System.out.println(shapeService.getCircle().getName("s","ss","SSS"));
}

}

-------------------------------------------------------------------------------------

output  Note: Advice run twice
===============================================================
Login advice run::get method called
Login advice run::get method called
Traingle name
Login advice run::get method called
Login advice run::get method called
Circle name

===============================================================

7. Let's run only for Circle getter with three parameters

-------------------------------------------------------------------------------------
package org.aop.model;

public class Circle {
private String name;

public String getName(String s,String ss,String sss) {
return name;
}

public void setName(String name) {
this.name = name;
}

}

-------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);

System.out.println(shapeService.getTriangle().getName());
System.out.println(shapeService.getCircle().getName("s","ss","SSS"));
}

}

-------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------
package org.aop.aspect;

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

@Aspect
public class LoginAspect {
@Before("execution(public * *get*(*,*,*))")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

}

-------------------------------------------------------------------------------------
output  Note: Advice only run before circle getter
===============================================================
Traingle name
Login advice run::get method called
Circle name
===============================================================


8. Have another advice with same matching expression, secondAdvice
Both advice has matching @Before("execution(public * *get*())")

-------------------------------------------------------------------------------------
package org.aop.aspect;

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

@Aspect
public class LoginAspect {
@Before("execution(public * *get*())")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}
@Before("execution(public * *get*())")
public void secondAdvice() {
System.out.println("Second advice executed.");
}


}

-------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);

System.out.println(shapeService.getTriangle().getName());
System.out.println(shapeService.getCircle().getName());
}

}

-------------------------------------------------------------------------------------

output  Two sets for Triangle and Circle
===============================================================
Login advice run::get method called
Second advice executed.
Login advice run::get method called
Second advice executed.
Traingle name
Login advice run::get method called
Second advice executed.
Login advice run::get method called
Second advice executed.
Circle name

===============================================================

9. Pointcut
As shown in above both advice has the same method, point where method/advice executes
So that is called pointcut
we can define Pointcut and share among two Advices. 
It is easy, and resusability.

Note: We have to use a dummy method. and we are giving the name of the dummy method(poincut) to match the advice / configure the advice.

I have used allGetters() dummy method to hold the PointCut
and changed @Before expression to "allGetters"


New Aspect
-------------------------------------------------------------------------------------
package org.aop.aspect;

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

@Aspect
public class LoginAspect {
@Before("allGetters()")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}
@Before("allGetters()")
public void secondAdvice() {
System.out.println("Second advice executed.");
}
@Pointcut("execution(public * *get*())")
public void allGetters(){}


}

-------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);

System.out.println(shapeService.getTriangle().getName());
System.out.println(shapeService.getCircle().getName());
}

}

-------------------------------------------------------------------------------------

output  Two sets for Triangle and Circle
===============================================================
Login advice run::get method called
Second advice executed.
Login advice run::get method called
Second advice executed.
Traingle name
Login advice run::get method called
Second advice executed.
Login advice run::get method called
Second advice executed.
Circle name

===============================================================


10. Not define Pointcut well.
You have to define the pointcut as a method to advice
That is, it needs to have ()  after method name  "allGetters()"
If fail to define ()  will have exception

Below allGetters  does not have ()

@Before("allGetters")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}



output  Two sets for Triangle and Circle
First to get bean triangle and execute getter
at this point Pointcut comes to play
fails as not well defined
===============================================================
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'triangle' defined in class path resource [spring.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting '(' at character position 0
allGetters
^

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
at org.aop.main.AppMain.main(AppMain.java:9)
Caused by: java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting '(' at character position 0
allGetters
^

at org.aspectj.weaver.tools.PointcutParser.resolvePointcutExpression(PointcutParser.java:316)
at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:294)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:209)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:196)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:185)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:166)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:208)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:262)
at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:294)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:118)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:88)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:69)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:359)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1518)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
... 11 more


===============================================================