March 08, 2018

#Spring Part 8: Aspect Oriented Programming Interview Questions & Answers

What is Aspect Oriented Programming?
Aspect-oriented programming or AOP is one of the feature provided by Spring, actually it's not just a feature it a model of programming itself.

Suppose we have a common procedure across different objects, e.g Log message. To implement this, we can have a logMessage() method in all the objects. But this is not really a good design, because we are repeating the same method in all the objects. What we can do, we will create a new Logger class, which has logMessage() method. All other objects will refer to the Logger object's logMessage() method to print the message.

Now, if you are making a design diagram which depicts the relationship between all the objects and you want to know which object is an important one (by checking their relationship with other objects). In such case, the Logger will be the most important object, although it's not adding any business value.

The problem with this approach is that there will be too many relationships to the crosscutting objects and we need to still write the code to call the logMessage() method in all the business objects. In case, we use a different log implementation, then we need to make changes in all the business objects and make the changes accordingly to call the new log method.

All the applications have one other cross cutting concerns like logging, security or transactions. With AOP, we can remove the cross cutting concerns.

With AOP, we will create a 'Logging Aspect' class. After creating the aspect, we do not reference it from the objects, instead we will define the 'aspect configuration' which tells to which objects or methods these aspects apply to.

Suppose we have three business objects Partner, Vendor and Customer, each having the create() method and we need a logging mechanism while creating the Vendor and Customer. We need to do 'aspect configuration', Spring will make sure to call the logging method before creating the Vendor or a Customer. In case you decide to change the logging mechanism, all you need to make changes in 'aspect configuration'.

We can configure aspect to run before or after a particular (target) method.

Steps we need to take to write Aspect oriented program:
  • Write Aspects.
  • Configure where the aspects apply.
Explain different AOP terminologies?
  • Aspect: This is a module which has a set of APIs providing cross-cutting requirements. For example, a logging module would be called AOP aspect for logging. An application can have any number of aspects depending on the requirement. Aspects are implemented using regular classes or regular classes annotated with the @Aspect annotation in Spring Framework.
  • Advice: It's the actual action to be taken either before or after the method execution. Spring AOP uses an advice as an interceptor, maintaining a chain of interceptors “around” the join point.
  • Join Point: It represents a point in your application where we can plug-in the AOP aspect.
  • Pointcut: This is a set of one or more join points where an advice should be executed. We can specify pointcuts using expressions or patterns.
  • Introduction: This allows you to add new methods or attributes to the existing classes.
  • Target object: The object being advised by one or more aspects. This object will always be a proxied object, also referred to as the advised object.
  • Weaving: It is the process of linking aspects with other application types or objects to create an advised object. This can be done at compile time, load time, or at runtime.

What do you mean by Aspect?

  • Aspect is a modularization of concern which cuts across multiple objects.
  • Aspects are implemented using regular classes or regular classes annotated with the @Aspect annotation in Spring Framework.
  • Aspects are reusable blocks of code that are injected into application at runtime.
  • These are very powerful tools for adding behavior, especially behavior that applies to cross-cutting concerns. We can write the code in one spot and automatically apply it to many locations throughout our application.

What are the common applications of aspects in application development?

  • Logging
  • Security
  • Transaction management is another common use of aspects across the applications base. Spring also provides an aspect @Transactional to do this work.
  • Caching is another very useful opportunity for aspects and for this Spring provides an annotation. We can also write our own custom caching behavior.
What is an Advice?
An Action taken by an aspect at a particular joinpoint is known as an Advice. Spring AOP uses an advice as an interceptor, maintaining a chain of interceptors “around” the join point.


What are the different types of Advices?

  • Before: These types of advices execute before the joinpoint methods and are configured using @Before annotation mark.
  • After returning: These types of advices execute after the joinpoint methods completes executing normally and are configured using @AfterReturning annotation mark.
  • After throwing:  These types of advices execute only if joinpoint method exits by throwing an exception and are configured using @AfterThrowing annotation mark.
  • After (finally): These types of advices execute after a joinpoint method, regardless of the method’s exit whether normally or exceptional return and are configured using @After annotation mark.
  • Around: These types of advices execute before and after a joinpoint and are configured using @Around annotation mark.

What is the difference between a Joint point and Point cut?
Join point is a point of execution of the program, such as the execution of a method or the handling of an exception. In Spring AOP, a join point always represents a method execution.

Pointcut is a predicate or expression that matches join points. Advice is associated with a pointcut expression and runs at any join point matched by the pointcut.

