Thursday, March 26, 2015

Exceptions in spring configuration

This is to give you some details about the exceptions and how will they come. I have refered the code I explained in the
http://cgenit.blogspot.com/2015/03/spring-basic-collection-list.html  to generate the exceptions.

Here we have used a list points inside the Triangle class and we are injecting the beans for the Triangle.
We have circle bean definition , another bean we use.

So to refresh the xml configuration, it will look like below


spring.xml
--------------------------------------------------------------------------------------------------------------------
<bean name="triangle" class="org.aop.model.Triangle">
<property name="name" value="Traingle name"></property>
<property name="points">
<list>
<ref bean="zeroPoint" />
<ref bean="pointTwo" />
<ref bean="pointThree" />
</list>
</property>
</bean>

<bean name="zeroPoint" class="org.aop.model.Point">
<property name="x" value="0"></property>
<property name="y" value="0"></property>
</bean>
<bean name="pointTwo" class="org.aop.model.Point">
<property name="x" value="20"></property>
<property name="y" value="0"></property>
</bean>
<bean name="pointThree" class="org.aop.model.Point">
<property name="x" value="0"></property>
<property name="y" value="20"></property>
</bean>

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

 Error No 1: Let's add a circle to the points list. We have defined list as Points generic list inside the Triangle object.

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

package org.aop.model;

import java.util.List;

public class Triangle {
private String name;
private List points;

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getPoints() {
return points;
}
public void setPoints(List points) {
this.points = points;
}
@Override
public String toString() {
return "Triangle [name=" + name + ", points=" + points + "]";
}

}

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

Now this will give us conversion error and tell us bean creation does not know any strategy to convert the circle bean to Point. I have highlighted the text line where we can identify the error.


error code , adding circle bean highlighted.

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

<bean name="triangle" class="org.aop.model.Triangle">
<property name="name" value="Traingle name"></property>
<property name="points">
<list>
<ref bean="zeroPoint" />
<ref bean="pointTwo" />
<ref bean="pointThree" />
<ref bean="circle" />
</list>
</property>
</bean>

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


Below is the exception.
---------------------------------------------------------------------------------------------------

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 org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.util.ArrayList' to required type 'java.util.List' for property 'points'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.aop.model.Circle$$EnhancerBySpringCGLIB$$bb74d74b] to required type [org.aop.model.Point] for property 'points[3]': no matching editors or conversion strategy found
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:10)
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.util.ArrayList' to required type 'java.util.List' for property 'points'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.aop.model.Circle$$EnhancerBySpringCGLIB$$bb74d74b] to required type [org.aop.model.Point] for property 'points[3]': no matching editors or conversion strategy found
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:463)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:494)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:488)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1463)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1158)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
... 11 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type [org.aop.model.Circle$$EnhancerBySpringCGLIB$$bb74d74b] to required type [org.aop.model.Point] for property 'points[3]': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:267)
at org.springframework.beans.TypeConverterDelegate.convertToTypedCollection(TypeConverterDelegate.java:562)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:202)
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:448)
... 17 more


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


2. Error 2: let's try to add the Triangle class to Point bean definition.
Point class has two properties with name "x" and "y" and we have defined the values to be inject in bean creation in our spring.xml configuration. 
Now we have mistakenly given Triangle class to place where we need to give Point class.
As Triangle does not have setter for the defined property values it will give error when setting those properties when creating bean from the definition given.

error code inside spring.xml


------------------------------------------------------------------------------------------------------------------------
<bean name="zeroPoint" class="org.aop.model.Triangle">
<property name="x" value="0"></property>
<property name="y" value="0"></property>
</bean>
------------------------------------------------------------------------------------------------------------------------

