0% found this document useful (0 votes)
15 views

Workshop 6

Uploaded by

Surendra
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views

Workshop 6

Uploaded by

Surendra
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 34

Aspect Oriented Programming (AOP)

Spring framework is developed on two core concept namely Dependency Injection and
Aspect Oriented Programming. AOP is a way of extending existing classes without
touching your existing code base which can be very useful under some circumstances.

AOP is just an interceptor to intercept some processes, for example, when a method is
execute, Spring AOP can hijack the executing method, and add extra functionality
before or after the method execution.

AOP provides the way to dynamically add the cross-cutting concern before, after or
around the actual logic using simple pluggable configurations. AOP is a tool for
implementing crosscutting concerns. AOP is most commonly used for applying
common concerns to many parts of an application in a large scale. Logging and security
are examples of cross cutting concerns.

Core Concept

Following terminologies are most commonly used while developing a program that uses
AOP.

1. Aspect: An aspect is a class where we specify method that needs to be called


automatically whenever a particular method is called. Classes can be advised with
Aspects, that means that they are somehow enhanced with functionality
programmed in the aspects. By the way, Aspects are classes themselves.
2. Join Point: A join point is the specific point in the application such as method
execution i.e. method where we implement business logic. Join Point is anywhere in
your code where you could get an aspect to run some advice to execute a code
advised by some code in aspect. In spring the popular joint point that we use is
method exeuction joint point. Join point defines point in application at which we can
insert additional logic using AOP.
3. Advice: Advices are actions taken for a particular join point. In terms of
programming, they are methods that gets executed when a certain join point with
matching pointcut is reached in the application. It means, method that gets
automatically executed whenever a joint point method is executed. We implement
advice methods inside Aspect class. Advice methods job is to advice pointcut
methods to run. The code that is executed at a particular joinpoint is the advice.
Advice is implemented in the form of methods in a class.
4. Pointcut: Pointcut are expressions that is matched with join points to determine
whether advice needs to be executed or not. Pointcut uses different kinds of
expressions that are matched with the join points and Spring framework uses the
AspectJ pointcut expression language. Pointcut specifies joint point methods. The
particular join point we choose is defined by pointcut. Hence, point cut defines join
point where we are going to run our code. Hence, point cut defines join point where
we are going to run our code.
5. Target Object: They are the object on which advices are applied. Spring AOP is
implemented using runtime proxies so this object is always a proxied object. What is
means is that a subclass is created at runtime where the target method is overridden
and advices are included based on their configuration.
6. AOP proxy: Spring AOP implementation uses JDK dynamic proxy to create the
Proxy classes with target classes and advice invocations, these are called AOP
proxy classes. We can also use CGLIB proxy by adding it as the dependency in the
Spring AOP project.

AOP Advice Types

Based on the execution strategy of advices, they are of following types.

1. Before Advice: These advices runs before the execution of join point methods. We
can use @Beforeannotation to mark an advice type as Before advice.
2. After (finally) Advice: An advice that gets executed after the join point method
finishes executing, whether normally or by throwing an exception. We can create
after advice using @After annotation.
3. After Returning Advice: Sometimes we want advice methods to execute only if the
join point method executes normally. We can use @AfterReturning annotation to
mark a method as after returning advice.
4. After Throwing Advice: This advice gets executed only when join point method
throws exception, we can use it to rollback the transaction declaratively. We
use @AfterThrowing annotation for this type of advice.
5. Around Advice: This is the most important and powerful advice. This advice
surrounds the join point method and we can also choose whether to execute the join
point method or not. We can write advice code that gets executed before and after
the execution of the join point method. It is the responsibility of around advice to
invoke the join point method and return values if the method is returning something.
We use @Around annotation to create around advice methods.

Within <aop:config> We define following two things

1. Pointcut which specifies joint point i.e. method where we implement business
logic
<aop:pointcut id="camerasnap" expression="execution(*
ch6.demo.aop.Camera.snap(..))" />
2. Aspect which implements advice method. In this, you specify reference to Aspect
class as well as pointcut reference.

<aop:aspect id="loggeraspect" ref="logger" >


<aop:before method="aboutToTakePhoto" pointcut-
ref="camerasnap" />
</aop:aspect>
Note:
<bean id="logger" class="ch6.demo.aop.Logger"></bean>

XML Based Configuration

Let us develop a sample application program that uses AOP concept based on
configurations stored on XML file.

1. Create a Dynamic Web Project named AOPDemo


2. Include following jar files in Build Path and Deployment Assembly
aspectjrt-1.8.9.jar aspectjweaver-1.8.9.jar aopalliance-1.0.0.jar commons-logging-1.2.jar
spring-aop-4.2.2.RELEASE.jar spring-aspects-4.2.2.RELEASE.jar spring-beans-4.2.2.RELEASE.jar spring-context-4.2.2.RELEASE.jar
spring-core-4.2.2.RELEASE.jar spring-expression- spring-web-4.2.2.RELEASE.jar spring-webmvc-4.2.2.RELEASE.jar
4.2.2.RELEASE.jar

