Monday, October 31, 2022

Spring - AOP (Aspect Oriented Programming)


In general, in enterprise applications development, if we use Object Oriented Programming languages then we have to provide the implementation by combining both the Application's business logic and services logic.


Example :

publicclassTransaction{
public void deposit(---){
----Deposit Logic-----
----Authentocation-----
----Logging------------
----Transact-----------
}
public void withdraw(---){
----Deposit Logic-----
----Authentication-----
----Logging------------
----Transact-----------
}
publicvoidtransfer(---){
----Deposit Logic-----
----Authentication-----
----Logging------------
----Transact-----------
}
}

  • If we use the above style of implementation then we are able to get the following problems.

  • It is very difficult to modify the services logic, it required to modify in all business methods.
    •  It will not provide Sharability
    •  It will not provide Code Reusability.
    •  Itwillprovidetightlycoupleddesign.

  • To overcome the above problems we have to use Aspect Orientation.
  • Aspect Orientation is not a programming language, it is a methodology or a paradiagm, it will be applied on Object Oriented Programming in order to get loosely coupled design and in order to improve sharability and Reusability.
  • The basic idea behind Aspect Orientation is to separate all services logic from System Business logic , declaring each and every service as an aspect and injecting these aspects into the application Business logic in the respective locations by using Dependence Injection.


  • In enterprise Applications, AOP will provide the following advantages.
    •  In Enterprise applications, Business components look very clean and have only
    • business implementation statements.
    •  All Services are implemented in a common place which simplifies code maintenance.
    •  We can make changes in a common location, so that, the changes are reflected in all business methods.

  • AOP is implemented by the following vendors.
    •  AspectJ
    •  SpringAOP
    •  JBOSSAOP

  • Spring Framework is providing the following two types of implementations 
  1. SchemaBasedImplementation
  2. AspectJ
    • a. DeclarativeBasedApproach 
    • b. Annotation-Based Approach
2. AOP Terminology

  • In general, AOP will use the following terminologies inorder to implement AOP-based implementation.
    1. Aspect
    2. Advice
    3. Joinpoint  
    4. Pointcut
    5. Target
    6. Proxy
    7. Weaving
    8. Introduction

1. Aspect:

  • An Aspect is the concern or a service which we want to implement in the application such as logging, transactional , Security etc.

2. Advice:

  • An Advice is the actual implementation of the aspect. Aspect is a concept and Advice is the concrete implementation of the concept.

3. Join point:

  • A JoinPoint is a point in the execution of the program where an aspect can be applied. It could be before/after executing the method, before throwing an exception, before/after modifying an instance variable etc.

4. Pointcut:

  • PointCuts tell on which join points the aspect will be applied. Advice is associated with a point-cut expression and is applied to a join point that matches the point-cut expression.

5. Target:

  • Target is a business component class which is being advised

6. Proxy:

  • Proxy is the object which is created by the framework after applying the advice on the target object.
    • Proxy = target + advice(s)

7. Weaving:

  • Weaving is the process of applying the aspect on the target object to product the proxy object. Weaving can be done at compile time, class loading time or runtime. Spring AOP supports weaving at runtime.

8. Introduction:

  • An Introduction allows adding new methods or attributes to existing classes. The new method and instance variable can be introduced to existing classes without having to change them, giving them a new state and behavior.


3. Advices In AOP

  • Advice is the implementation of Aspect. An Advice provides the code for implementation of the service or Aspect. As an example consider logging service, logging is an Aspect and Advice denotes the implementation of Logj.
  • In general, all the advices code will not be included in business methods at compile time, these services will be included at runtime.
  • Spring Framework is providing the following various advices.

    1.  BeforeAdvice
    2.  After Advice
    3.  After-Returning
    4.  After-throwing
    5.  AroundAdvice
    6.  Before Advice:

3.1. BeforeAdvice

  • Before advice contains service/Aspect implementation , it will be executed before executing the respective business method.
  • To represent Before Advice, Spring Framework has provided a predefined interface in the form of "org.springframework.aop.MethodBeforeAdvice".
  • If we want to use Before Advice in Spring applications , first, we have to declare an user defined class, it must implement org.springframework.aop.MethodBeforeAdvice interface and we must provide implementation for the following method provided by MethodBeforeAdvice interface.

  • public void before(Method m,Object[] Bus_Meth_Params, Object target)throws Exception

    • Where java.lang.reflect.Method parameter is able to provide metadata of the Business method to which BeforeAdvice is applied.
    • Where Object[] is providing business method parameter values in the form of Objects.
    • Where Object is representiung the target Object.
    • The services which are implemented in before() method are executed at before executing business logic.

Example:

 public class BeforeAdviceImpl implements MethodBeforeAdvice{
    public void before(Methodmethod,Object[]params,Objecttarget)
        throwsException{
        -----Serviceimplementation-----
    }
 }

3.2.After Advice[After Returning Advice] :

  • It is same as Before Advice, But this advice contains services which are applied after completion of our business method logic
  • To create an after returning advice in spring, we have to declare an user defined class, it must implement org.springframework.aop.AfterReturningAdvice and we must implement the following method.

  • public void afterReturning(Object returnValue,Object[] args, Object target)throws Exception
    • Where first parameter is representning return value in the form of Object type.
    • Where second parameter is able to represent business method parameters in the form of
    • Object[].
    • Where third parameter is representing Target Object.

Example :

public class AfterReturningAdviceImpl implements AfterReturningAdvice {
    public void afterReturning(Object returnValue,Object[] args, 
        Object target)throws Except ion{
    ----
    }
}

Note: 

  • In Schema Based implementation, After Advice and After-Returning Advice are same, but, in Annotation approach both are different.

3.3. After-throwing or Throws Advice:

  • This advice will be executed after throwing an exception from the business method.
  • To represent After-Throwing Advice, Spring Framework has provided a predefined interface in the form of "org.springframework.aop.ThrowsAdvice".
  • If we want to use After Throwing Advice in Spring applications , first, we have to declare an user defined class, it must implement org.springframework.aop.ThrowsAdvice interface and we must provide implementation for the following method provided by ThrowsAdvice interface.

    • public void afterThrowing([Method, args, target], ThrowableSubclass)
    • Some Examples of the above form are
    • public void afterThrowing(Exception ex)
    • public void afterThrowing(RemoteException)
    • public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
    • public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)

      • Where java.lang.reflect.Method parameter is able to provide metadata of the Business method to which BeforeAdvice is applied.
      • Where Object[] is providing business method parameter values in the form of Objects.
      • Where Object is representiung the target Object.
      • Where Exception is representing the generated Exception.