Below is the exception
------------------------------------------------------------------------------------------------------------------------
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'triangle' defined in class path resource [spring.xml]: Cannot resolve reference to bean 'zeroPoint' while setting bean property 'points' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'zeroPoint' defined in class path resource [spring.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'x' of bean class [org.aop.model.Triangle]: Bean property 'x' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:326)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:107)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:350)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:154)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1417)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1158)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
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:10)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'zeroPoint' defined in class path resource [spring.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'x' of bean class [org.aop.model.Triangle]: Bean property 'x' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1453)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1158)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
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.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:320)
... 17 more
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'x' of bean class [org.aop.model.Triangle]: Bean property 'x' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1043)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:903)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:75)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:57)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1450)
... 25 more

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

Spring Basic - Collection List

Let's look at how we do the bean definitions to the List, Collection object.
Here also we use basic spring maven project and introduce the Point object which we use as a attribute in the Triangle to set the three points.
We are giving the tree points as a list to Triangle.
basic ode structure and package is as below
http://cgenit.blogspot.com/2015/03/aop-basic-application-code-and.html

The new class Point , we need to define three instances , as Triangle requires three points.
Point class will be as follows

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

public class Point {
private int x;
private int y;

public int getX() {
return x;
}

public void setX(int x) {
this.x = x;
}

public int getY() {
return y;
}

public void setY(int y) {
this.y = y;
}

@Override
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}


}

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

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

import java.util.List;

public class Triangle {
private String name;
private List<Point> points;

public String getName() {
return name;
}

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

public List<Point> getPoints() {
return points;
}

public void setPoints(List<Point> points) {
this.points = points;
}

@Override
public String toString() {
return "Triangle [name=" + name + ", points=" + points + "]";
}


}

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

spring.xml

Here we define bean definition to Point.java and add new attribute points type of List (Collection) to hold the three points.
We have defined a bean definition for each point.
When defining the collection or List attribute , we have used <list> tag and inside <list> tag we have given <ref>  tag to insert the values for the  list.
-------------------------------------------------------------------------------------------
<bean name="triangle" class="org.aop.model.Triangle">
<property name="name" value="Traingle name"></property>
<property name="points">
<list>
<ref bean="zeroPoint" />
<ref bean="pointTwo" />
<ref bean="pointThree" />
</list>
</property>
</bean>

<bean name="zeroPoint" class="org.aop.model.Point">
<property name="x" value="0"></property>
<property name="y" value="0"></property>
</bean>
<bean name="pointTwo" class="org.aop.model.Point">
<property name="x" value="20"></property>
<property name="y" value="0"></property>
</bean>
<bean name="pointThree" class="org.aop.model.Point">
<property name="x" value="0"></property>
<property name="y" value="20"></property>
</bean>

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

Output
======================================================
Triangle [name=Traingle name, points=[Point [x=0, y=0], Point [x=20, y=0], Point [x=0, y=20]]]
======================================================

Spring Basic - Understanding scope and Alias

I have been using basic coding structure in explaining most of the concepts ,including AOP.
Below is the link
http://cgenit.blogspot.com/2015/03/aop-basic-application-code-and.html


Spring has basically 6 bean scopes and except for "singleton" and "prototype" other four are valid in the context of web-aware Spring ApplicationContext.

Following table shows the details

Table 5.3. Bean scopes
ScopeDescription
singleton(Default) Scopes a single bean definition to a single object instance per Spring IoC container.
prototypeScopes a single bean definition to any number of object instances.
requestScopes a single bean definition to the lifecycle of a single HTTP request; that is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
sessionScopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
global sessionScopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext.
applicationScopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.

You can refer http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-scopes   for more details.

Here I am going to explain the behavior of the singleton and the prototype.

Singleton -basically make sure there will be only once instance , in this case one instance per container.
Prototype - gives you a new instance in each time you request or refer the bean definition.

Remember : Spring container default configuration is "singleton"

Let's check it with application. we are using "ShapeService" bean definition to understand this.
We get the bean calling same definition twice and let's compare the two object.
If the result is true , then two object are similar --> mean Singleton.

xml definition for bean

spring.xml
----------------------------------------------------------------------------------------------------


<bean name="shapeService" class="org.aop.service.ShapeService"