3. Create two packages namely ch6.demo.aop and ch6.demo.controller inside src


folder.
4. Inside ch6.demo.aop create two classes namely Camera.java and Logger.java
5. Put following codes inside Camera.java[ This class implements pointcut methods
i.e. where we implement business logic]
package ch6.demo.aop;
public class Camera {
public void snap() {
System.out.println("SNAP!");
}
public String sayHello(String name) {
return "Hello "+name;
}
public void validate(int age)throws Exception{
if(age<18){
throw new ArithmeticException("Not valid age");
}
else{
System.out.println("Thanks for vote");
}
}
}
6. Put following codes inside Logger.java [ This class is called Aspect class where
we implement advice method]
package ch6.demo.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class Logger {


public void aboutToTakePhoto() {
System.out.println("About to take photo...");
}
public void log(JoinPoint jp,String returnVal) throws Throwable
{
System.out.println("Return value:"+returnVal);
System.out.println("XML Configuration driven: After returning
"+jp.getSignature().getName()+"()");
}
public Object myadvice(ProceedingJoinPoint pjp) throws Throwable
{
System.out.println("Additional Concern Before calling actual
method");
Object obj=pjp.proceed();
System.out.println("Additional Concern After calling actual
method");
return obj;
}
public void myadvice1(JoinPoint jp,Throwable error)//it is advice
{
System.out.println("additional concern");
System.out.println("Method Signature: " + jp.getSignature());
System.out.println("Exception is: "+error);
System.out.println("end of after throwing advice...");
}
}
7. Create a file named MyController.java inside ch6.demo.controller package and
put following codes inside it.
package ch6.demo.controller;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import ch6.demo.aop.Camera;
@Controller
public class MyController {
@RequestMapping(value="/",method=RequestMethod.GET)
public String displayMainPage()
{
ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext("ch6/demo/controller/appConfig.xml");
Camera camera = (Camera)context.getBean("camera");
/*String result=camera.sayHello("Mukesh");
System.out.println("Return Value="+result);
camera.snap();*/
////////////////////////
try{
camera.validate(19);
}catch(Exception e){System.out.println(e);}
System.out.println("calling validate again...");

try{
camera.validate(11);
}catch(Exception e){System.out.println(e);}
context.close();
return "main";
}
}
8. Create a file named appConfig.xml inside ch6.demo.controller package and put
following codes inside it.
<?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/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<aop:aspectj-autoproxy />
<bean id="camera" class="ch6.demo.aop.Camera"></bean>
<bean id="logger" class="ch6.demo.aop.Logger"></bean>

<aop:config>
<aop:pointcut id="pointCutAfterThrowing"
expression="execution(* ch6.demo.aop.Camera.validate(..))" />
<aop:pointcut id="camerasnap" expression="execution(*
ch6.demo.aop.Camera.snap(..))" />
<aop:pointcut id="logPointCut" expression="execution(public *
ch6.demo.aop.Camera.sayHello(..))" />
<aop:aspect id="loggeraspect" ref="logger" >

<aop:after-throwing method="myadvice1" throwing="error"


pointcut-ref="pointCutAfterThrowing" />
<aop:before method="aboutToTakePhoto" pointcut-
ref="camerasnap" />
<aop:after method="aboutToTakePhoto" pointcut-
ref="camerasnap" />
<aop:around method="myadvice" pointcut-ref="camerasnap" />

<aop:after-returning method="log" returning="returnVal" pointcut-


ref="logPointCut" />

</aop:aspect>

</aop:config>
</beans>

9. Inside WEB-INF folder, create two XML files namely aopdispachet-servlet.xml


and web.xml:
10. Put following codes inside aopdispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">

<context:component-scan base-package="ch6.demo" />

<mvc:annotation-driven />

<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>

</beans>

11. Put following codes inside web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID"
version="2.5">
<display-name>AOPDemo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>

<servlet>
<description></description>
<display-name>aopdispatcher</display-name>
<servlet-name>aopdispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-
class>
</servlet>
<servlet-mapping>
<servlet-name>aopdispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

12. Create main.jsp inside WebContent folder and put following codes

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"


pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>AOP Test Demo Main Page</h1>
</body>
</html>

Analysis:

1. aboutToTakePhoto( ) method implemented inside Logger class[Aspect class] is


called just before and after snap( ) method is called
2. myadvice( ) method implemented inside Logger class[Aspect class] is called just
before and after snap() method is called.
3. log()method implemented inside Logger class[Aspect class] is called after
sayHello() method returns some value.
4. myadvice1( ) method implemented inside Logger class[Aspect class] is called if
validate( ) method throws an Exception
Annotation Based Configuration

Let us develop a sample application program that uses AOP concept based on
annotation.The sample application is similar to the XML based application discussed
above.

1. Create a Dynamic Web Project named AOPAnnotation


2. Include following jar files in Build Path and Deployment Assembly
aspectjrt-1.8.9.jar aspectjweaver-1.8.9.jar aopalliance-1.0.0.jar commons-logging-1.2.jar
spring-aop-4.2.2.RELEASE.jar spring-aspects-4.2.2.RELEASE.jar spring-beans-4.2.2.RELEASE.jar spring-context-4.2.2.RELEASE.jar
spring-core-4.2.2.RELEASE.jar spring-expression- spring-web-4.2.2.RELEASE.jar spring-webmvc-4.2.2.RELEASE.jar
4.2.2.RELEASE.jar

3. Create two packages namely ch6.demo.aop and ch6.demo.controller inside src


folder.
4. Inside ch6.demo.aop create two classes namely Camera.java and Logger.java
5. Put following codes inside Camera.java[ This class implements pointcut methods
i.e. where we implement business logic]
package ch6.demo.aop;
public class Camera {
public void snap() {
System.out.println("SNAP!");
}
public String sayHello(String name) {
return "Hello "+name;
}
public void validate(int age)throws Exception{
if(age<18){
throw new ArithmeticException("Not valid age");
}
else{
System.out.println("Thanks for vote");
}
}
}

6. Put following codes inside Logger.java [ This class is called Aspect class where
we implement advice method]
.
package ch6.demo.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class Logger {

@Pointcut("execution(* ch6.demo.aop.Camera.snap(..))")
public void cameraSnap() {
}
/*@Before("cameraSnap()")
public void aboutToTakePhoto() {
System.out.println("About to take photo...");
}
@After("cameraSnap()")
public void afterPhoto()
{
System.out.println("After Pointcut Demo");
}*/
@AfterThrowing( pointcut = "execution(*
ch6.demo.aop.Camera.validate(..))",throwing= "error")
public void myadvice1(JoinPoint jp,Throwable error)//it is advice
{
System.out.println("additional concern");
System.out.println("Method Signature: " + jp.getSignature());
System.out.println("Exception is: "+error);
System.out.println("end of after throwing advice...");
}
@AfterReturning(pointcut = "execution(public *
ch6.demo.aop.Camera.sayHello(..))", returning= "returnVal")
public void log(JoinPoint jp,String returnVal) throws Throwable
{
System.out.println("Return value:"+returnVal);
System.out.println("XML Configuration driven: After returning
"+jp.getSignature().getName()+"()");
}
@Around("cameraSnap()")
public Object myadvice(ProceedingJoinPoint pjp) throws Throwable
{
System.out.println("Additional Concern Before calling actual
method");
Object obj=pjp.proceed();
System.out.println("Additional Concern After calling actual method");
return obj;
}

}
7. Create a file named MyController.java inside ch6.demo.controller package and
put following codes inside it.
package ch6.demo.controller;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import ch6.demo.aop.Camera;
@Controller
public class MyController {
@RequestMapping(value="/",method=RequestMethod.GET)
public String displayMainPage()
{
ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext("ch6/demo/controller/appConfig.xml");
Camera camera = (Camera)context.getBean("camera");
/*String result=camera.sayHello("Mukesh");
System.out.println("Return Value="+result);
camera.snap();*/
////////////////////////
try{
camera.validate(19);
}catch(Exception e){System.out.println(e);}
System.out.println("calling validate again...");

try{
camera.validate(11);
}catch(Exception e){System.out.println(e);}
context.close();
return "main";
}
}
8. Create a file named appConfig.xml inside ch6.demo.controller package and put
following codes inside it.

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:annotation-config></context:annotation-config>
<context:component-scan base-package="ch6.demo" />
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

9. Inside WEB-INF folder, create two XML files namely aopdispachet-servlet.xml


and web.xml:
10. Put following codes inside aopdispatcher-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<context:component-scan base-package="ch6.demo" />
<mvc:annotation-driven />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>

</beans>

11. Put following codes inside web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>AOPAnnotation</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>aopdispatcher</display-name>
<servlet-name>aopdispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>aopdispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

12. Create main.jsp inside WebContent folder and put following codes

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"


pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>AOP AnnotationTest Demo Main Page</h1>
</body>
</html>

Analysis:

1. We removed pointcut declaration from aopConfig.xml file to Aspect class Logger


as shown above.
2. aboutToTakePhoto( ) method implemented inside Logger class[Aspect class] is
called just before and after snap( ) method is called
3. myadvice( ) method implemented inside Logger class[Aspect class] is called just
before and after snap() method is called.
4. log()method implemented inside Logger class[Aspect class] is called after
sayHello() method returns some value.
5. myadvice1( ) method implemented inside Logger class[Aspect class] is called if
validate( ) method throws an Exception

Integrating with IOC Container


Spring IOC container is responsible for creating objects, wiring them together, configure
objects and manage their complete life cycle from creation till destruction. Spring IOC
container uses DI while creating beans. The container gets its instructions on what
objects to instantiate, configure, and assemble by reading configuration metadata
provided. The configuration metadata can be represented either by XML, Java
annotations, or Java code.

Spring AOP:It is related to cross cutting concern.What it mean is in large system the
common functionality is scattered throughout different modules.so,aop provides a
easiest way to take out a common implementaiton in the form of aspect.The very base
principle of AOP is finding common tasks/aspects which returns in many places in the
code and dont belong to the concerete business of the code. For example write to log
on every entrance to any function, or when an object is created wrapp it, or send email
to admin when calling to specific function. So instead of the programmers will handle
these non businuss aspect we take it from them and we manage these aspects behond
the scene.

Objective of IOC is to reduce explicit dependencies between components, while


purpose of AOP is is to wire components together possibly by enforcing certain
common behavior.

Spring AOP can be integrated with IOC container to achieve followings:

1. Any Object created by the IOC Container can easily be advised.


Example:
"camera" object created above by Logger Aspect
2. All AOP framework objects, such as pointcuts and advices, can be configured
using Spring IoC
<bean id="camera" class="ch6.demo.aop.Camera"></bean>
<bean id="logger" class="ch6.demo.aop.Logger"></bean>

<aop:config>
<aop:pointcut id="pointCutAfterThrowing"
expression="execution(* ch6.demo.aop.Camera.validate(..))" />
<aop:pointcut id="camerasnap" expression="execution(*
ch6.demo.aop.Camera.snap(..))" />
<aop:pointcut id="logPointCut" expression="execution(public *
ch6.demo.aop.Camera.sayHello(..))" />
<aop:aspect id="loggeraspect" ref="logger" >

<aop:after-throwing method="myadvice1" throwing="error"


pointcut-ref="pointCutAfterThrowing" />
<aop:before method="aboutToTakePhoto" pointcut-
ref="camerasnap" />
<aop:after method="aboutToTakePhoto" pointcut-
ref="camerasnap" />
<aop:around method="myadvice" pointcut-ref="camerasnap" />

<aop:after-returning method="log" returning="returnVal" pointcut-


ref="logPointCut" />

</aop:aspect>

</aop:config>

Reference:

1. http://stackoverflow.com/questions/2572158/what-is-aop-dependency-injection-
and-inversion-of-control-in-simple-english
2. http://www.tutorialspoint.com/spring/spring_ioc_containers.htm

Spring AOP and Proxy


It is also possible programmatically to create proxies that advise target objects. Proxy is
an object that wraps target object and advice object. To enable AspectJ annotation
support in the Spring IoC container, you only have to define an empty XML element
aop:aspectj-autoproxy in your bean configuration file. Then, Spring will automatically
create proxies for any of your beans that are matched by your AspectJ aspects.

Proxy Types

1. JDK Dynamic Proxy


2. CGLIB Proxy

According to Spring documentation, in case your target implements at least one


interface, a JDK dynamic proxy will be used. However if your target object does not
implement any interfaces then a CGLIB proxy will be created.

This is how you can force creation of the CGLIB proxies (set proxy-target-class="true"):
<aop:config proxy-target-class="true">
<!-- other beans defined here... -->
</aop:config>
When using AspectJ and its autopoxy support you can also force CGLIB proxies. This is
where the <aop:aspectj-autoproxy> is used and also here the "proxy-target-class" must
be set to true:
<aop:aspectj-autoproxy proxy-target-class="true"/>

JDK proxies work by implementing the same interface as your target object and
delegating calls to it; they do not work if there is no interface to implement. In case you
don't have an interface like above, Spring needs to use a byte code library like CGLIB to
dynamically create classes at runtime that incorporate the aspect functionality.

Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxy for a given
target object. (JDK dynamic proxies are preferred whenever you have a choice).
If the target object to be proxied implements at least one interface then a JDK dynamic
proxy will be used. All of the interfaces implemented by the target type will be proxied.
If the target object does not implement any interfaces then a CGLIB proxy will be used.
To enable CGLIB proxy, you have to declare following in your XML file:
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

Programmatic Proxy Creation


It is possible to create AOP proxies programmatically using ProxyFactory class. We
need to set target or TargetSource, add any advisors or advice we choose and then call
getProxy( ) method to obtain AOP proxy.

Let us develop a sample application where we create proxy manually. For this, follow
the below steps:

1. Create a project named ProxyDemo1 and add following jar files into the project in
Java Build Path.

aopalliance-1.0.jar aspectjweaver-1.7.2.jar commons-logging-1.1.1.jar spring-aop-


4.2.2.RELEASE.jar

spring-aspects- spring-beans- spring-context- spring-context-support-


4.2.2.RELEASE.jar 4.2.2.RELEASE.jar 4.2.2.RELEASE.jar 4.2.2.RELEASE.jar

spring-core- spring-expression-
4.2.2.RELEASE.jar 4.2.2.RELEASE.jar

2. Create a package named ch6.demo.aop inside src folder and create following
various class files inside it.
3. PhotoSnapper.java which is an interface going to be inherited by target class
(Camera)

package ch6.demo.aop;

public interface PhotoSnapper {


public void snap() throws Exception;

4. Machine.java which is yet another interface going to be inherited by target class


(Camera)
package ch6.demo.aop;

public interface Machine {

public void machineMethod();


}

5. Camera.java which is a target class


package ch6.demo.aop;

import org.springframework.stereotype.Component;

@Component("camera")
public class Camera implements PhotoSnapper,Machine{

public Camera() {

System.out.println("Constructor Code");
// TODO Auto-generated constructor stub
}

public void snap() throws Exception {


System.out.println("SNAP!");

//throw new Exception("bye bye!");


}

@Override
public void machineMethod() {
// TODO Auto-generated method stub

}
}
6. Logger.java an aspect class which comprises of advise methods

package ch6.demo.aop;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.AfterReturning;

import org.aspectj.lang.annotation.AfterThrowing;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.aspectj.lang.annotation.Pointcut;

import org.springframework.stereotype.Component;

@Aspect

@Component

public class Logger {

@Pointcut("execution(* ch6.demo.aop.Camera.snap())")

public void cameraSnap() {

@Before("cameraSnap()")

public void beforeAdvice() {


System.out.println("Before advice ...");

7. MessageDecorator.java which is another way of implementing advise methods

package ch6.demo.aop;

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

public class MessageDecorator implements MethodInterceptor {

@Override

public Object invoke(MethodInvocation invocation) throws


Throwable {

// TODO Auto-generated method stub

System.out.println("Hello ");

Object retVal=invocation.proceed();

System.out.print("!");

return retVal;

}
8. MyPointCut.java which comprises of creating pointcuts programmatically.

package ch6.demo.aop;
import java.lang.reflect.Method;
import org.springframework.aop.support.StaticMethodMatcherPointcut;

public class MyPointCut extends StaticMethodMatcherPointcut {

public boolean matches(Method method, Class<?> clazz) {

String targetMethod = "snap";

boolean intercept = false;

if (targetMethod.equals(method.getName())) {

intercept = true;

return intercept;

9. beans.xml which comprises of codes for making proxy object as a target object
programmatically.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">

<context:annotation-config></context:annotation-config>
<context:component-scan
base-package="ch6.demo.aop">
</context:component-scan>

<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-
autoproxy>
</beans>

10. TestApp.java which comprises of code to test various things like, programmatic
proxy creation, determining proxy types and so on.

package ch6.demo.aop;

import org.springframework.aop.Advisor;

import org.springframework.aop.Pointcut;

import org.springframework.aop.framework.ProxyFactory;

import org.springframework.aop.support.AopUtils;

import org.springframework.aop.support.DefaultPointcutAdvisor;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestApp {

public static void main(String[] args) {

ClassPathXmlApplicationContext context = new


ClassPathXmlApplicationContext("ch6/demo/aop/beans.xml");

Object obj = context.getBean("camera");


System.out.println("Class of camera bean: " + obj.getClass());

System.out.println(obj instanceof Camera);

System.out.println(obj instanceof PhotoSnapper);

System.out.println(obj instanceof Machine);

System.out.println("CGlib Proxy="+AopUtils.isCglibProxy(obj));

System.out.println("Dynamic
Proxy="+AopUtils.isJdkDynamicProxy(obj));

Object obj1 = context.getBean("camera");

ProxyFactory factory = new ProxyFactory();

Pointcut pc = new MyPointCut();

Advisor advisor = new DefaultPointcutAdvisor(pc, new


MessageDecorator());//pointcut and advice

factory.addAdvisor(advisor);

factory.setTarget(obj1);

factory.addInterface(PhotoSnapper.class);

//factory.addAdvice(new MessageDecorator());

factory.setExposeProxy(true);

PhotoSnapper obj2=(PhotoSnapper)factory.getProxy();

Camera camera = (Camera)context.getBean("camera");

try

camera.snap();

obj2.snap();
}

catch(Exception e)

System.out.println("Execption occuered="+e);

e.printStackTrace();

Analysis:

Your code never invokes the advice methods of an aspect class. Spring does it for you
based on your XML configuration or annotations on the aspect class. How does the
magic happen? Under the covers, Spring implements a proxy to intercept calls to a
target object.For cases in which interfaces are not available or not used in an
application’s design, it’s possible to create proxies by relying on CGLIB. To enable
CGLIB, you need to set the attribute proxy-targetclass= true in aop:aspectj-autoproxy.

Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxies for your
target objects.

If a target class( Camera class) implements an interface(PhotoSnapper), then the


following bean is no longer an instance of target class, rather the bean is an instance of
any of the interface that the target class implements.

Camera camera = (Camera)context.getBean("camera");

One solution to above problem is that We can change the way the proxy system works
by changing the proxy to be an instance of target class. In order to do this, we should
have following tag on our container xml file. This is for annotation based approach.

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

For XML based AOP, the solution is:

<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
proxy-target-class="true" will tell the system that the proxy object is an instance of target
class. If we do this, then proxy object along with target object (two objects) will be
created. Hence, if you have any constructor in target class, then due to proxy object
creation the constructor will be called first. As proxy class is child class of target class,
while calling constructor while creating proxy object, it will automatically call target class
constructor. It means, constructor will be called twice. To eliminate this problem, you
have to put all methods that the target class has in an interface and implement that
interface in a target class and will getting bean object, then cast it to this interface
object.

If you have the following code,


Object obj = context.getBean("camera");
System.out.println("Class of camera bean: " + obj.getClass());
System.out.println(obj instanceof Camera);
System.out.println(obj instanceof PhotoSnapper);
System.out.println("CGlib Proxy="+AopUtils.isCglibProxy(obj));
System.out.println("Dynamic Proxy="+AopUtils.isJdkDynamicProxy(obj));

It will produce following output:


Class of camera bean: class ch6.demo.aop.Camera$$EnhancerBySpringCGLIB$$89cdb8d2
true
false
CGlib Proxy=true
Dynamic Proxy=false

Reason is obj is sub class of Camera class and as Camera does not implement any
interface, proxy used is CGLIB not dynamic proxy.

However, if Camera class implements an interface lets us say PhotoSnapper, then you
will get following output:

Class of camera bean: class com.sun.proxy.$Proxy8


false
true
CGlib Proxy=false
Dynamic Proxy=true

Obj is no longer an instance of Camera rather an instance of PhotoSnapper interface.


Since, Camera class implements an interface, the proxy used is JDKDynamicProxy not
the CGLIB proxy.

If Camera class implements another interface let us say Machine, then you still will get
above output.
Note: Interfaces should not be empty

Hence, obj bean is not an instance of target class(Camera) rather it is an instance of all
interfaces that the target class implements.

If you include following code in above application

Camera camera = (Camera)context.getBean("camera");

try

{ camera.snap();

catch(Exception e)

{ System.out.println("Execption occuered="+e);

e.printStackTrace();

Then, you will notice following error.

Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy8


cannot be cast to ch6.demo.aop.Camera

You will get above exception because bean retrieved is proxy and you are trying to
convert it into Camera

The solution to above problem is: We have to change the way how proxy works by
making sure that proxy be an instance of target class rather than an instance of
interfaces.

If you remove following code from beans.xml

<aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>

, then aop feature will not work and you will not get above error output, you will get
following output:

Class of camera bean: class ch6.demo.aop.Camera


true
true
true
CGlib Proxy=false
Dynamic Proxy=false
SNAP!
If proxy-target-class="ftrue">, then it implies that proxy object i.e. obj object and camera
object is going to be an instance of target class. So, if you keep following code,

<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

Then, you will not receive any error.

Class of camera bean: class ch6.demo.aop.Camera$$EnhancerBySpringCGLIB$$60f9ee44


true
true
true
CGlib Proxy=true
Dynamic Proxy=false
Before advice ...
SNAP

Now, the bean object is not an instance of proxy rather an instance of subclass of
Camera

Examining and Manipulating Proxy State at Runtime


Spring allows us to examine and even change the advice applying to any AOP proxy at
runtime.

Example:

 isAopProxy(Object o) method of AopUtils class to find whether an object is an


AOP proxy
 isJdkDynamicProxy( ) method of AopUtils class to find whether object is JDK
proxy.
 is CglibProxy( ) method of AopUtils class to find whether object is CGLIB proxy
 Any AOP proxy can be cast to Advised interface, which enables advice to be
examined and changed. Some of the methods are as follows:

public interface Advised {

TargetSource getTargetSource();

void setTargetSource(TargetSource targetSource);

boolean getExposeProxy();

boolean getProxyTargetClass();

Advisor[] getAdvisors();
Class[] getProxiedInterfaces();

boolean isInterfaceProxied(Class intf);

void addAdvice(Advice advice) throws AopConfigException;

void addAdvice(int pos, Advice advice) throws AopConfigException;

void addAdvisor(Advisor advisor) throws AopConfigException;

void addAdvisor(int pos, Advisor advisor) throws AopConfigException;

boolean removeAdvisor(Advisor advisor) throws AopConfigException;

void removeAdvisor(int index) throws AopConfigException;

boolean removeAdvice(Advice advice) throws AopConfigException;

boolean isFrozen();

// Other methods omitted: finding and replacing advices and advisors

Reference

1. http://docs.spring.io/spring/docs/2.5.x/reference/aop.html#aop-proxying
2. http://codeomitted.com/around-advice-example-with-proxyfactory/
3. http://www.java2s.com/Code/Java/Spring/ProxyFactoryAddAdvisor.htm
4. http://www.java2s.com/Code/Java/Spring/ProxyFactoryAddAdvisor.htm
5. http://www.intertech.com/Blog/secrets-of-the-spring-aop-proxy/

TargetSource
A TargetSource is used to obtain the current "target" of an AOP invocation.Spring offers
the concept of a TargetSource, expressed in
the org.springframework.aop.TargetSource interface. This interface is responsible for
returning the "target object" implementing the join point. Target source must return
target instance each tie AOP proxy handles method invocation. a pooling TargetSource
can return a different target instance for each invocation, using a pool to manage
instances.

If you do not specify a TargetSource, a default implementation is used that wraps a


local object. The same target is returned for each invocation. When target object is
known in advance, Spring creates an implementation of TargetSource interface without
developer needing to be aware of it. Such kind of default TargetSource is called
SingletonTargetSource.

SingletonTargetSource will return the same instances in all cases when the getTarget()
method is called. However, TargetSource interface allows us to get Target object from
pool or factory.

Example:
PhotoSnapper obj2=(PhotoSnapper)factory.getProxy();
Advised advised=(Advised)obj2;
try{System.out.println(advised.getTargetSource().getTarget().getClass());
System.out.println("Singleton Check="+(advised.getTargetSource() instanceof
SingletonTargetSource));
}catch(Exception e){}

Above program will produce following output


Singleton Check=true

HotSwappableTargetSource
This enables us to swap the target object under proxy in a thread safe manner.

In above ProxyDemo1 project, create a package named ch6.demo.targetsource inside


src folder and create following classes under it.

1. MyInterface.java where you define method


package ch6.demo.targetsource;

public interface MyInterface {


public void snap();
}

2. MyInterfaceImpl.java where you define your business methods


package ch6.demo.targetsource;

public class MyInterfaceImpl implements MyInterface{

@Override
public void snap() {
System.out.println("I am Inside MyInterfaceImpl");

}
3. MyInterfaceImpl2.java where you define you business methods [ We are going to
swap MyInterfaceImpl object with MyInterfaceImpl2 object ]
package ch6.demo.targetsource;

public class MyInterfaceImpl2 implements MyInterface {

@Override
public void snap() {
System.out.println("I am inside MyInterfaceImpl2");

}
}

4. beans.xml where you create beans and many more


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

<context:annotation-config></context:annotation-config>
<context:component-scan
base-package="ch6.demo.targetsource">
</context:component-scan>

<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-
autoproxy>
<bean id="target1" class="ch6.demo.targetsource.MyInterfaceImpl">
</bean>
<bean id="target2"
class="ch6.demo.targetsource.MyInterfaceImpl2">
</bean>
<bean id="swapper"
class="org.springframework.aop.target.HotSwappableTargetSource">
<constructor-arg ref ="target1"/>
</bean>
<bean id="swappable"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource" ref ="swapper" />
</bean>
</beans>
5. Logger.java where you define advices
package ch6.demo.targetsource;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class Logger {

@Pointcut("execution(* ch6.demo.targetsource.MyInterfaceImpl.snap()) ||
execution(* ch6.demo.targetsource.MyInterfaceImpl2.snap())")

public void cameraSnap() {


}

@Before("cameraSnap()")
public void beforeAdvice() {
System.out.println("Before advice ...");
}

}
6. TestApp.java contains application logic to test your application.
package ch6.demo.targetsource;

import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.target.HotSwappableTargetSource;
import
org.springframework.context.support.ClassPathXmlApplicationContext;

import ch6.demo.aop.MessageDecorator;
import ch6.demo.aop.MyPointCut;

public class TestApp {

public static void main(String[] args) {


ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext("ch6/demo/targetsource/beans.xml");
MyInterface target1 = (MyInterface)
context.getBean("target1");
MyInterface target2 = (MyInterface)
context.getBean("target2");
MyInterface proxied = (MyInterface)
context.getBean("swappable");
HotSwappableTargetSource swapper =
(HotSwappableTargetSource) context.getBean("swapper");
System.out.println("Before Swap");
proxied.snap();
System.out.println("After Swap");
Object obj=swapper.swap(target2);
proxied.snap();

}
Pooling Target Sources:

TargetSource supports pooling. This is used if pool of targets instead of single


target is required such that target is freed at the end of interceptor chain. To
develop sample application that uses pooling concept, you must have to add
commons-pool-1.6.jar in Java Build path and follow below steps:
1. Add following codes in beans.xml
<bean id="target3" name="target3"
class="ch6.demo.targetsource.MyInterfaceImpl" scope="prototype" />
<bean id="poolTargetSource"
class="org.springframework.aop.target.CommonsPoolTargetSource">
<property name="targetBeanName" value="target3"/>
<property name="maxSize" value="14"/>
</bean>
<bean id="poolConfigAdvisor"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBea
n">
<property name="targetObject" ref="poolTargetSource"/>
<property name="targetMethod" value="getPoolingConfigMixin"/>
</bean>
<bean id="myBean"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource" ref="prototypeTargetSource"/>
<property name="proxyTargetClass"><value>true</value></property>
<property
name="interceptorNames"><value>poolConfigAdvisor</value></property>
</bean>
2. Add following codes in TestApp.java
PoolingConfig conf = (PoolingConfig) context.getBean("myBean");
System.out.println("Max pool size is " + conf.getMaxSize());
MyInterface myBean = (MyInterface) context.getBean("myBean");
myBean.snap();

PrototypeTargetSource:

To develop sample application that uses PrototypeTargetSource, you have to


follow below steps:
1. Put following codes in beans.xml file that you have created earlier which is in
ch6.aop.targetsource package
<bean id="prototypeTargetSource"
class="org.springframework.aop.target.PrototypeTargetSource">
<property name="targetBeanName" value="target3"/>
</bean>
<bean id="myBean1"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource" ref="prototypeTargetSource"/>
<property name="proxyTargetClass"><value>true</value></property>

</bean>
2. Put following codes in TestApp.java
MyInterface target3 = (MyInterface) context.getBean("myBean1");
target3.snap();

Reference:

1. http://itmyhome.com/spring/aop-api.html
2. https://technology.amis.nl/2005/06/19/pulling-the-rug-from-under-your-feet-while-
keeping-standing-using-the-hot-swappable-target-source-in-spring-aop/

Terminating the Interceptor Chain Early


We can terminate an advice in the chain early using following two different ways:

1. Throwing an Exception
2. Returning value instead of calling proceed

Example:
1. Inside ch6.aop.targetsource package create a class named
MessageDecorator.java which implements Advice methods as shown below:
package ch6.demo.targetsource;

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

public class MessageDecorator implements MethodInterceptor {

@Override
public String invoke(MethodInvocation invocation) throws Throwable {
// TODO Auto-generated method stub
System.out.println("Hello000 ");
try{throw new ArithmeticException("Stopping Interceptor Chain
Early"); }catch(Exception e){System.out.println(e);}
return "asd";
//Object retVal=invocation.proceed();
//System.out.print("!");
//return retVal;
}

2. Put following codes inside TestApp.java


package ch6.demo.targetsource;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MessageDecorator implements MethodInterceptor {

@Override
public String invoke(MethodInvocation invocation) throws Throwable {
// TODO Auto-generated method stub
System.out.println("Hello000 ");
try{throw new ArithmeticException("Stopping Interceptor Chain
Early"); }catch(Exception e){System.out.println(e);}
return "asd";
//Object retVal=invocation.proceed();
//System.out.print("!");
//return retVal;
}
}

Exposing Current Proxy and Current Method Invocation

Exposing Current Proxy

It is possible to configure to expose proxy itself such that you can retrieve the
proxy and invoke advised methods on the proxy from the target object. In order
to expose proxy, you have to do following:
factory.setExposeProxy(true);

Exposing Current Method Invocation

Sometimes target object needs to see the method invocation. For this, we need
to expose the current method invocation. To expose current method invocation,
you have to include following in your beans.xml file

<bean id="exposeInvocation"
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<property name="targetClass">

<value>org.springframework.aop.interceptor.ExposeInvocationInterceptor</value>
</property>
<property name="targetField"><value>INSTANCE</value></property>
</bean>
<bean id="swappable"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource" ref ="swapper" />
<property name="exposeProxy"><value>true</value></property>
<property name="interceptorNames">
<list>
<value>exposeInvocation</value>
</list>
</property>
</bean>
AspectJ and AspectWerkz Integration

AspectJ and AspectWerkz Integration are two powerful AOP framework. We can
integrate these frameworks in Spring to build sophisticated AOP support in Spring.

AspectJ Integration

AspectJ is an extension to the Java language that elevates aspects and pointcuts to
language level constructs.

In our previous chapters, we studied about common AspectJ annotations such as


@Before, @After etc.

Reference:

https://dzone.com/articles/aop-made-easy-aspectj-and

AspectWerkz Integration

Besides AspectJ, the most important and dedicated framework is AspectWrekz.


AspectWrekz differes from AspectJ in that it does not extend the Java language but
uses XML metadata to bind aspects at runtime. Since 2005, AspectJ and AspectWerkz
are integrated together.

You might also like