Example:

3.4. Around Advice

  • Around Advice will be executed before and after executing the business method.
  • Around Advice is combination of both Before and After Advice.
  • Around Advice is not given by spring framework and it is from Open Source implementation called AOP alliance.
  • Around Advice can be used by any framework which supports AOP.

  • To represent Around Advice, Spring AOP Aliance has provided a predefined interface in the form of org.aopalliance.intercept.MethodInterceptor.
  • MethodINterceptor has provided the following method inorder to provide services before and after execution of the business method.
    • public Object invoke(MethodInvocation mi)throws Throwable

  • In Around Advice, we will implement Before and After Advice in invoke() method, in invoke() method will provide before advice logic before calling proceed() method and we will provide After Advice logic after calling proceed() method.
  • Note: Around Advice can access the return value of business method and it can modify the value and it can return a different value back to the client, as return type is Object, but in the After Advice its not possible right, as its return type is void.

Example:

public class AroundAdviceImpl implements MethodInterceptor {
    public Object invoke(MethodInvocation mi)throws Throwable {
        //Before Logic
        Object ob = mi.proceed();

        //After logic
        return ob;
    }
 }

 3.5. PointCut

  • PointCut defines at what Joinpoints Advices has to be applied, instead of defining advices at all join points.
  • If we want to use PointCuts in AOP based applications then we have to configure that pointcuts in Spring configuration File.
  • To configure Pointcuts in configuration file then we have to use the following two types of PointCuts.

    1.  Static Pointcut
    2.  Dynamic Pointcut

6.1 Static Pointcut:

  • Static pointcuts define advice that is always executed. Static pointcuts are based on method and target class, and cannot take into account the method's arguments. 
  • Static pointcuts are sufficient - and best - for most usages. It's possible for Spring to evaluate a static pointcut only once, when a method is first invoked: after that, there is no need to evaluate the pointcut again with each method invocation.
  • To represent Pointcuts , Spring framework has provided a predefined interface in the form of "org.springframework.aop.PointCut".
  • SpringFramework has provided the following Implementation classes for org.springframework.aop.PointCut interface.
    •  NameMatchMethodPointcut  
    •  Perl5RegexpMethodPointcut  
    • JdkRegexpMethodPointcut

6.2 Dynamic Pointcut:

  • Dynamic pointcuts determine if advice should be executed by examining the runtime method arguments.
  • Dynamic pointcuts are costlier to evaluate than static pointcuts. They take into account method arguments, as well as static information. This means that they must be evaluated with every method invocation; the result cannot be cached, as arguments will vary.
  • To represent Dynamic Pointcut Spring has provided the following predefined class.

    •  ControlFlowPointcut
    •  DynamicMethodMatcherPointcut

  • If we want to use Pointcuts in Spring applications then we have to configure Pointcut and Advisor in apring configuration file.
  • In spring applications, we will use "DefaultPointCutAdvosor" inorder to suggest the advices to the Pointcuts.
  • Where if we want to use NameMatchMethodPointcut then we have to use "mappedNames" property of type "array" and we must provide business method names as values to which we want to apply advices.

Example:

public class MyString {
    public static void reverseString(String str) { 
        StringBuffer sb = new StringBuffer(str);
        System.out.println(sb.reverse()); 
    }
}

  • Where If we want to use "Perl5RegexpMethodPointcut" and "JdkRegexpMethodPointcut" in spring applications then we have to use a property like "pattern" of list type with different patterns.

Example:

 <beanid="pointcut"class="org.springframework.aop.support.Perl5RegexpMethodPointcut" >
    <property name="patterns">
    <list>
        <value>.*Employee.*</value>
    </list>
    </property>
 </bean>

  • Where if we want to use DefaultPointcutAdvisor in spring applications then we have to use "point-cut" and "advice" properties.

4. Example of  Before Advice

Employee.java

 publicclassEmployee{
     private int eno;
     private String ename;
     private float esal;
     private String eemail;
     private String emobile;

    public int getEno() {
        return eno;
    }

    public void setEno(int eno) {
        this.eno = eno;
    }

     public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public float getEsal() {
        return esal;
    }

    public void setEsal(float esal) {
        this.esal = esal;
    }

    public String getEemail() {
        return eemail;
    }

    public void setEemail(String eemail) {
        this.eemail = eemail;
    }

    public String getEmobile() {
        return emobile;
    }

    public void setEmobile(String emobile) {
        this.emobile = emobile;
    }
}

EmployeeService.java

package com.cloudtechtwitter.bo;
import com.cloudtechtwitter.beans.Employee;
public interface EmployeeService{
    public void displayEmployee(Employee emp);
        public void getEmployeeDetails(Employee emp);
    }
}

 EmployeeServiceImpl.java

package com.cloudtechtwitter.bo;
import com.cloudtechtwitter.beans.Employee;

public class EmployeeServiceImp limplements EmployeeService{

    @Override
    public void displayEmployee(Employee emp) {
        System.out.println("Employee Details from displayEmployee(---)");
        System.out.println("----------------------------------------------");
        System.out.println("Employee Number :"+emp.getEno());
        System.out.println("Employee Name :"+emp.getEname());
        System.out.println("Employee Salary :"+emp.getEsal());
        System.out.println("Employee Email Id :"+emp.getEemail());
        System.out.println("Employee Mobile No :"+emp.getEmobile());
    }

    public void getEmployeeDetails(Employee emp) {
         System.out.println("Employee Details from getEmployeeDetails(--)");
         System.out.println("---------------------------------------------------");
         System.out.println("Employee Number :"+emp.getEno());
         System.out.println("Employee Name :"+emp.getEname());
         System.out.println("Employee Salary :"+emp.getEsal());
         System.out.println("Employee Email Id :"+emp.getEemail());
         System.out.println("Employee Mobile No :"+emp.getEmobile());
    }
 }

 EmployeeValidator.java