autowire="byName" scope="singleton" id="shapeServiceId"></bean>

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

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);
ShapeService shapeService1 = ctx.getBean("shapeService",
ShapeService.class);



shapeService.getCircle();
System.out.println("shapeService and shapeService1 equal="
+ shapeService.equals(shapeService1));

}

}

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

output
===========================================================
shapeService and shapeService1 equal=true
===========================================================

Not : two objects are similar, Singleton

We can try with omitting the "singleton" scope definition. most of the time we write omitting this.
----------------------------------------------------------------------------------------------------
<bean name="shapeService" class="org.aop.service.ShapeService"

autowire="byName"  id="shapeServiceId"></bean>

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

output will be still same
===========================================================
shapeService and shapeService1 equal=true
===========================================================

Now let's change the scope to prototype and see the result.

----------------------------------------------------------------------------------------------------
<bean name="shapeService" class="org.aop.service.ShapeService"

autowire="byName" scope="prototype" id="shapeServiceId"></bean>

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

output resulting "false"
===========================================================
shapeService and shapeService1 equal=false
===========================================================

This is beacuse , prototype returns a new object for each call.


Now let's look at that with Alias.
Alias is referring same object with a different name. When we need create more than one bean from the same bean definition we can use Alias mechanism.

There are two ways to create alias
      1. we can give the alias names in the "name" attribute with space. comma or semicolon.
I have used space for my example.
     2.  use Alias tag

below is the sample bean definitions

spring.xml
----------------------------------------------------------------------------------------------------
<bean name="shapeService shapeService1 shapeService2" class="org.aop.service.ShapeService" autowire="byName" scope="singleton" id="shapeServiceId"></bean> <alias name="shapeService" alias="shapeServiceAlias" />


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

Here i have used singleton scope. That will help us to test and tell you that all beans are refer to one. When you compare with equal all must be equal.
We retrieve each bean and compare. Below is the test code and output.

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);
ShapeService shapeService1 = ctx.getBean("shapeService1",
ShapeService.class);
ShapeService shapeService2 = ctx.getBean("shapeService2",
ShapeService.class);
ShapeService shapeService3 = ctx.getBean("shapeServiceId",
ShapeService.class);
ShapeService shapeService4 = ctx.getBean("shapeServiceAlias",
ShapeService.class);

// FactoryService factoryService = new FactoryService();
// ShapeService shapeService = (ShapeService) factoryService
// .getBean("shapeService");

shapeService.getCircle();
System.out.println("shapeService and shapeService1 equal="
+ shapeService.equals(shapeService1));
System.out.println("shapeService and shapeService2 equal="
+ shapeService.equals(shapeService2));
System.out.println("shapeService and shapeServiceId equal="
+ shapeService.equals(shapeService3));
System.out.println("shapeService and shapeServiceAlias equal="
+ shapeService.equals(shapeService4));

}

}


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

Output :: Note ::all equal as all refer to one with singleton
===========================================================
shapeService and shapeService1 equal=true
shapeService and shapeService2 equal=true
shapeService and shapeServiceId equal=true
shapeService and shapeServiceAlias equal=true
===========================================================

So you can see the output being true as all refer to one bean definition and scope is singleton. Actually to test this we need to use the singleton scope as with prototype we cannot exactly tell it refers to same bean definition.
so we can see the output , if we change the scope to prototype.

spring.xml  Note:: scope change to prototype
----------------------------------------------------------------------------------------------------
<bean name="shapeService shapeService1 shapeService2" class="org.aop.service.ShapeService" autowire="byName" scope="prototype" id="shapeServiceId"></bean> <alias name="shapeService" alias="shapeServiceAlias" />

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

Output :: after change to prototype
===========================================================
shapeService and shapeService1 equal=false
shapeService and shapeService2 equal=false
shapeService and shapeServiceId equal=false
shapeService and shapeServiceAlias equal=false
===========================================================


all will be false as each time new instance will be created with the prototype scope.

Tuesday, March 24, 2015