In short, advice represents an action taken by an aspect at a particular joint point. A joint point is a point in a program, such as method execution, exception handling etc, where as a pointcut is an expression language of APO that matched joint points. 

What is Weaving?
Weaving is the process for interleaving separate cross-cutting concerns such as logging into core concerns such as business logic code to complete the system. AOP weaving composes different implementations of aspects into a cohesive system based on weaving rules. The weaving process (aka injection of aspects into Java classes) can happen at:
  • Compile-time: Weaving occurs during compilation process.
  • Load-time: Weaving occurs at the byte-code level at class loading time.
  • Runtime: Similar to load-time where weaving occurs at byte-code level during runtime as join points are reached in the executing application.
In Spring AOP, weaving is performed at runtime.

On what basis should we decided to use a particular weaving approach?
Load-time and runtime weaving have the advantages of being highly dynamic and enabling changes on the fly without having to rebuild and redeploy. But Load-time and runtime weaving adversely affect system performance. Compile time weaving offers better performance but requires rebuilding and redeployment to effect changes. 

How to declare aspect in Spring AOP?
 < bean id="myAspect" class="com.scrutiny.aop.MyAspect" >
   < !-- configure properties of aspect here -- >
 < /bean >

How to declare a pointcut in Spring AOP?
@Pointcut("execution(* update(..))")
private void customerUpdate {}
 
A pointcut declaration has four parts:
  • Matching Method Signature Patterns
  • Matching Type Signature Patterns
  • Matching Bean Name Patterns
  • Combining Pointcut Expressions
What is the difference between concern and cross-cutting concern in Spring AOP?
A Concern is a behavior, which we want to have in our application like Employment Management. Whereas cross-cutting concern is a concern which is applicable throughout the application e.g logging and security.

What are the available AOP implementations?
AspectJ, Spring AOP and JBoss AOP.

How to enable @AspectJ Support?
Include the below XML code in application XML: < aop:aspectj-autoproxy/ >
What are the Pointcut Designators supported by Spring AOP
  • execution: pointcut expression for matching method execution join points.
  • within: pointcut expression for matching to join points within certain types
  • this: pointcut expression for matching to join points where the bean reference is an instance of the given type
  • target: pointcut expression for matching to join points where the target object is an instance of the given type
  • args: pointcut expression for matching to join points where the arguments are instances of the given types
  • @target: pointcut expression for matching to join points where the class of the executing object has an annotation of the given type
  • @args: pointcut expression for matching to join points where the runtime type of the actual arguments passed have annotations of the given type
  • @within: pointcut expression for matching to join points within types that have the given annotation
  • @annotation: pointcut expression for matching to join points where the subject of the join point has the given annotation
Some examples of common pointcut expressions are:
  • the execution of any public method: execution(public * *(..))
  • the execution of any method with a name beginning with "set": execution(* set*(..))
  • the execution of any method defined by the PolicyService interface: execution(* com.scrutiny.service.PolicyService.*(..))
  • the execution of any method defined in the service package: execution(* com.scrutiny.service.*.*(..))
  • the execution of any method defined in the service package or a sub-package: execution(* com.scrutiny.service..*.*(..))
  • any join point (method execution only in Spring AOP) within the service package: within(com.scrutiny.service.*)
  • any join point (method execution only in Spring AOP) within the service package or a sub-package: within(com.scrutiny.service..*)
  • any join point (method execution only in Spring AOP) where the proxy implements the PolicyService interface: this(com.scrutiny.service.PolicyService)
  • any join point (method execution only in Spring AOP) where the target object implements the PolicyService interface: target(com.scrutiny.service.PolicyService)
  • any join point (method execution only in Spring AOP) which takes a single parameter, and where the argument passed at runtime is Serializable:
  • args(java.io.Serializable)
  • any join point (method execution only in Spring AOP) where the target object has an @Transactional annotation: @target(org.springframework.transaction.annotation.Transactional)
  • any join point (method execution only in Spring AOP) where the declared type of the target object has an @Transactional annotation: @within(org.springframework.transaction.annotation.Transactional)
  • any join point (method execution only in Spring AOP) where the executing method has an @Transactional annotation: @annotation(org.springframework.transaction.annotation.Transactional)
  • any join point (method execution only in Spring AOP) which takes a single parameter, and where the runtime type of the argument passed has the @Classified annotation: @args(com.xyz.security.Classified)
  • any join point (method execution only in Spring AOP) on a Spring bean named 'policyService': bean(policyService)
  • any join point (method execution only in Spring AOP) on Spring beans having names that match the wildcard expression '*Service': bean(*Service)