package com.cloudtechtwitter.advice;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
import com.cloudtechtwitter.beans.Employee;

public class EmployeeValidator implements MethodBeforeAdvice {

 @Override
 public void before(Method method, Object[] params, Object target) 
    throws Throwable {

     Employee emp = (Employee) params[];
     System.out.println("Validation Messages for "+method.getName());
     System.out.println("-----------------------------------------------");
    
    if( emp.getEno() <  || emp.getEno() > 999) {
        System.out.println("*********Employee Number must be  digit number **********");
     }
    
     if( emp.getEsal() <  || emp.getEsal() > 5) {
         System.out.println("********* Employee Salary Must be in between  to 5 * *******");

     }

     if(!emp.getEemail().endsWith("@cloudtechtwitter.com")) {
         System.out.println("********* Employee Email is Invalid *************");
     }

     if(!emp.getEmobile().startsWith("9-")) {
         System.out.println("********* Employee Mobile Number is INvalid ********");
     }
 }
}

 ApplicationContext.xml

<?xmlversion=""encoding="UTF-8"?>
    <beansxmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.worg//XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/sche ma/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/
aop/spring-aop.xsd">
<!-- Bean Object -->
 <bean id="empBean" class="com.cloudtechtwitter.beans.Employee">
     <property name="eno" value="5"/>
     <property name="ename" value="AAA"/>
     <property name="esal" value=""/>
     <property name="eemail" value="aaa@gmail.com"/>
     <property name="emobile" value="9988776655"/>
 </bean>
 <!-- Target Object -->
 <bean id="empService" class="com.cloudtechtwitter.bo.EmployeeServiceImpl"/>
 
 <!-- Advice -->
 <bean id="validatorAdvice" class="com.cloudtechtwitter.advice.EmployeeValidator"/>
 
 <!-- Pointcut -->
 <bean id="pointcut" class="org.springframework.aop.support.NameMatchMethodPointc ut">
     <property name="mappedNames">
         <array>
         <value>displayEmployee</value>
         <value>getEmployeeDetails</value>
         </array>
     </property>
 </bean>
 
 <!-- Advisor -->
 <bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
     <property name="pointcut" ref="pointcut"/>
     <property name="advice" ref="validatorAdvice"/>
 </bean>
 
 <!-- Proxy Object -->
 <bean id="empProxy" class = "org.springframework.aop.framework.ProxyFactoryBean">
     <property name="target" ref="empService"/>
     <property name="interceptorNames">
     <list>
        <value>advisor</value>
     </list>
     </property>
 </bean>
 </beans>

 Test.java

package com.cloudtechtwitter.test;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.NameMatchMethodPointcut;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.cloudtechtwitter.beans.Employee;
import com.cloudtechtwitter.bo.EmployeeService;

public class Test {
  public static void main(String[] args) {
     ApplicationContext context = new 
        ClassPathXmlApplicationContext("applicationConte xt.xml");
     
     Employee emp = (Employee) context.getBean("empBean");
     EmployeeService empService = (EmployeeService) context.getBean("empProxy");
     empService.displayEmployee(emp);
     
     System.out.println();
     empService.getEmployeeDetails(emp);
 }
}

5. Example of After Advice

Student.java

package com.cloudtechtwitter.beans;
 publicclassStudent{
     private String sname;
     private String squal;
     private String semail;
     private String smobile;

    public String getSname() {
        return sname;
    }
    
    public void setSname(String sname) {
        this.sname = sname;
    }

    public String getSqual() {
        return squal;
    }

    public void setSqual(String squal) {
        this.squal = squal;
    }
    
    public String getSemail() {
        return semail;
    }

    public void setSemail(String semail) {
        this.semail = semail;
    }

    public String getSmobile() {
        return smobile;
    }

    public void setSmobile(String smobile) {
        this.smobile = smobile;
    }
}

 InstituteService.java

package com.cloudtechtwitter.bo;
import com.cloudtechtwitter.beans.Student;

public interface InstituteService{
    public void enquiry(Student std, String course_Name);
        public void registration(Student std, String course_name);
     }
}

InstituteServiceImpl.java

package com.cloudtechtwitter.bo;
import com.cloudtechtwitter.beans.Student;

public classI InstituteServiceImp limplements InstituteService{

    @Override
    public void enquiry(Student std, String course_Name) {
        System.out.println("Student Enquiry Details");
        System.out.println("-----------------------------");
        System.out.println("Student Name :"+std.getSname());
        System.out.println("Student Qualification :"+std.getSqual());
        System.out.println("Student Email ID :"+std.getSemail());
        System.out.println("Student Mobile NUmber :"+std.getSmobile());
        System.out.println("Enquiry Course Name :"+course_Name);
     }

    public void registration(Student std, String course_Name) {
        System.out.println("Student Course Registration Details");
         System.out.println("-------------------------------------");
         System.out.println("Student Name :"+std.getSname());
         System.out.println("Student Qualification :"+std.getSqual());
         System.out.println("Student Email ID :"+std.getSemail());
         System.out.println("Student Mobile NUmber :"+std.getSmobile());
         System.out.println("Enquiry Course Name :"+course_Name);
    }
 }

 ThanqAdvice.java

package com.cloudtechtwitter.advice;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
import com.cloudtechtwitter.beans.Student;

public class ThanqAdvice implement AfterReturningAdvice{

    @Override
    public void afterReturning(Object return_Val, Method method, Object[] params, Object t arget) throws Throwable {
        Student std = (Student)params[];
        String course_Name = (String)params[];
        System.out.println("ThanQ "+std.getSname()+" 
            for your course "+method.getName()+"on "+course_Name);
        System.out.println("cloudtechtwitter Team will contact with you for the Course Schedule");
    }
 }

ApplicationContext.xml

 <?xmlversion=""encoding="UTF-8"?>
 <beansxmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.worg//XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/sche ma/beans/spring-beans.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/ aop/spring-aop.xsd">
    