Spring AOP - Understanding Proxy

AOP proxy is one of few Terminolgies comes with AOP. I have used basic code structure to explain and test the concepts. It's given with

http://cgenit.blogspot.com/2015/03/aop-basic-application-code-and.html

Here we have basically given spring.xml - configuration and dependency modules with pom.xml.
Business logic explanation code contains Aspect , Advice , Pointcut

with this we are going to introduce you the new concept of  "Proxy".

In simple Proxy is defined as an "Object created by the AOP framework in order to implement the Aspect contract.( Aspect contract include advice method execution  and related details pointcut etc..)"

So Proxy can be viewed in the OOP encapsulation point of view as well.

So basic coding structure , we have two object Triangle, Circle and ShapeService to get the instance of Circle and Triangle.
To test we have "AppMain.java" where it get the bean of  "shapeService " from ApplicationContext and get the circle or Triangle instance from  "shapeService " bean.

For implementation of proxy, we change the flow and we introduce a new class "FactoryService" class and we use that to get the beans.
We implement getBean method accepting beantype as parameter in the "FactoryService.java" .
You can give the name of the bean and get the bean as you need. If no matching bean found for the requested type "NULL" oblect will be return from the FactoryService.
This is a implementation of Factory design pattern.
Below is the code.

FactoryService.java
-------------------------------------------------------------------------------------------------

package org.aop.service;

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

public class FactoryService {

public Object getBean(String beanType) {
if ("shapeService".equalsIgnoreCase(beanType)) {
return new ShapeService();
}
if ("circle".equalsIgnoreCase(beanType)) {
return new Circle();
}
if ("triangle".equalsIgnoreCase(beanType)) {
return new Triangle();
}

return null;
}

}

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


Now we have to change our main method.
We are not going to define a bean in the Context and this straight away access the Factory and get the whatever the instance/object we need.
First we create instance on factory and from factory we get the shapeService bean.

So we comment the lines where we used context as we are not going to use in AppMain.java.

--------------------------------------------------------------------------------------------------
// ApplicationContext ctx = new ClassPathXmlApplicationContext(
// "spring.xml");

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

and write new line

-----------------------------------------------------------------------------------------------
FactoryService factoryService = new FactoryService();
ShapeService shapeService = (ShapeService) factoryService
.getBean("shapeSerivce");

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

This is the same thing as previously accessing with context.

So new Test class will look like below.

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

import org.aop.service.FactoryService;
import org.aop.service.ShapeService;

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);

FactoryService factoryService = new FactoryService();
ShapeService shapeService = (ShapeService) factoryService
.getBean("shapeService");
shapeService.getCircle();
}

}

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


Now to get verified whether the getter is called we just add sysout inside the getter on ShapeService.
System.out.println("ShapeService::getCircle called.");

new circle class will be

ShapeService.java   sysout is highlighted.
-----------------------------------------------------------------------------------------------
package org.aop.service;

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

public class ShapeService {

private Circle circle;
private Triangle triangle;

@Loggable
public Circle getCircle() {
System.out.println("ShapeService::getCircle called.");
return circle;
}

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

public Triangle getTriangle() {
return triangle;
}

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

}


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


IF you run the main method the output will be as follows.

Output
=========================================================
ShapeService::getCircle called.
=========================================================


Now let's write new plain method "loggingAdvice" inside Aspect "LoginAspect"

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

public void loginAdvice() {
System.out.println("Logging from the advice.");
}
-------------------------------------------------------------------------------------------------

Now we need to execute this method whenever the shapeService "getCircle" is called.

How to do that.
We need to create a proxy object. Proxy must be type of ShapeService object.
So we create a new class extends ShapeService class.

Let's create a new class "ShapeServiceProxy.java" and extends it from ShapeService.java

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

public class ShapeServiceProxy extends ShapeService {

}

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

So Proxy is almost same object as ShapeService, as i have not included any method or override any method.
Now you can use Proxy Object instead of "shapeService" inside the factory.