What is the difference between Spring AOP and AspectJ AOP?
AspectJ is the industry-standard implementation for Aspect Oriented Programming whereas Spring implements AOP for some cases. Main differences between Spring AOP and AspectJ are:
  • Spring AOP is simpler to use than AspectJ because we don’t need to worry about the weaving process.
  • Spring AOP supports AspectJ annotations, so if you are familiar with AspectJ then working with Spring AOP is easier.
  • Spring AOP supports only proxy-based AOP, so it can be applied only to method execution join points. AspectJ support all kinds of pointcuts.In simpler words Spring AOP supports only method level pointcuts, where as AspectJ supports field level pointcuts
  • One of the shortcoming of Spring AOP is that it can be applied only to the beans created through Spring Context.
When to use Spring AOP and when to use full AspectJ?
If we only need to advice the execution of operations on Spring beans then we should use Spring AOP. Spring AOP is simpler than AspectJ. Full AspectJ requires the AspectJ compiler in the build process. In case if we advice objects not to be managed by Spring Container, use AspectJ.

What are the required libraries to run AspectJ LTW in Spring?
spring-aop.jar, aspectjrt.jar and aspectjweaver.jar
 
What do you mean by Proxy in Spring Framework?
An object which is created after applying advice to a target object is known as a Proxy. In case of client objects the target object and the proxy object are the same.

Which design pattern is used in Spring AOP?

AOP is mainly based on Proxy design pattern (to perform run-time weaving). It also uses remote, Singleton, template method and decorator design pattern.
Writing Aspect using Aspect Oriented Programming
Let us create first Aspect using Aspect Oriented Programming. For this we will first add dependencies in pom.xml

##pom.xml
 < ?xml version="1.0" encoding="UTF-8"? >
 < 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.example < /groupId >
     < artifactId > AOPTest < /artifactId >
     < version > 0.0.1-SNAPSHOT < /version >
     < packaging > jar < /packaging >

     < name > AOPTest < /name >
     < description > Demo project for Spring Boot < /description >

     < parent >
         < groupId > org.springframework.boot < /groupId >
         < artifactId > spring-boot-starter-parent < /artifactId >
         < version > 1.5.10.RELEASE < /version >
         < relativePath / >
     < /parent >
     < properties >
         < project.build.sourceEncoding > UTF-8 < /project.build.sourceEncoding >
         < project.reporting.outputEncoding > UTF-8 < /project.reporting.outputEncoding >
         < java.version > 1.8 < /java.version >
     < /properties >
     < dependencies >
         < dependency >
             < groupId > org.springframework.boot < /groupId >
             < artifactId > spring-boot-starter < /artifactId >
         < /dependency >
         < dependency >
             < groupId > org.springframework < /groupId >
             < artifactId > spring-aspects < /artifactId >
             < version > 4.1.1.RELEASE < /version >
         < /dependency >
         < !-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -- >
         < dependency >
             < groupId > org.aspectj < /groupId >
             < artifactId > aspectjrt < /artifactId >
             < version > 1.8.10 < /version >
         < /dependency >
         < dependency >
             < groupId > org.springframework.boot < /groupId >
             < artifactId > spring-boot-starter-test < /artifactId >
             < scope > test < /scope >
         < /dependency >
         < dependency >
             < groupId > aopalliance < /groupId >
             < artifactId > aopalliance < /artifactId >
             < version > 1.0 < /version >
         < /dependency >
         < dependency >
             < groupId > cglib < /groupId >
             < artifactId > cglib < /artifactId >
             < version > 3.2.6 < /version >
         < /dependency >
         < dependency >
             < groupId > asm < /groupId >
             < artifactId > asm < /artifactId >
             < version > 3.3.1 < /version >
         < /dependency >
     < /dependencies >
     < build >
         < plugins >
             < plugin >
                 < groupId > org.springframework.boot < /groupId >
                 < artifactId > spring-boot-maven-plugin < /artifactId >
             < /plugin >
         < /plugins >
     < /build >
 < /project >

##We will create a class AOPMain which will have a main method. We will be instatiating the Spring context.
package com.test.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.aop.service.ShapeService;

public class AOPMain {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
        ShapeService shapeService=context.getBean("shapeService", ShapeService.class);
        System.out.println("*****AOPMain: Inside main(), the Shape circle name is "+shapeService.getCircle().getName());
    }
}