     <!-- Beans -->
     <bean id="stdBean" class="com.cloudtechtwitter.beans.Student">
         <property name="sname" value="cloud"/>
         <property name="squal" value="BTech"/>
         <property name="semail" value="cloud@gmail.com"/>
         <property name="smobile" value="9-9988776655"/>
     </bean>
    
    <!-- Target -->
    <bean id="target" class="com.cloudtechtwitter.bo.InstituteServiceImpl"/>
 
    <!-- Advice -->
    <bean id="advice" class="com.cloudtechtwitter.advice.ThanqAdvice"/>
 
    <!-- Proxy -->
    <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
         <property name="target" ref="target"/>
         <property name="interceptorNames">
             <list>
             <value>advice</value>
             </list>
         </property>
    </bean>
 </beans>

Test.java

package com. cloudtechtwitter.test;
import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.aop.support.NameMatchMethodPointcut; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.cloudtechtwitter.beans.Employee; import com.cloudtechtwitter.bo.EmployeeService; public class Test { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationConte xt.xml"); Employee emp = (Employee) context.getBean("empBean"); EmployeeService empService = (EmployeeService) context.getBean("empProxy"); empService.displayEmployee(emp); System.out.println(); empService.getEmployeeDetails(emp); } }

6. Example of Throws Advice:

Movie.java

import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.NameMatchMethodPointcut;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.cloudtechtwitter.beans.Employee;
import com.cloudtechtwitter.bo.EmployeeService;

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = 
        new ClassPathXmlApplicationContext("applicationConte xt.xml");
        
        Employee emp = (Employee) context.getBean("empBean");
        EmployeeService empService = (EmployeeService) context.getBean("empProxy");
        empService.displayEmployee(emp);
        System.out.println();
        empService.getEmployeeDetails(emp);
    }
}

 MovieService.java

package com.cloudtechtwitter.bo;
import com.cloudtechtwitter.beans.Movie;

public interface MovieService{
    public void playMovie(Movie movie)throws Exception;
}

MovieServiceImpl.java 

package com.cloudtechtwitter.bo;
import com.cloudtechtwitter.beans.Movie;

public class MovieServiceImpl implements MovieService{

 @Override
 public void playMovie(Movie movie)throws Exception {
     System.out.println("Movie Details");
     System.out.println("----------------");
     System.out.println("Movie Name :"+movie.getMovie_Name());
     System.out.println("Movie Time :"+movie.getShow_Time());
     System.out.println("Price :"+movie.getPrice());
    throw new RuntimeException("Power Failure Occurred");
 }
}

 MoneyReturnAdvice.java

package com.cloudtechtwitter.advice;
importjava.lang.reflect.Method;
importorg.springframework.aop.ThrowsAdvice;

publicclass MoneyReturnAdvice implements ThrowsAdvice{

 public void afterThrowing(Method method, Object[] params,
         Object target, Exception e) {
    
    System.out.println("Power Failure Exception Occurred, 
        Movie was stopped, please co me to counter and collect your money");
 }
}

ApplicationContext.xml

 <?xml version=""encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.worg//XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/sche ma/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/ aop/spring-aop.xsd">

     <!-- Beans -->
     <bean id = "movieBean" class="com.cloudtechtwitter.beans.Movie">
         <property name="movie_Name" value="Bahubali"/>
         <property name="show_Time" value="6:pm"/>
         <property name="price" value="5"/>
     </bean>

     <!-- Target -->
     <bean id="target" class="com.cloudtechtwitter.bo.MovieServiceImpl"/>

     <!-- Advice -->
     <bean id="advice" class="com.cloudtechtwitter.advice.MoneyReturnAdvice"/>

     <!-- Proxy -->
     <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
         <property name="target" ref="target"/>
         <property name="interceptorNames">
             <list>
             <value>advice</value>
             </list>
         </property>
     </bean>
  </beans>

Test.java

package com.cloudtechtwitter.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.cloudtechtwitter.beans.Movie;
import com.cloudtechtwitter.bo.MovieService;

public class Test{

 public static void main(String[] args) {
    ApplicationContext context = new 
        ClassPathXmlApplicationContext("applicationConte xt.xml");
    Movie movie = (Movie)context.getBean("movieBean");
    MovieService movie_Service = (MovieService) context.getBean("proxy");
    try {
         movie_Service.playMovie(movie);

     } catch (Exception e) {
     }
 }
}

7. Example of Around Advice:

Account.java

package com.cloudtechtwitter.beans;
public class Account{
 private String accNo;
 private String accName;
 private String accType;
 private int balance;

 public String getAccNo() {
    return accNo;
 }
 
 public void setAccNo(String accNo) {
   this.accNo = accNo;
 }

 public String getAccName() {
    return accName;
 }

 public void setAccName(String accName) {
    this.accName = accName;
 }

 public String getAccType() {
    return accType;
 }

 public void setAccType(String accType) {
    this.accType = accType;
 }

 public int getBalance() {
    return balance;
 }

 public void setBalance(int balance) {
    this.balance = balance;
 }
}

Cheque.java

 package com.cloudtechtwitter.beans;
 public class Cheque{
    
    private String cheque_No;
    private int amount;

    public String getCheque_No() {
        return cheque_No;
    }

    public void setCheque_No(String cheque_No) {
        this.cheque_No = cheque_No;
    }
    
    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }
 }

TransactionService.java

package com.cloudtechtwitter.bo;
import com.cloudtechtwitter.beans.Account;
import com.cloudtechtwitter.beans.Cheque;

public interface TransactionService{
     public void debit(Account acc, Cheque cheque );
}

 TransactionServiceImpl.java

package com.cloudtechtwitter.bo;
import com.cloudtechtwitter.beans.Account;
import com.cloudtechtwitter.beans.Cheque;

publicclass TransactionServiceImpl implements TransactionService{

 @Override
 public void debit(Account acc, Cheque cheque) {
     int initial_Amount = acc.getBalance();
     int debit_Amount = cheque.getAmount();
     int total_Amount = initial_Amount - debit_Amount;
     acc.setBalance(total_Amount);
     System.out.println("*******Transaction Success*******************");
     System.out.println("*******Amount is debited from Account********");
  }
 }

 ChequeClearenceAdvice.java

import com.cloudtechtwitter.beans.Account;
import com.cloudtechtwitter.beans.Cheque;