FactoryService .java
-------------------------------------------------------------------------------------------------

package org.aop.service;

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

public class FactoryService {

public Object getBean(String beanType) {
if ("shapeService".equalsIgnoreCase(beanType)) {
return new ShapeServiceProxy();
}
if ("circle".equalsIgnoreCase(beanType)) {
return new Circle();
}
if ("triangle".equalsIgnoreCase(beanType)) {
return new Triangle();
}

return null;
}

}

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

So let's add a method to Proxy , override getter.
Here inside the Override method , you call super method. So nothing is changed.

So why we do that.

If you can remember the Around advice , this is like that.
This proxy object method is called before the Target "shapeService" getCircle method and you can do whatever you need.

I think now you can understand AOP with respect to OOP very well.

ShapeServiceProxy .java  new proxy with override getter.
-------------------------------------------------------------------------------------------------
package org.aop.service;

import org.aop.model.Circle;

public class ShapeServiceProxy extends ShapeService {

@Override
public Circle getCircle() {
return super.getCircle();
}
}
-------------------------------------------------------------------------------------------------


Now let's add loginAdvice method before the "getCircle" method called.
So the new method , override method inside proxy will looks like below.


ShapeServiceProxy .java  new proxy with override getter and with adding advice method.
-------------------------------------------------------------------------------------------------
package org.aop.service;

import org.aop.aspect.LoginAspect;
import org.aop.model.Circle;

public class ShapeServiceProxy extends ShapeService {

@Override
public Circle getCircle() {
new LoginAspect().loginAdvice();
return super.getCircle();
}
}

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

So every time , getCircle method called, loginAdvice method will be called Before the getCircle method.
Note : Before
If you can understand , now you can decide when to add the loginAdvice, 
eg : Bfore , After, Around, After Returning or After Throwing 

Now let;'s run the main method.

Output
=========================================================
Logging from the advice.
ShapeService::getCircle called.
=========================================================

So now you will understand how simple is that and definitely give you a idea about how AOP works inside spring background and how proxy encapsulates AOP work.

Monday, March 23, 2015

Spring Aspect Oriented Programming , AOP - writting custom Annotation

Basic Scenario
This is to describe on How to write a simple annotation.
I am writing custom annotation with name "Loggable" and I will use it with the "myArroundAdvice" which is Advice with type "Around" written in the LoginAspect.java

basic code for project is described in
http://cgenit.blogspot.com/2015/03/aop-basic-application-code-and.html

Let's write custom annotation.
If you using eclipse , you can select annotation and give name "Loggable" and it will create Loggable custom annotation.
Else simply you can create a class with name "Loggable" , and put "@interface" before name "Loggable"  as shown in below code

package I have used is same package "org.aop.aspect".  You can have your own package.

So we have defined custom annotation. Then how to use it.
So in the advice , give the path to custom annotation, in the place where you give the poincut.

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

@Around("@annotation(org.aop.aspect.Loggable)")
public Object myArroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
// advice code here
}

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

put the annotation in the place you need to do the Logging or execute advice.
Here we are going to add the Logging to "getCircle" method in the ShapeService object
So we add the annotation above the "getCircle" method as shown in below

-----------------------------------------------------------------------------------
@Loggable
public Circle getCircle() {

return circle;
}
-----------------------------------------------------------------------------------

Once you run the project . you will get below output.

Output - custom annotation
=================================================
Circle set name =Circle name
Before advice.
After Returning.
After Finally.
Circle set name =dummy name
====================================================

Final coding as below


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

public @interface Loggable {


}

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

Below is the new Advice. You may have some unused imports, that's cause i have ommited some codes to ease of explanation. Don't worry about that. Just remove those.

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

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

import org.aspectj.lang.annotation.Pointcut;

@Aspect