##Create Spring.xml
 < ?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="traingle" class="com.test.aop.model.Traingle" >
         < property name="name" value="Traingle Name" / >
     < /bean >
     < bean name="circle" class="com.test.aop.model.Circle" >
         < property name="name" value="Circle Name" / >
     < /bean >
     < bean name="shapeService" class="com.test.aop.service.ShapeService"    autowire="byName" / >
     < bean name="loggingAspect" class="com.example.aspect.LoggingAspect" / >
 < /beans >

##Circle class
package com.test.aop.model;

public class Circle {
    private String name;
    //getters and setters
}

##Traingle class
package com.test.aop.model;

public class Traingle {
    private String name;
    //getters and setters
}

##Create ShapeService
package com.test.aop.service;

import com.test.aop.model.Circle;
import com.test.aop.model.Traingle;

public class ShapeService {

    private Circle circle;
    private Traingle traingle;

    //getters and setters
}

##Create a LoggingAspect, which will contain list of all the Aspects.
package com.example.aspect;

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

@Aspect
public class LoggingAspect {
   
    /* The advice will run before the execution of getName() method.
     * In this case the advice will executed before calling any method with name getName()*/
    @Before("execution(public String getName())")
    public void getNameAdvice() {
        System.out.println("*****LoggingAspect: getNameAdvice is executed..");
    }
       
    /* If you want advice to execute only before executing a particular method in
     * a specific class then, you need to full path of the class before the method name.*/
    @Before("execution(public String com.test.aop.model.Traingle.getName())")
    public void getTraingleNameAdvice() {
        System.out.println("*****LoggingAspect: getTraingleNameAdvice is executed..");
    }
   
    /* If you want advice to execute every time a method which starts with get and
     * returns a String*/
    @Before("execution(public String get*())")
    public void getAllStringAdvice() {
        System.out.println("*****LoggingAspect: getAllAdvice is executed..");
    }
   
    /* If you want advice to execute every time a method which starts with get, irrespective of the return type*/
    @Before("execution(public * get*())")
    public void getAllAdvice() {
        System.out.println("*****LoggingAspect: getAllAdvice is executed..");
    }
   
    /*Suppose you want to execute two advice's before calling a particular method.
     * 1). You need to declare a methods (e.g forAllGetters() with a @PointCut
     * 2). Declare two advice's and instead of execution, write the name of method which has @PointCut annotation.
     */
   
    @Before("forAllGetters()")
    public void firstAdvice() {
        System.out.println("*****LoggingAspect: firstAdvice is executed..");
    }   
    @Before("forAllGetters()")
    public void secondAdvice() {
        System.out.println("*****LoggingAspect: secondAdvice is executed..");
    }
   
    @Pointcut("execution(* get*())")
    public void forAllGetters()
    {}
   
    /*If you want to apply point cuts to all the methods of a particular class*/   
    @Pointcut("within(com.test.aop.model.Traingle)")
    public void forAllMethodsOfClass()
    {}
   
    /*If you want to apply point cuts to all the methods inside a particular package/ sub package*/
    @Pointcut("within(com.test..*)")
    public void forAllMethodsPackages()
    {}
}

JoinPoints
If you want a advice to print a message depending on which method has actually triggered the advice, this can be done by JoinPoints. The JoinPoints has information about the actual method call, that has triggered the advice.

JoinPoints means, all the places in our code, where we can apply advice.

@Aspect
public class LoggingAspect {
    @Before("forAllMethodsOfCircle()")
    public void circleAdvice(JoinPoint joinPoint) {
        System.out.println("*****LoggingAspect: Circle Advice is executed: "+joinPoint.toString());
        //get Target, returns the object whose method us called which triggered the advice
        Circle circle=(Circle)joinPoint.getTarget();       
    }
   
    /*If you want to apply point cuts to all the methods of a particular class*/   
    @Pointcut("within(com.test.aop.model.Circle)")
    public void forAllMethodsOfCircle()
    {}
   
    /*This will be called for all the methods which takes String as an argument and to get the argument which is passed.*/
    @Before("args(name)")
    public void stringArgumentMethods(String name)
    {
        System.out.println("*****LoggingAspect: methods with String argument:"+name);
    }
}
ALSO CHECKSpring Interview Questions

-K Himaanshu Shuklaa..

No comments:

Post a Comment

RSSChomp Blog Directory