publicclass TransactionServiceImpl implements TransactionService{

 @Override
 public void debit(Account acc, Cheque cheque) {
     int initial_Amount = acc.getBalance();
     int debit_Amount = cheque.getAmount();
     int total_Amount = initial_Amount - debit_Amount;
     acc.setBalance(total_Amount);
     System.out.println("*******Transaction Success*******************");
     System.out.println("*******Amount is debited from Account********");
  }
 }

 applicationContext.xml

 <?xmlversion=""encoding="UTF-8"?>
     <beansxmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.worg//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.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/ aop/spring-aop.xsd">

    <!-- Beans -->
    <bean id="accBean" class="com.cloudtechtwitter.beans.Account">
     <property name="accNo" value="abc"/>
     <property name="accName" value="cloud"/>
     <property name="accType" value="Savings"/>
     <property name="balance" value=""/>
     </bean>

    <bean id="chequeBean" class="com.cloudtechtwitter.beans.Cheque">
     <property name="cheque_No" value="xyz"/>
     <property name="amount" value=""/>
    </bean>

    <!-- Target -->
    <bean id="target" class="com.cloudtechtwitter.bo.TransactionServiceImpl"/>

    <!-- Advice -->
    <bean id="advice" class="com.cloudtechtwitter.advice.ChequeClearenceAdvice"/>

     <!-- Proxy -->
    <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="target"/>
        <property name="interceptorNames">
        <list>
            <value>advice</value>
        </list>
    </property>
    </bean>
 </beans>

Test.java

package com.cloudtechtwitter.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.cloudtechtwitter.beans.Account;
import com.cloudtechtwitter.beans.Cheque;
import com.cloudtechtwitter.bo.TransactionService;

public class Test {

 public static void main(String[] args) {
     ApplicationContext context = new 
        ClassPathXmlApplicationContext("applicationConte xt.xml");
     Account account = (Account) context.getBean("accBean");
     Cheque cheque = (Cheque) context.getBean("chequeBean");
     TransactionService tx_Service = (TransactionService) context.getBean("proxy");
     tx_Service.debit(account, cheque);
 }
}
8. AspectJ

  • AspectJ is well known in AOP language, it provides specialized syntax to express concerns. It also provides tools to add a concern into the system and enables crosscutting concern and modularization, such as logging, error checking and handling, and so on.

  • Spring is supporting AspectJ in the following two ways.
    1.  Declarativeapproach
    2.  @AspectJannotationstyleapproach
 8.1. Declarative approach:

  • IN declarative approach, we will use Aspectj Namespace tags inorder to declare aspects, advices, Pointcuts,......
  • In declarative configuration approach, all the aspect declarations are placed under the <aop:config/> tag.
  • To use AOP namespace tags, we need to import the spring-aop schema.

applicationContext.xml

 <?xmlversion=""encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w org//XMLSchema-instance" 
        xmlns:aop="http://www.springframework.org/schema/aop" 
        xsi:schemaLocation= "http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/b eans/spring-beans.xsd 
        http://www.springframework.org/schema/aop http://www.springframework. org/schema/aop/spring-aop-xsd"> 
    <aop:config>
        <!-- contains aspect configuration and all method related configuration -->
    </aop:config>
 </beans>

Note:

  • The aop:config will contain all aspect configurations and all specific method-related configurations, such as around, pointcut, and so on.

8.1.1. Declaring Aspects:

  • To declare aspects by using AspectJ namespace tags we have to use the following tags. 

<aop:aspect id="--" ref="--"> 
    -----
    <aop:aspect id="--" ref="--"> 
        -----
    </aop:aspect> 
<aop:config>

  • Where "id" attribute will take Aspect id value.
  • Where "ref" attribute will take identity of the class ehich has declared in the configuration file by using <bean> tag in out side of <aop:aspect> tag.

Example:

<beans.....>
 <aop:config>
     <aop:aspect id="loggingAspect" ref="loggingAspectBean">
      ...
     </aop:aspect>
 </aop:config>
 <bean id="loggingAspectBean" 
        cla
 </beans>

8.1.2 Declaring Pointcuts:

  • A pointcut helps in determining the join points to be executed with different advices. To declare pointcuts we have to use the following tags in configuration file.

Example:

<aop:config>
    <aop:aspect id="----" ref="----">
       <aop:pointcut id="----" expression="------"/> 
       ...
    </aop:aspect> 
</aop:config>

  • Where "id" attribute in <aop:pointcut> tag will take identity to the Pointcut.
  • Where "expression" attribute in <aop:pointcut> will take AspectJ expression to define expression for the business methods which are required Advices.
  • Where "expression" attribute will take "execution" function with an expression.

Example:

  • <aop:pointcut id="businessService" expression="execution(* com.cloudtechtwitter.service.*.*(..))"/> 
  • In the above code, expression will repersent all java methods with any type of return type.

Example:

 <aop:config>
 <aop:aspect id="loggingAspect" ref="loggingAspectBean">
    <aop:pointcut id="loggingOperation" 
        expression="execution(* com.cloudtechtwitter.service .EmployeeService.*(..))" />
  </aop:aspect>
</aop:config>
<beanid="loggingAspectBean"class="com.cloudtechtwitter.aspect.EmployeeCRUDLoggingAspe ct" />

Examples on Pointcut Expressions:

1. execution (* com.cloudtechtwitter.service.EmployeeService.*(..))

  • The above Expression matches all of the methods declared in the EmployeeService
  • interface
  • The above expression matches methods with any modifier (public, protected, and private)
  • and any return type.
  •  The two dots in the argument list match any number of arguments.

2. execution(* EmployeeService.*(..))

  • The above Expression matches all methods of EmployeeService interface which are existed in the present package with any type of access modifier and with any return type. 

3. execution(public * EmployeeService.*(..))

  • The above Expression matches all public methods of EmployeService interface with any return type.

4. execution(public Employee EmployeeService.*(..))

  • The above Expression matches all public methods of EmployeeService interface with Employee return type.

5. execution(public Employee EmployeeService.*(Employee, ..))

  • The above Expression matches all methods of EmployeeService interface with Employee return type and first parameter as Employee. 