public class LoginAspect {
@Around("@annotation(org.aop.aspect.Loggable)")
public Object myArroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
Object returnValue = null;
try {
System.out.println("Before advice.");
returnValue = proceedingJoinPoint.proceed();
System.out.println("After Returning.");
} catch (Throwable e) {
System.out.println("After Throwing.");
}

System.out.println("After Finally.");
return returnValue;

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

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

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

public class ShapeService {

private Circle circle;
private Triangle triangle;

@Loggable
public Circle getCircle() {
// circle = null;
// circle.getName();
return circle;
}

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

public Triangle getTriangle() {
return triangle;
}

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

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

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);


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

}


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


You can check the exception also.
To get a exception and check what;s happen when an exception , just remove commented two lines in the "getCircle" method in the ShaepService.java
This will make null pointer exception

------------------------------------------------------------------------------------
@Loggable
public Circle getCircle() {
circle = null;
circle.getName();
return circle;
}
------------------------------------------------------------------------------------


Output - custom annotation with Nullpointer exception
=================================================
Circle set name =Circle name
Before advice.
After Throwing.
After Finally.
Exception in thread "main" java.lang.NullPointerException
at org.aop.main.AppMain.main(AppMain.java:18)
====================================================

You can see that in output Line number 3 , it's printing  After Throwing. .

If you need to see the what's happening with the ProceedingJoinPoint , you can print that just using sysout.

so if you add a sysout to advice . It's highlighted in the below code inside advice.

LoginAspect .java
------------------------------------------------------------------------------------

package org.aop.aspect;

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

@Aspect
public class LoginAspect {


@Around("@annotation(org.aop.aspect.Loggable)")
public Object myArroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
Object returnValue = null;
try {
System.out.println("Before advice.");
System.out.println(proceedingJoinPoint);
returnValue = proceedingJoinPoint.proceed();
System.out.println("After Returning.");
} catch (Throwable e) {
System.out.println("After Throwing.");
}

System.out.println("After Finally.");
return returnValue;
}


}

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


So the new output will be

Output - custom annotation with Nullpointer exception and with sysout proceedingJoinPoint
=================================================
Circle set name =Circle name
Before advice.
execution(Circle org.aop.service.ShapeService.getCircle())
After Throwing.
After Finally.
Exception in thread "main" java.lang.NullPointerException
at org.aop.main.AppMain.main(AppMain.java:18)

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

you can see it's printing the joinpoint of the execution, where we have applied our custom annotation.
I have highlighted in  the output.
execution(Circle org.aop.service.ShapeService.getCircle())

Also you can see what happens if you remove the "proceedingJoinPoint.proceed();" from the advice. So let's comment that line and see what will happen.

So new Advice will look like below

LoginAspect .java  Note: proceedingJoinPoint.proceed();  is commented.
-----------------------------------------------------------------------------------------------
package org.aop.aspect;

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

@Aspect
public class LoginAspect {


@Around("@annotation(org.aop.aspect.Loggable)")
public Object myArroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
Object returnValue = null;
try {
System.out.println("Before advice.");
// System.out.println(proceedingJoinPoint);
// returnValue = proceedingJoinPoint.proceed();
System.out.println("After Returning.");
} catch (Throwable e) {
System.out.println("After Throwing.");
}

System.out.println("After Finally.");
return returnValue;
}



}


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

Output - commenting "proceedingJoinPoint.proceed();"
=================================================
Circle set name =Circle name
Before advice.
After Returning.
After Finally.
Exception in thread "main" java.lang.NullPointerException
at org.aop.main.AppMain.main(AppMain.java:18)

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

Note : you are getting a NullPointerException.


Friday, March 20, 2015

AOP basic application code and configuration

I have made a simple maven project to test and describe AOP concepts.
POM files and spring.xml configuration files and Two Objects Circle.java and Trinagle.javab with the service class ShapeService.java. Aspect is done inside LoginAspect.java and Application test main method coded with the AppMain.java

Those configuration and base class files are shown below.
Each scenario i will be using thise main basic application and alter the code to test specific Aspect concepts.
In each i will be point out changes i do with respect to the base code.

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());
 }

}

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