AOP is a tool for implementing crosscutting concerns, which means that you use AOP for modularizing individual pieces of logic, known as concerns, and you apply these concerns to many parts of an application

Logging and security are typical examples of crosscutting concerns that are present in many applications.

The two distinct types of AOP: static and dynamic. In static AOP, like AspectJ’s , the crosscutting logic is applied to your code at compile time, and you cannot change it without modifying the code and recompiling. With dynamic AOP, like Spring’s AOP, crosscutting logic is applied dynamically, at runtime. This allows you to make changes in the distribution of crosscutting without recompiling the application.



AOP Concepts



Joinpoint - A joinpoint is a well-defined point during the execution of your application. Typical examples of joinpoints include a call to a method, the method invocation itself, class initialization, and object instantiation. Joinpoints define the points in your application at which you can insert additional logic using AOP.
Advice: The code that is executed at a particular joinpoint is called the advice. There are many different types of advice, including before advice, which executes before the joinpoint, and after advice, which executes after it.
Pointcuts: A pointcut is a collection of joinpoints that you use to define when advice should be executed.
Aspects: An aspect is the combination of advice and pointcuts.
Weaving: This is the process of actually inserting aspects into the application code at the appropriate point
Target: An object whose execution flow is modified by some AOP process is referred to as the target object. Often, you see the target object referred to as the advised object.
Introduction: Introduction is the process by which you can modify the structure of an object by introducing additional methods or fields to it. You can use introduction to make any object implement a specific interface without needing the object’s class to implement that interface explicitly





Types of AOP
Static AOP

In static AOP, the weaving process forms another step in the build process for an application

The drawback of this mechanism is that any modifications you make to the aspects, even if you
simply want to add another joinpoint, require you to recompile the entire application.

AspectJ is an excellent example of a static AOP implementation



Dynamic AOP

Dynamic AOP implementations like Spring AOP differ from static AOP implementations in that the
weaving process is performed dynamically at runtime.

The slight drawback of dynamic AOP is that, typically, it does not perform as well as static AOP, but its performance is steadily improving

The major benefit of dynamic AOP implementations is the ease with which you can modify the entire aspect set of an application without needing to recompile the main application code.



Choosing an AOP Type

Spring AOP is less complex than AspectJ



AOP in Spring
“Hello,World” in AOP


we take a simple class that outputs the message “World”, and then using AOP, we transform an instance of this class at runtime to output “Hello, World!” instead



The MessageWriter Class


public class MessageWriter {
public void writeMessage() {
System.out.print("World");
}
}


We want to advise—that is, add some advice to—this class so that the writeMessage()
method actually writes “Hello World!” instead


To do this, we need to execute some code before the method body executes to write “Hello”, and some code after the method body executes to write “!”.


In AOP terms, what we need is an around advice—that is, advice that executes around a joinpoint. In this case, the joinpoint is the invocation of the writeMessage() method.


Implementing Around Advice


import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MessageDecorator implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.print("Hello ");
Object retVal = invocation.proceed();
System.out.println("!");
return retVal;
}
}




The MethodInterceptor interface is the AOP Alliance standard interface for implementing around advice for method invocation joinpoints


The MethodInvocation object represents the method invocation that is being advised, and using this object, we control when the method invocation is actually allowed to proceed. Because this is around advice, we are essentially capable of performing some actions before the method is invoked and some actions after it is invoked but before it returns.


The final step in this sample is to weave the MessageDecorator advice into the code. To do this, we create an instance of MessageWriter, the target, and then create a proxy of this instance, instructing the proxy factory to weave in the MessageDecorator advice.


Weaving the MessageDecorator Advice
import org.springframework.aop.framework.ProxyFactory;


public class HelloWorldWeaver {
public static void main(String[] args) {
MessageWriter target = new MessageWriter();
// create the proxy
ProxyFactory pf = new ProxyFactory();
pf.addAdvice(new MessageDecorator());
pf.setTarget(target);
MessageWriter proxy = (MessageWriter) pf.getProxy();
// write the messages
target.writeMessage();
System.out.println("");
proxy.writeMessage();
}
}



Creating Advice in Spring

Spring supports five different flavors of advice


Before - org.springframework.aop. MethodBeforeAdvice - Using before advice, you can perform custom processing before a joinpoint executes. Because a joinpoint in Spring is always a method invocation, this essentially allows you to perform preprocessing before the method executes. Before advice has full access to the target of the method invocation as well as the arguments passed to the method, but it has no control over the execution of the method itself.

After returning - org.springframework.aop.AfterReturningAdvice - After returning advice is executed after the method invocation at the joinpoint has finished executing and has returned a value.

Around - org.aopalliance.intercept.MethodInterceptor - In Spring, around advice is modeled using the AOP Alliance standard of a method interceptor. Your advice is allowed to execute before and after the method invocation, and you can control the point at which the method invocation is allowed to proceed. You can choose to bypass the method altogether if you want, providing your own implementation of the logic.