6. execution(public Employee EmployeeService.*(Employee, Integer))
  •  The above Expression matches all public methods of EmployeeService with Employee return type and with Employee as First parameter and Integer type parameter as second.

8.1.3 Declaring Advices:

  • Spring AspectJ is supporting thye following five advices .

  •  <aop:before> 
    • It is applied before calling the actual business logic method.
  •  <aop:after> 
    • It is applied after calling the actual business logic method.
  •  <aop:after-returning> 

    • it is applied after calling the actual business logic method. It can beused to intercept the return value in advice.

  •  <aop:around> 
    • It is applied before and after calling the actual business logic method.
  •  <aop:after-throwing> 
    • It is applied if actual business logic method throws exception.
  • All the above advices tags contains "method" and "pointcut-ref" attributes, where "method" atribute will take advice method and "pointcut-ref" attribute will take Pointcut reference whic we declared in Configuration file.

Example

 <beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.worg//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-.xsd
   http://www.springframework.org/schema/aop/
   http://www.springframework.org/schema/aop/spring-aop-.xsd ">

 <aop:config>
    <!-- Spring AOP Pointcut definitions -->
    <aop:pointcut id="loggingOperation"
    expression="execution(* com.cloudtechtwitter.service.EmployeeService.*(..))" />

    <!-- Spring AOP aspect -->
    <aop:aspect id="loggingAspect" ref="loggingAspectBean">
       <!-- Spring AOP advises -->
       <aop:before pointcut-ref="loggingOperation" method="logBefore" />
       <aop:after pointcut-ref="loggingOperation" method="logAfter" />
   </aop:aspect>
 </aop:config>

 <!-- Spring AOP aspect instances -->
 <bean id="loggingAspectBean" 
      class="com.cloudtechtwitter.aspect.EmployeeCRUDLoggingAs pect" />

 <!-- Target Object -->
 <bean id="employeeManager" class="com.cloudtechtwitter.service.EmployeeServiceImpl" />
</beans>

Steps to prepare Application by using AspectJ namespace tags

  1.  Declare Beans.
  2.  Declare Service interface
  3.  Declare Service interface implementation class.
  4.  CreateAspectclass
  5.  PrepareSpringConfigurationfile.
  6.  PrepareTestApplication

Example On AOP namespace tags

Employee.java

 packagecom.cloudtechtwitter.beans;

 publicclassEmployee{
 private int eno;
 private String ename;
 private float esal;
 private String eaddr;

 public int getEno() {
   return eno;
 }

 public void setEno(int eno) {
   this.eno = eno;
 }

 public String getEname() {
   return ename;
 }

 public void setEname(String ename) {
   this.ename = ename;
 }

 public float getEsal() {
   return esal;
 }

 public void setEsal(float esal) {
   this.esal = esal;
 }

 public String getEaddr() {
   return eaddr;
 }

 public void setEaddr(String eaddr) {
   this.eaddr = eaddr;
 }
}

 EmployeeService.java

package com.cloudtechtwitter.service;
import com.cloudtechtwitter.beans.Employee;

public interface EmployeeService{

 public String createEmployee(Employee emp)throws Exception;
 public Employee searchEmployee(int eno);
 public String updateEmployee(Employee emp);
 public String deleteEmployee(Employee emp);
}

 EmployeeServiceImpl.java

package com.cloudtechtwitter.service;
import com.cloudtechtwitter.beans.Employee;

public class EmployeeServiceImpl implements EmployeeService{