Throws - org.springframework.aop.ThrowsAdvice - Throws advice is executed after a method invocation returns but only if that invocation threw an exception. It is possible for throws advice to catch only specific exceptions, and if you choose to do so, you can access the method that threw the exception, the arguments passed into the invocation, and the target of the invocation.

Introduction - org.springframework.aop.IntroductionInterceptor - Spring models introductions as special types of interceptors. Using an introduction interceptor, you can specify the implementation for methods that are being introduced by the advice. Introductions are covered in more detail in the next chapter.



Interfaces for Spring advice types





Creating Before Advice


Before advice is one of the most useful advice types available in Spring. Before advice can modify the arguments passed to a method and can prevent the method from executing by raising an exception.






Creating After Returning Advice
after returning advice is executed after the method invocation at the joinpoint
returns.


ReportAuditLogAdvice


public class ReportAuditLogAdvice implements AfterReturningAdvice {


private static final Log log = LogFactory.getFactory().getInstance(
ReportAuditLogAdvice.class);


private WebDAO webDao;




/*
* (non-Javadoc)
*
* @see org.springframework.aop.AfterReturningAdvice#afterReturning(java.lang.Object,
* java.lang.reflect.Method, java.lang.Object[], java.lang.Object)
*/
public void afterReturning(Object arg0, Method arg1, Object[] arg2,
Object arg3) {

log.debug("**** audit log started for: "+arg1.getDeclaringClass().getName());

try {

WorkflowServiceRequest request = (WorkflowServiceRequest) arg2[0];
String serviceName = arg1.getDeclaringClass().getName();
serviceName = serviceName
.substring(serviceName.lastIndexOf(".") + 1);
RequestToVOHelper helper = new RequestToVOHelper();
//todo erming fix the compilation error later
FbOperationLogVO opLogVO = helper.workflowToOperation(request,
arg1.getName(), serviceName);
log.debug("**** Operation Log VO :");
log.debug(opLogVO);
webDao.saveOperationLog(opLogVO);

log.debug("*** audit log end .....");

} catch (Throwable ex) {
log.error("Unable to audit but ignored the same......... ");
ex.printStackTrace();
}
}






/**
* @return the webDao
*/
public WebDAO getWebDao() {
return webDao;
}






/**
* @param webDao the webDao to set
*/
public void setWebDao(WebDAO webDao) {
this.webDao = webDao;
}


}


Creating Around Advice
Around advice functions like a combination of before and after advice, with one big difference—you can modify the return value. Not only that, you can also prevent the method from actually executing. This means that using around advice, you can essentially replace the entire implementation of a method with new code.


Around advice in Spring is modeled as an interceptor using the MethodInterceptor interface.







Creating Throws Advice


Throws advice is similar to after returning advice in that it executes after the joinpoint, which is always a method invocation, but throws advice only executes if the method threw an exception.


Throws advice is also similar to after returning advice in that it has little control over program execution. If you are using a throws advice, you can’t choose to ignore the exception that was raised and return a value for the method instead. The only modification you can make to the program flow is to change the type of exception that is thrown.


public class ExceptionLogAdvice implements ThrowsAdvice {
protected final Log log = LogFactory.getFactory().getInstance(
ExceptionLogAdvice.class);


public void afterThrowing(Method m, Object[] args, Object target,
Exception ex) {
StringBuffer buffer = ObjectToString(m, args, ex);
log.fatal(buffer);

}


private StringBuffer ObjectToString(Method m,Object[] args,Exception ex){

InetAddress ipaddress=null;
try {
ipaddress = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
log.error("Unknown host exception occured",e);
}
StringBuffer buffer=new StringBuffer();
if(ipaddress==null){
buffer.append("\nUnknown host exception occured.Not able to retrieve ip address of the System \n");
}
else{
buffer.append("\nException Occured\nIPADDRESS: "+ipaddress.getHostAddress());
buffer.append("\nHost Name: "+ipaddress.getHostName()+"\n");
}
buffer.append("Exception in following method \n"+m);
if(args!=null && args.length>0){
int argLength=args.length;
for(int i=0;i<argLength;i++){
buffer.append("\n\nMethod Param"+(i+1)+"...."+args[i]);
}
}
buffer.append("\n\nError Message: "+ex.getMessage()+"\n");
buffer.append("Error Cause: " + ex.getCause() + "\n");
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
ex.printStackTrace(pw);
pw.flush();
sw.flush();
buffer.append(sw);
return buffer;
}
}

Leave a Reply

Subscribe to Posts | Subscribe to Comments

About This Site

Howdy! My name is Suersh Rohan and I am the developer and maintainer of this blog. It mainly consists of my thoughts and opinions on the technologies I learn,use and develop with.

Blog Archive

Powered by Blogger.

- Copyright © My Code Snapshots -Metrominimalist- Powered by Blogger - Designed by Suresh Rohan -