   @Override
   public String createEmployee(Employee emp){
      System.out.println("Employee "+emp.getEno()+" 
         Inserted Successfully from createEm ployee()");
      return "Success";
   }

    @Override
    public Employee searchEmployee(int eno) {
      System.out.println("Employee "+eno+" 
         Existed from serachEmployee()");
      return null;
    }

    @Override
    public String updateEmployee(Employee emp) {
       System.out.println("Employee "+emp.getEno()+"
          Updated Successfully from updateE mployee()");
      return "Success";
    }

    @Override
    public String deleteEmployee(Employee emp) {
       System.out.println("Employee "+emp.getEno()+" 
          Deleted Successfully from deleteEmp loyee()");
       return null;
     }
 }

LoggingAspectBean.java

package com.cloudtechtwitter.aspects;
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;

public class LoggingAspectBean {

 public void before(JoinPoint jp) {
   System.out.println("Before "+jp.getSignature()
      .getName()+" method execution");
 }

 public void after(JoinPoint jp) {
   System.out.println("After "+jp.getSignature().
      getName()+" method execution");
 }

 public void afterReturning(JoinPoint jp, Object result) {
   System.out.println("After Returning "+result+" 
      from "+jp.getSignature().getName());
 }

 public void around(ProceedingJoinPoint jp) {
   System.out.println("Before "+jp.getSignature()
      .getName()+"execution from around Adv ice");

   try {
       jp.proceed();
   } catch (Throwable e) {
      e.printStackTrace();
   }
   
   System.out.println("After "+jp.getSignature()
      .getName()+"execution from around Advice");
  }
  
  public void afterThrowing(JoinPoint jp, Throwable exception) {
      System.out.println("After throwing "+exception+" 
      from "+jp.getSignature().getName()+" method");
   }
 }

applicationContext.xml

<?xml version=""encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.worg//XMLSchema-instance"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xsi:schemaLocation="nhttp://www.springframework.org/schema/beans 
   http://www.springframework.org/sche ma/beans/spring-beans.xsd
   http://www.springframework.org/schema/aop 
   http://www.springframework.org/schema/ aop/spring-aop.xsd">

 <!--beans-->
<bean id="empBean" class="com.cloudtechtwitter.beans.Employee">
 <property name="eno" value=""/>
 <property name="ename" value="AAA"/>
 <property name="esal" value="5"/>
 <property name="eaddr" value="Hyd"/>
 </bean>

<!-- target Bean-->
<bean id="empService" class="com.cloudtechtwitter.service.EmployeeServiceImpl"/>

<!-- Aspect bean -->
<bean id="loggingAspectBean" class="com.cloudtechtwitter.aspects.LoggingAspectBean"/>
 <aop:config>
    <aop:aspect id="loggingAspect" ref="loggingAspectBean">
       <aop:pointcut expression="execution(* com.cloudtechtwitter.service.EmployeeService.*(..)) " id="empPointcut"/>
       <aop:before method="before" pointcut-ref="empPointcut"/>
       <aop:after method="after" pointcut-ref="empPointcut"/>
       <aop:after-returning method="afterReturning" pointcut- ref="empPointcut" returning="result"/>
       <aop:around method="around" pointcut-ref="empPointcut"/>
       <aop:after-throwing method="afterThrowing" throwing="exception" pointcut- ref="empPointcut"/>
    </aop:aspect>
  </aop:config>
 </beans>

 Test.java

package com.cloudtechtwitter.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.cloudtechtwitter.beans.Employee;
import com.cloudtechtwitter.service.EmployeeService;

publicclassTest{

public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationConte xt.xml");
    EmployeeService empService = (EmployeeService)context.getBean("empService");
    Employee emp = (Employee) context.getBean("empBean");
    String message = "";
    
    try {
       message = empService.createEmployee(emp);
    } catch (Exception e) {
    
    }
    System.out.println(message);
 }
}

Example:

Show.java

package com.cloudtechtwitter.beans;
public class Show{

 private String name;
 private String time;
 private int price;

 public String getName() {
   return name;
 }

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

 public String getTime() {
   return time;
 }

 public void setTime(String time) {
   this.time = time;
 }

 public int getPrice() {
  return price;
 }

 public void setPrice(int price) {
   this.price = price;
 }

}

ShowService.java

package com.cloudtechtwitter.service;
import com.cloudtechtwitter.beans.Show;
publici interface ShowService{
     public String runShow(Show show)throws RuntimeException;
 }
ShowServiceImpl.java
package com.cloudtechtwitter.service;
import com.cloudtechtwitter.beans.Show;

public class ShowServiceImpl implements ShowService {
   @Override
   public String runShow(Show show)throws RuntimeException {
      System.out.println("******Show "+show.getName()+" Start****");
         System.out.println("Show "+show.getName()+" is Running Successfully");
         
      if(!show.getName().equalsIgnoreCase("Mimicry")) {
         throw new RuntimeException();
      }

      System.out.println("******Show "+show.getName()+" End****");

      return "success";
   }

 }

ShowAspect.java

package com.cloudtechtwitter.aspect;

import org.aspectj.lang.ProceedingJoinPoint;

public classShowAspect{

 public void before() {
   System.out.println("Get Tickets for the Show");

 }

 public void around(ProceedingJoinPoint jp) {
   System.out.println("Show is Ready To start, 
      Take Chairs and Keep mobiles in Silent m ode");
   try {
      jp.proceed();
   } catch (Throwable e) {
      e.printStackTrace();
   }
   
   System.out.println("Show Completed just now, Check your Laguages");
 }

 public void after() {
   System.out.println("Show is over , quit from Hall");
 }

 public void afterReturning() {
   System.out.println("Tankq for attending Show");
 }

 public void afterThrowing() {
  System.out.println("There is an Interruption in show, because, Show is not Mimicry sh ow");
 }

 }

applicationContext.xml

 <aop:aspect id="loggingAspect" ref="loggingAspectBean">
    <aop:pointcut id="loggingOperation" 
        expression="execution(* com.cloudtechtwitter.service .EmployeeService.*(..))" />
  </aop:aspect>
</aop:config>
<beanid="loggingAspectBean"class="com.c

Test.java

 <?xml version=""encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.worg//XMLSchema-instance"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xsi:schemaLocation="
   http://www.springframework.org/schema/beans http://www.springframework.org/sche ma/beans/spring-beans.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/ aop/spring-aop.xsd">

 <!-- beans -->
   <bean id="showBean" class="com.cloudtechtwitter.beans.Show">
       <property name="name" value="Singing"/>
       <property name="time" value="7:PM"/>
       <property name="price" value=""/>
   </bean>

 <!-- Target -->
 <bean id="showService" class="com.cloudtechtwitter.service.ShowServiceImpl"/>

 <!-- aspect -->
 <bean id="showAspect" class="com.cloudtechtwitter.aspect.ShowAspect"/>
 <aop:config>
    <aop:aspect id="mimicryShowAspect" ref="showAspect">
       <aop:pointcut expression="execution(public String com.cloudtechtwitter.service.ShowSe rvice.runShow(com.cloudtechtwitter.beans.Show))" id="showPointcut"/>
       <aop:before method="before" pointcut-ref="showPointcut"/>
       <!-- <aop:around method="around" pointcut-ref="showPointcut"/> -->
       <aop:after method="after" pointcut-ref="showPointcut"/>
       <aop:after-returning method="afterReturning" pointcut-ref="showPointcut"/>
       <aop:after-throwing method="afterThrowing" pointcut-ref="showPointcut" />
    </aop:aspect>
 </aop:config>
 </beans>

Test.java

package com.cloudtechtwitter.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.cloudtechtwitter.beans.Show;
import com.cloudtechtwitter.service.ShowService;

publicclassTest{
 public static void main(String[] args) {
   ApplicationContext context = 
      new ClassPathXmlApplicationContext("applicationConte xt.xml");
    Show show = (Show) context.getBean("showBean");
    ShowService showService = (ShowService) context.getBean("showService");
   
   try {
      showService.runShow(show);
   } catch (RuntimeException e) {
    //System.out.println(e.getMessage());
    }
  }
 }
8.2.@AspectJ annotation style approach :

  • Spring Framework supporting Annotations to support AspectJ implementation in the form of "org.aspectj.lang.annotation" package.

  • Spring AspectJ AOP implementation provides the following annotations:

  • @Aspect: 
    • It will declare a class as an aspect.
  • @Pointcut: 
    • It will declare a pointcut expression.
  • @Before: 
    • It will declare before advice, It will be executed before executing the Business method.
  • @After: 
    • It will declare after advice, It will be executed after executing the actual Business method and before returning result.
  • @AfterReturning:
    •  It declares after returning advice, It will be executed after calling the actual Business method and after returning result.
  • @Around: 
    • It declares around advice, It will be executed before and after calling the actual Business method.
  • @AfterThrowing: 
    • It declares the throws advice, It will be executed if the actual Business method throws exception.

Note: 

  • To activate all the above annotations in Spring applications we have to use <aop:aspectj- autoproxy/> tag in spring configuration file.

8.2.1 Example using @AspectJ annotation

Account.java

packagecom.cloudtechtwitter.beans;

public class Account{
 privte String accNo;
 private String accName;
 private String accType;
 private int balance;

 public String getAccNo() {
   return accNo;
 }

 public void setAccNo(String accNo) {
   this.accNo = accNo;
 }

 public String getAccName() {
   return accName;
 }

 public void setAccName(String accName) {
   this.accName = accName;
 }

 public String getAccType() {
   return accType;
 }

 public void setAccType(String accType) {
   this.accType = accType;
 }

 public int getBalance() {
   return balance;
 }

 public void setBalance(int balance) {
   this.balance = balance;
 }
}

  TransactionService.java

 package com.cloudtechtwitter.service;
 import com.cloudtechtwitter.beans.Account;
 import com.cloudtechtwitter.exceptions.InsufficientFundsException;

 public interface TransactionService {
   public String withdraw(Account acc, int wd_Amt)throws InsufficientFundsException;
 }

TransactionServiceImpl.java

package com.cloudtechtwitter.service;
import org.springframework.stereotype.Component;
import com.cloudtechtwitter.beans.Account;
import com.cloudtechtwitter.exceptions.InsufficientFundsException;

@Component("transaction")
public classTransactionServiceImpl implements TransactionService{

 @Override
 public String withdraw(Account acc, int wd_Amt) throws InsufficientFundsException {
    String status = "";
    if(acc.getBalance() > wd_Amt) {
      int total_Bal = acc.getBalance() - wd_Amt;
      acc.setBalance(total_Bal);
      System.out.println("From withdraw(): Transaction Withdraw Completed ");
      status = "SUCCESS";
    }else {
      status = "FAILURE";
      throw new InsufficientFundsException("Funds are not Sufficient in Account");
    }
 return status;
 }
}

 InsufficientFundsException.java

package com.cloudtechtwitter.exceptions;
public class InsufficientFundsException extends Exception{

   public InsufficientFundsException(String desc) {
    super(desc);
   }
}

TransactionAspect.java

packagecom.cloudtechtwitter.aspect;
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.springframework.stereotype.Component;
import com.cloudtechtwitter.beans.Account;
import com.cloudtechtwitter.exceptions.InsufficientFundsException;

@Component("aspect")
@Aspect
public class TransactionAspect {

 @Before("execution(* com.cloudtechtwitter.service.TransactionService.*(..))")
 public void before(JoinPoint jp) {
   Object[] args = jp.getArgs();
   Account acc = (Account) args[];
   System.out.println("Before Advice : Initial Balance :"+acc.getBalance());
 }

 @After("execution(* com.cloudtechtwitter.service.TransactionService.*(..))")
 public void after(JoinPoint jp) {
   Object[] args = jp.getArgs();
   Account acc = (Account) args[];
   System.out.println("After Advice : Total Balance :"+acc.getBalance());
 }

 @AfterReturning(pointcut="execution(* com.cloudtechtwitter.service.TransactionService.*(..))",
 returning="result")
 public void afterReturning(JoinPoint jp, String result) {
   System.out.println("After Returning Advice: Transaction Status :"+result);
 }

 @Around("execution(* com.cloudtechtwitter.service.TransactionService.*(..))")
 public void around(ProceedingJoinPoint jp) {
   System.out.println("Around Advice : Before "+jp.getSignature()
      .getName()+" Method E xecution");
   String status = "";

    try {
       status = (String)jp.proceed();
    } catch (Throwable e) {
       e.printStackTrace();
    }

    System.out.println("Around Advice : After "+jp.getSignature()
    .getName()+" Method Ex ecution");
    System.out.println("Around Advice : Transaction Status :"+status);
 }


 //@AfterThrowing(pointcut="execution(* com.cloudtechtwitter.service.TransactionService.*(..))",
 //throwing="exception")
 public void afterThrowing(JoinPoint jp, InsufficientFundsException exception) {
   
   System.out.println("After Throwing Advice : 
      "+exception.getClass().getName()+" In Tra nsaction :"+exception.getMessage());
 }

}

applicationContext.xml

<?xml version=""encoding="UTF-8"?>
 <!--
 <beansxmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.worg//XMLSchema-instance"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xsi:schemaLocation=" http://www.springframework.org/schema/beans 
      http://www.springframework.org/sche ma/beans/spring-beans.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/ aop/spring-aop.xsd">
 -->
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.worg//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/beans http://www.springframework.org/sche ma/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/ aop/spring-aop.xsd
    http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context.xsd">
 <context:annotation-config/>
 <context:component-scan base-package="com.cloudtechtwitter.service"/>
 <context:component-scan base-package="com.cloudtechtwitter.aspect"/>
 <aop:aspectj-autoproxy/>
 <!-- beans -->
 <bean id="accBean" class="com.cloudtechtwitter.beans.Account">
 <property name="accNo" value="abc"/>
 <property name="accName" value="cloud"/>
 <property name="accType" value="Savings"/>
 <property name="balance" value=""/>
 </bean>
 <!--
 <bean id="transaction" class="com.cloudtechtwitter.service.TransactionServiceImpl"/>
 <bean id="txAspect" class="com.cloudtechtwitter.aspect.TransactionAspect"/>
 -->
</beans>

Test.java.

package com.cloudtechtwitter.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.cloudtechtwitter.beans.Account;
import com.cloudtechtwitter.exceptions.InsufficientFundsException;
import com.cloudtechtwitter.service.TransactionService;

public class Test {
 public static void main(String[] args) {
    ApplicationContext context = 
      new ClassPathXmlApplicationContext("applicationConte xt.xml");

    Account acc = (Account) context.getBean("accBean");
    TransactionService txService = (TransactionService) context.getBean("transaction");
       try {
          txService.withdraw(acc,5);
       } catch (InsufficientFundsException e) {
          //e.printStackTrace();
       }
 }

}

You may also like

Kubernetes Microservices
Python AI/ML
Spring Framework Spring Boot
Core Java Java Coding Question
Maven AWS