You are on page 1of 48

Spring AOP:

—----------
In general, in enterprise applications, we will prepare the applications by
using Object orientation style, in Object Orientation style we will provide
the business logic and Services Logic[Authentication, Validations,
Internationalization, Logging,....] in a combined manner.

public class Transaction{


public void deposit(){
—Authentication—-
—Business logic—----
—-Logging—--
—---Transaction—---
}
public void withdraw(){
—Authentication—-
—Business logic—----
—-Logging—--
—---Transaction—---
}
public void transfer(){
—Authentication—-
—Business logic—----
—-Logging—--
—---Transaction—---

}
}

In the above approach, we are able to get the following problems.


1. No Code Reusability, Same services logic we provided repeadly in all
the business methods.
2. No Shareability, Separate individual Services logics are maintained at
each and every Business method.
3. No easy changes in the Services, if we want to provide any updations in
any service then we must change the respective code in all the business
methods.
—-----
—------
To overcome all the above problems we must use AOP, that is Aspect Oriented
Programming.
AOP is a methodology or a set of rules and regulations or a set of
conventions which are applied on the Object oriented Programming in order to
improve Reusability and Shareability.

As per the Aspect Orientation, we have to separate all the services logic
from Business logic, we must declare each and every service as an aspect and
we must provide all the required aspects to the applications at runtime.

In the enterprise applications AOP is able to provide the following


advantages.
1. In AOP, all the business components are very much clean and have only
business logic.
2. All Services are implemented at a common location which simplifies the
Code maintenance.
3. We can make changes in common locations, so that the changes are
available to all business methods.

AOP is implemented by the following vendors.


1. AspectJ
2. Spring AOP
3. JBOSS AOP

Spring Framework is able to provide the AOP like below.


1. Schema Based AOP
2. AspectJ
a. Declarative Approach
b. Annotation Approach
AOP Terminology:
—----------------
1. Aspect
2. Advice
3. Joinpoint
4. Pointcut
5. Target
6. Proxy
7. Weaving
8. Introduction

Aspect:
Aspect is a cross cutting concern or a service which we are going to apply in
the applications.
EX: Logging, Transactions, Security,.....

Advice:
Advice is the actual implementation of the Aspect , that is Aspect is a
concept And the Advice is the implementation of the Aspect.

EX: Logging is an aspect, but the same Logging has so many implementations
like Log4j, JAVA provided Logging,.... Each and every implementation of
Logging which we are going to use in our application is called an Advice.

JoinPoint:
JoinPoint is a point in the application execution where an aspect can be
applied.

Pointcut:
Pointcut is an expression, it represents which Aspects at which join point we
are going to apply in the application.

Target:
It is a Business component to apply all the aspects.

Proxy:
Proxy is an object which has the Target object with all the aspects or
Advices.

Proxy = Target + Advices


Weaving:
Weaving is the process of applying aspects on the target objects in Proxy
objects.

Introduction:
An introduction provides a very good environment to allow adding new methods
or attributes to the existing components without having changes in the code
and giving new behavior to the Component.

Advices in Spring:
—------------------
Advice is the real implementation of the Aspect, Advice is able to provide
the code for implementing Aspects.
EX: Logging is an aspect but it's one of the implementation Log4j is an
advice.

Spring Framework has provided the following advice in AOP.

1. Before Advice
2. After Advice
3. After-Returning Advice
4. After-throwing Advice
5. Around Advice
Before Advice:
—---------------
Before Advice will have the Aspect implementation and it will be executed
just before the Business method execution.

To represent Before Advice , Spring Framework has provided a predefined


interface in the form of “org.springframework.aop.MethodBeforeAdvice”.

MethodBeforeAdvice has the following method to execute before executing the


respective business method.

public void before(Method m, Object[] params, Object target)

Where Method is able to provide the complete metadata of a particular


business method.

Where Object[] is able to provide business method parameters.

Where Object is representing a Target object that is the actual Business


Component.

EX:
Public class BeforeAdviceImpl implements MethodBeforeAdvice{
public void before(Method m, Object[] params, Object target){
—---Aspect Implementation—---
}
}

After Advice / After Returning Advice:


—--------------------------------------
It is the same as BeforeAdvice, but it will be executed after executing the
respective Business method.

To represent AfterAdvice, Spring Framework has provided a predefined


interface in the form of “org.springframework.aop.AfterReturningAdvice”.

AfterReturningAdvice has the following method to execute after executing the


Business method.

public void afterReturning(Object returnValue, Object[] args, Object target)

Where Object [First parameter] is representing the return value from the
Business method.
Where Object[] is representing parameters of the Business method.
Where Object [Third parameter] is representing Target object.

public class AfterReturningAdviceImpl implements AfterReturningAdvice{


public void afterReturning(Object returnValue, Object[] args, Object
target){
—--implementation—--
}
}

Note: In Schema based implementation, AfterAdvice and AfterReturningAdvice


are same , but in Annotation based Approach AfterAdvice and
AfterReturningAdvice are different.

ThrowsAdvice / After-Throwing Advice:


—-------------------------------------
This advice will have the aspect implementation , it will be executed when we
get an exception in the Business method.

To represent this advice Spring Framework has provided a predefined interface


in the form of “org.springframework.aop.ThrowsAdvice”.

The above interface has the following method to execute after getting an
Exception.

public void afterThrowing(Method m, Object[] params, Object target, Throwable


t)

Where Method is able to provide metadata of the Business method.


Where Object[] represents Business method parameters.
Where Object is representing a Target object.
Where Throwable represents the exception which we have in the Business
Method.

public class ThrowsAdviceImpl implements ThrowsAdvice{


public void afterThrowing(Method m, Object[] params, Object target,
Throwable t){
—----
}

}
AroundAdvice:
—------------
This advice will be executed before and after the business method execution.

It is the combination of BeforeAdvice and AfterAdvice.

To represent AroundAdvice we have a predefined interface in the form of


“org.aopalliance.intercept.MethodInterceptor”.

The MethodInterceptor interface was provided by a third party organization


named “AOPAlliance” and it is supported by All the AOP implementations like
SPring AOP.

MethodInterceptor has the following method to execute before and after


business methods.

public Object invoke(MethodInvocation mi)throws Throwable

Where MethodInvocation has a proceed() method inorder to execute the Business


method.

public class AroundAdviceImpl implements MethodInterceptor{


public object invoke(MethodInvocation mi)throws Throwable{
—----Before Advice Logic—----
Object returnValue = mi.proceed();
—----After Advice Logic—-----
return returnValue;
}
}

Pointcut:
Pointcut defines at what joinpoint what advice/Advices has/have to be
applied.

If we want to provide Pointcuts in Spring Framework then we must configure


Pointcut and its expressions in the Spring Configuration file.

In Spring Framework there are two types of Pointcuts.

1. Static Pointcut
2. Dynamic Pointcut
Static pointcut:
Static Pointcut defines the advice that is always executed.In Spring
applications we will define static pointcuts on the basis of the business
method and target class.

To represent PointCuts in Spring applications Spring Framework has provided a


predefined interface in the form of “org.springframework.aop.PointCut”.

Spring framework has provided the following implementation classes for the
PointCut interface.

1. NameMatchMethodPointCut
2. Perl5RegexprMethodPointCut
3. JdkRegexMethodPointCut
—----
—----
Dynamic Pointcut:
DynamicPointcut is a pointcut, it will determine if the advice should be
executed or not on the basis of the runtime method arguments.

EX:
1. ControlFlowPointCut
2. DynamicMethodMatcherpointCut

If we want to use Pointcuts in Spring applications then we have to configure


Pointcut and Advisor in the Spring Configuration file.

In Spring Applications, in general we will use “DefaultPointCutAdvisor”


inorder to suggest the advice for the join points.

If we want to use NameMatchMethodPointCut in Spring applications then we have


to use the “mappedNames” property of type array and we must provide business
method names as values to which advice we want to apply.

<bean id=”pointcut”
class=”org.springframework.aop.support.NameMatchMethodPointcut”>
<property name=”mappedNames”>
<array>
<value>deposit</value>
<value>withdraw</value>
<value>transferFunds</value>
</array>
</property>
</bean>

Perl5RegexprMethodPointCut and JdkRegexMethodPointCut are able to provide


advice by matching the provided regular expression to the Business methods;
these pointcuts require the “pattern” property where we must define regular
expression.

<bean id=”pointcut”
class=”org.springframework.aop.support.Perl5RegexmethodPointcut”>
<property name=”pattern”>
<list>
<value>EmployeeService.*</value>
</list>
</property>
</bean>

<bean id=”advisor”
class=”org.springframework.aop.support.DefaultPointcutAdvisor”>
<property name=”pointcut” ref=”pointcut”/>
<property name=”advice” ref=”advice”/>
</bean>

To prepare AOP applications we have to use the following steps.


1. Create Bean components as per the requirements.
2. Create Service Interface and Service class.
3. Create Advice class
4. Prepare Configuration file with the following configurations.
a. Bean configuration
b. Service Class Configuration
c. Advice configuration
d. Pointcut configuration
e. Advisor Configuration
f. Proxy Configuration
5. Create a Test Application and access the business method.
EXample on Before Advice:
Employee.java
package com.durgasoft.beans;

public class Employee {


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.durgasoft.service;

import com.durgasoft.beans.Employee;

public interface EmployeeService {


public void displayEmployee(Employee employee);
}

EmployeeServiceImpl.java
package com.durgasoft.service;

import com.durgasoft.beans.Employee;

public class EmployeeServiceImpl implements EmployeeService{


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

EmployeeValidatorAdvice.java
package com.durgasoft.advices;
import com.durgasoft.beans.Employee;
import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class EmployeeValidatorAdvice implements MethodBeforeAdvice {


@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
Employee employee = (Employee) args[0];
System.out.println("Validation Messages for
"+method.getName());

System.out.println("================================================"
);
int eno = employee.getEno();
if(eno == 0){
System.out.println("Employee Number Is Required");
}else{
if(eno < 100 || eno > 999){
System.out.println("Employee Number Must be 3 digit
number");
}
}
String ename = employee.getEname();
if(ename == null || ename.equals("")){
System.out.println("Employee Name Is Required");
}

float esal = employee.getEsal();


if(esal == 0.0f){
System.out.println("Employee Salary is Required");
}else{
if(esal < 10000.0f){
System.out.println("Employee Salary Must be minimum
10000");
}
}

String eemail = employee.getEemail();


if(eemail == null || eemail.equals("")){
System.out.println("Employee Email Id Is Required");
}else{
if(!eemail.endsWith("@durgasoft.com"))
System.out.println("Invalid Email Id, Hint:
xxxx@durgasoft.com");
}

String emobile = employee.getEmobile();


if(emobile == null || emobile.equals("")){
System.out.println("Employee Mobile Number Is required");
}else{
String[] mobileNo = emobile.split("-");// 91-9988776655
if(!mobileNo[0].equals("91")){
System.out.println("Invalid Mobile Number, Mobile
Number Must be started with 91-");
}
if(mobileNo[1].length() != 10){
System.out.println("Invalid Mobile number, Mobile
number must be a 10 digit number");
}
}
}
}

Main.java
package com.durgasoft;

import com.durgasoft.beans.Employee;
import com.durgasoft.service.EmployeeService;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {


public static void main(String[] args) {
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("SpringConfig.xml");
//EmployeeService employeeService1 = (EmployeeService)
applicationContext.getBean("employeeService");
EmployeeService employeeServiceProxy = (EmployeeService)
applicationContext.getBean("proxy");
Employee employee = (Employee)
applicationContext.getBean("employee");
employeeServiceProxy.displayEmployee(employee);
}
}

SpringConfig.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context

https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="employee" class="com.durgasoft.beans.Employee">
<property name="eno" value="123"/>
<property name="ename" value="Durga"/>
<property name="esal" value="50000"/>
<property name="eemail" value="durga@durgasoft.com"/>
<property name="emobile" value="91-9988776655"/>
</bean>

<!-- Target -->


<bean id="employeeService"
class="com.durgasoft.service.EmployeeServiceImpl"/>

<!-- Advice: Aspect implementation -->


<bean id="validatorAdvice"
class="com.durgasoft.advices.EmployeeValidatorAdvice"/>

<!-- Pointcut: List of Business methods to apply Advices.-->


<bean id="pointcut"
class="org.springframework.aop.support.NameMatchMethodPointcut">
<property name="mappedNames">
<array>
<value>displayEmployee</value>
</array>
</property>
</bean>

<!-- Advisor: Mapping between Advice and Pointcut -->


<bean id="advisor"
class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="validatorAdvice"/>
<property name="pointcut" ref="pointcut"/>
</bean>

<!-- Proxy: Target + Advisors -->


<bean id="proxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="employeeService"/>
<property name="interceptorNames">
<list>
<value>advisor</value>
</list>
</property>
</bean>

</beans>

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.durgasoft</groupId>
<artifactId>springaopapp01</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.8</version>
</dependency>
</dependencies>
</project>

Example on After Advice


—---------------------
Student.java
package com.durgasoft.beans;

public class Student {


private String sname;
private String squal;
private String semail;
private String smobile;
private String saddr;

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

public String getSaddr() {


return saddr;
}

public void setSaddr(String saddr) {


this.saddr = saddr;
}
}

InstituteService.java
package com.durgasoft.service;

import com.durgasoft.beans.Student;

public interface InstituteService {


public void courseEnquiry(Student student, String courseName);
public void courseRegistration(Student student, String
courseName);
}

InstituteServiceImpl.java
package com.durgasoft.service;

import com.durgasoft.beans.Student;

public class InstituteServiceImpl implements InstituteService{

@Override
public void courseEnquiry(Student student, String courseName) {
System.out.println("Student Course Enquiry Details");
System.out.println("---------------------------------");
System.out.println("Student Name :
"+student.getSname());
System.out.println("Student Qualification :
"+student.getSqual());
System.out.println("Student Email Id :
"+student.getSemail());
System.out.println("Student Mobile Number :
"+student.getSmobile());
System.out.println("Student Address :
"+student.getSaddr());
System.out.println("Student Course Name : "+courseName);
}

@Override
public void courseRegistration(Student student, String courseName)
{
System.out.println("Student Course Registration Details");
System.out.println("---------------------------------");
System.out.println("Student Name :
"+student.getSname());
System.out.println("Student Qualification :
"+student.getSqual());
System.out.println("Student Email Id :
"+student.getSemail());
System.out.println("Student Mobile Number :
"+student.getSmobile());
System.out.println("Student Address :
"+student.getSaddr());
System.out.println("Student Course Name : "+courseName);
}
}

ThanQAdvice.java
package com.durgasoft.advices;

import com.durgasoft.beans.Student;
import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class ThanqAdvice implements AfterReturningAdvice {


@Override
public void afterReturning(Object returnValue, Method method,
Object[] args, Object target) throws Throwable {
Student student = (Student) args[0];
String courseName = (String) args[1];

System.out.println("ThanQ "+student.getSname()+" for your


"+method.getName()+" on the Course "+courseName);
System.out.println("Durgasoft Team will be in touch with you
for further Scheduling.");
}
}

Main.java
package com.durgasoft;

import com.durgasoft.beans.Student;
import com.durgasoft.service.InstituteService;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {


public static void main(String[] args) {
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("SpringConfig.xml");
InstituteService instituteService = (InstituteService)
applicationContext.getBean("proxy");
Student student = (Student)
applicationContext.getBean("student");
instituteService.courseEnquiry(student, "JAVA");

System.out.println();

instituteService.courseRegistration(student, "JAVA");

}
}

SpringConfig.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context

https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="student" class="com.durgasoft.beans.Student">
<property name="sname" value="Durga"/>
<property name="squal" value="MTech"/>
<property name="semail" value="durga@durgasoft.com"/>
<property name="smobile" value="91-9988776655"/>
<property name="saddr" value="Hyd"/>
</bean>

<!-- Target -->


<bean id="target"
class="com.durgasoft.service.InstituteServiceImpl"/>

<!-- Advice -->


<bean id="advice" class="com.durgasoft.advices.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>

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.durgasoft</groupId>
<artifactId>springaopapp02</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.8</version>
</dependency>
</dependencies>

</project>

Example on Throws Advice:


Movie.java
package com.durgasoft.beans;

public class Movie {


private String movieName;
private String showTime;
private int price;

public String getMovieName() {


return movieName;
}

public void setMovieName(String movieName) {


this.movieName = movieName;
}

public String getShowTime() {


return showTime;
}

public void setShowTime(String showTime) {


this.showTime = showTime;
}

public int getPrice() {


return price;
}

public void setPrice(int price) {


this.price = price;
}
}

MovieService.java
package com.durgasoft.service;

import com.durgasoft.beans.Movie;

public interface MovieService {


public void playMovie(Movie movie)throws Exception;
}

MovieServiceImpl.java
package com.durgasoft.beans;

import com.durgasoft.service.MovieService;

public class MovieServiceImpl implements MovieService {

@Override
public void playMovie(Movie movie) throws Exception {
System.out.println("Movie "+movie.getMovieName()+" Started at
"+movie.getShowTime());
throw new RuntimeException("Power Failure Occurred");
}
}

MoneyReturnAdvice.java
package com.durgasoft.advices;

import org.springframework.aop.ThrowsAdvice;

import java.lang.reflect.Method;

public class MoneyReturnAdvice implements ThrowsAdvice {


public void afterThrowing(Method method, Object[] params, Object
target, Exception exception){
System.out.println(exception.getMessage()+" , Movie was
Stopped, Please contact to the Theater Manager to get back your
Money");
}
}

Main.java
package com.durgasoft;

import com.durgasoft.beans.Movie;
import com.durgasoft.service.MovieService;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {


public static void main(String[] args){
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("SpringConfig.xml");
MovieService movieService = (MovieService)
applicationContext.getBean("proxy");
Movie movie = (Movie) applicationContext.getBean("movie");
try {
movieService.playMovie(movie);
} catch (Exception e) {

}
}
}

SpringConfig.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context

https://www.springframework.org/schema/context/spring-context.xsd">
<!-- Movie -->
<bean id="movie" class="com.durgasoft.beans.Movie">
<property name="movieName" value="Bahubali"/>
<property name="showTime" value="9:00PM"/>
<property name="price" value="500"/>
</bean>

<!-- Target -->


<bean id="target" class="com.durgasoft.beans.MovieServiceImpl"/>

<!-- Advice -->


<bean id="advice"
class="com.durgasoft.advices.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>

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.durgasoft</groupId>
<artifactId>springaopapp03</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.8</version>
</dependency>
</dependencies>

</project>
Example on AroundAdvice:
Account.java
package com.durgasoft.beans;

public class Account {


private String accNo;
private String accHolderName;
private String accType;
private int balance;

public String getAccNo() {


return accNo;
}

public void setAccNo(String accNo) {


this.accNo = accNo;
}

public String getAccHolderName() {


return accHolderName;
}

public void setAccHolderName(String accHolderName) {


this.accHolderName = accHolderName;
}

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.durgasoft.beans;

public class Cheque {


private String chequeNumber;
private int amount;

public String getChequeNumber() {


return chequeNumber;
}

public void setChequeNumber(String chequeNumber) {


this.chequeNumber = chequeNumber;
}

public int getAmount() {


return amount;
}

public void setAmount(int amount) {


this.amount = amount;
}
}

TransactionService.java
package com.durgasoft.service;

import com.durgasoft.beans.Account;
import com.durgasoft.beans.Cheque;

public interface TransactionService {


public void debit(Account account, Cheque cheque);
}

TransactionServiceImpl.java
package com.durgasoft.service;

import com.durgasoft.beans.Account;
import com.durgasoft.beans.Cheque;
public class TransactionServiceImpl implements TransactionService{

@Override
public void debit(Account account, Cheque cheque) {
System.out.println("**********Transaction START*********");
int initialAmount = account.getBalance();
int debitAmount = cheque.getAmount();
int totalAmount = initialAmount - debitAmount;
account.setBalance(totalAmount);
System.out.println("********Transaction Success*********");
System.out.println("********Amount is debited from
Account*******");
System.out.println("********Transaction END*********");
}
}

ChequeClearenceAdvice.java
package com.durgasoft.advices;

import com.durgasoft.beans.Account;
import com.durgasoft.beans.Cheque;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class ChequeClearenceAdvice implements MethodInterceptor {


@Override
public Object invoke(MethodInvocation invocation) throws Throwable
{
Object[] params = invocation.getArguments();
Account account = (Account) params[0];
Cheque cheque = (Cheque) params[1];

System.out.println("Dear Customer!, a Cheque with the number


"+cheque.getChequeNumber()+" is coming for clarence, please maintain
the proper amount in your account ");
invocation.proceed();
System.out.println("Dear Customer!, the Account Number
"+account.getAccNo()+" has been debited the amount
"+cheque.getAmount()+" in the clerence of the cheque with the cheque
number "+cheque.getChequeNumber()+" Now the total Amount is
"+account.getBalance());
return null;
}
}

Main.java
package com.durgasoft;

import com.durgasoft.beans.Account;
import com.durgasoft.beans.Cheque;
import com.durgasoft.service.TransactionService;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {


public static void main(String[] args) {
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("SpringConfig.xml");
Account account = (Account)
applicationContext.getBean("account");
Cheque cheque = (Cheque) applicationContext.getBean("cheque");

TransactionService transactionService = (TransactionService)


applicationContext.getBean("proxy");
transactionService.debit(account, cheque);

}
}

SpringConfig.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context

https://www.springframework.org/schema/context/spring-context.xsd">
<!-- Beans -->
<bean id="account" class="com.durgasoft.beans.Account">
<property name="accNo" value="abc123"/>
<property name="accHolderName" value="Durga"/>
<property name="accType" value="Savings"/>
<property name="balance" value="50000"/>
</bean>
<bean id="cheque" class="com.durgasoft.beans.Cheque">
<property name="chequeNumber" value="1234556789"/>
<property name="amount" value="10000"/>
</bean>

<!-- target -->


<bean id="target"
class="com.durgasoft.service.TransactionServiceImpl"/>

<!-- Advice -->


<bean id="advice"
class="com.durgasoft.advices.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>

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.durgasoft</groupId>
<artifactId>springaopapp04</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.8</version>
</dependency>
</dependencies>

</project>

AspectJ:
—--------
AspectJ is a language, it is able to represent AOP and it has provided
specialized syntaxes to express concerns.

AspectJ is supported by Spring in the following two approaches.

1. Declarative Approach.
2. @Aspectj annotation style approach.

1. Declarative Approach:
—------------------------
IN declarative approach, we will use a set AOP tags which are provided by
the AOP namespace in the Spring COnfiguration file in order to declare
Aspects, Advices, Pointcuts,.....

SpringConfig.xml
—----------------
<beans ………..
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
—-----
<aop:config>
—-----
</aop:config>
—---
</beans>

Where <aop:config> tag will have all the aspects configuration and all the
specific business methods related configurations like
advice,pointcuts,....

1. Declaring Aspects:
To declare Aspects by using AOP tags we have to use the following tags in
the Spring Configuration file.

<beans …… >
—--
<aop:config>
<aop:aspect id=”--” ref=”---”/>
—---
</aop:config>
—--
</beans>

EX:
<beans>
<bean id=”loggingBean”
class=”com.durgasoft.aspects.EmployeeLoggingBean”/>
<aop:config>
<aop:aspect id=”loggingAspect” ref=”loggingBean”>
—---
</aop:aspect>
</aop:config>

</beans>

2.Declaring Pointcuts:
A pointcut helps in determining the join points to be executed with
different advices.
<beans…..>
<aop:config>
<aop:aspect id=”--” class=”---”>
<aop:pointcut id=”--” expression=”---”/>
—----
</aop:aspect>
</aop:config>
</beans>

EX:
<beans>
<bean id=”loggingBean”
class=”com.durgasoft.aspects.EmployeeLoggingBean”/>
<aop:config>
<aop:aspect id=”loggingAspect” ref=”loggingBean”>
<aop:pointcut id=”logPointcut”
expression=”execution(*
com.durgasoft.service.EmployeeService.*(...))”
/>
</aop:aspect>
</aop:config>

</beans>

Example on pointcut Expressions:


1. execution(* com.durgasoft.service.EmployeeService.*(..))
This expression is able to represent all the business methods which are
available in EmployeeService and having any number of parameters and
having any access modifier and any Return type

2. execution(* EmployeeService.*(..))
This expression is able to represent all the business methods which are
available in EmployeeService in the current package and having any number
of parameters and having any access modifier and any Return type.

3. execution(public * com.durgasoft.service.EmployeeService.*(..)):
This expression is able to represent all the business methods which are
available in EmployeeService , which are declared with public and which
are having any return type and which are having any number of parameters.
4. execution(public Employee com.durgasoft.service.EmployeeService.*(..)):
This expression is able to represent all the business methods which are
having public access modifiers , which are having only Employee return
type and which are having any number of parameters.

5. execution(public Employee
com.durgasoft.service.EmployeeService.*(Employee ,..)):
This expression is able to represent all the business methods of
EmployeeService which are having public access modifiers, which are having
Employee return type and which are having the first parameter is Employee.

6. execution(public Employee EmployeeService.*(Employee, Integer)):


This expression is able to represent all the business methods of the
EmployeeService which are having public access modifier, which are having
the Employee return type, Which are having Employee and Integer
parameters.

3. Declaring Advices:
—--------------------
Spring AspectJ is providing the following five advices.
1. <aop:before>
2. <aop:after>
3. <aop:after-returning>
4. <aop:around>
5. <aop:after-throwing>
In all the above advices, there are two attributes.
1. Method: it will take an advice method name.
2. pointcut-ref: it will take pointcut reference value.

EX:
<beans>
<bean id=”loggingBean”
class=”com.durgasoft.aspects.EmployeeLoggingBean”/>
<aop:config>
<aop:aspect id=”loggingAspect” ref=”loggingBean”>
<aop:pointcut id=”logPointcut”
expression=”execution(*
com.durgasoft.service.EmployeeService.*(...))”
/>
<aop:before method=”logBefore”
pointcut-ref=”logPointcut”/>
<aop:after method=”logAfter”
pointcut-ref=”logPointcut”/>
—--
</aop:aspect>
</aop:config>

</beans>

To prepare Applications by using ASPECTJ then we have to use the following


steps.
1. Declare beans
2. Declare Service interface
3. Declare Service implementation class
4. Declare Aspect class
5. Prepare Spring Configuration File
6. Prepare test Application

EX:
—--
Employee.java
package com.durgasoft.beans;

public class Employee {


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.durgasoft.service;

import com.durgasoft.beans.Employee;

public interface EmployeeService {


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

EmployeeServiceImpl.java
package com.durgasoft.service;

import com.durgasoft.beans.Employee;

public class EmployeeServiceImpl implements EmployeeService{

@Override
public String createEmployee(Employee employee) throws Exception {
System.out.println("Employee "+employee.getEno()+" Inserted
Successfullt from createEmployee() method");
return "SUCCESS";
}

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

@Override
public String updateEmployee(Employee employee) {
System.out.println("Employee "+employee.getEno()+" Updated
Successfully from updateEmployee() method");
return "SUCCESS";
}

@Override
public String deleteEmployee(Employee employee) {
System.out.println("Employee "+employee.getEno()+" Deleted
Successfully");
return "SUCCESS";
}
}

LoggingAspect.java
package com.durgasoft.aspects;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class LoggingAspect {


public void before(org.aspectj.lang.JoinPoint joinPoint){
System.out.println("Before
"+joinPoint.getSignature().getName()+" Method Execution");
}
public void after(org.aspectj.lang.JoinPoint joinPoint){
System.out.println("After
"+joinPoint.getSignature().getName()+" Method Execution");
}
public void afterReturning(org.aspectj.lang.JoinPoint joinPoint,
Object result){
System.out.println("After Returning "+result+" from
"+joinPoint.getSignature().getName()+" Method");
}
public void around(ProceedingJoinPoint proceedingJoinPoint){
System.out.println("Before
"+proceedingJoinPoint.getSignature().getName()+" execution from
AroundAdvice");
try {
proceedingJoinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("After
"+proceedingJoinPoint.getSignature().getName()+" execution from
AroundAdvice");
}
public void afterThrowing(JoinPoint joinPoint, Throwable
throwable){
System.out.println("After Throwing "+throwable+" from
"+joinPoint.getSignature().getName());
}
}

Main.java
package com.durgasoft;

import com.durgasoft.beans.Employee;
import com.durgasoft.service.EmployeeService;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {


public static void main(String[] args) {
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("SpringConfig.xml");
Employee employee = (Employee)
applicationContext.getBean("employee");
EmployeeService employeeService = (EmployeeService)
applicationContext.getBean("employeeService");
/*
String message = "";
try {
message = employeeService.createEmployee(employee);
} catch (Exception e) {

}
System.out.println(message);
*/
//employeeService.searchEmployee(111);

//employeeService.updateEmployee(employee);

}
}

SpringConfig.xml
<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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="employee" class="com.durgasoft.beans.Employee">
<property name="eno" value="111"/>
<property name="ename" value="Durga"/>
<property name="esal" value="50000"/>
<property name="eaddr" value="Hyd"/>
</bean>
<!-- Target -->
<bean id="employeeService"
class="com.durgasoft.service.EmployeeServiceImpl"/>

<!-- Aspect -->


<bean id="loggingAspectBean"
class="com.durgasoft.aspects.LoggingAspect"/>

<aop:config>
<aop:aspect id="loggingAspect" ref="loggingAspectBean">
<aop:pointcut id="employeePointcut"
expression="execution(*
com.durgasoft.service.EmployeeService.*(..))"/>
<aop:before method="before"
pointcut-ref="employeePointcut"/>
<aop:after method="after"
pointcut-ref="employeePointcut"/>
<aop:after-returning method="afterReturning"
pointcut-ref="employeePointcut" returning="result"/>
<aop:around method="around"
pointcut-ref="employeePointcut"/>
<aop:after-throwing method="afterThrowing"
pointcut-ref="employeePointcut" throwing="throwable"/>
</aop:aspect>

</aop:config>
</beans>

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.durgasoft</groupId>
<artifactId>springaopapp05</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.9</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectj-tools</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.19</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.19</version>
</dependency>

</dependencies>

</project>

@AspectJ Annotations Style Approach:


—-------------------------------
Spring Framework Supporting annotations to support AspectJ implementations
in the form of “org.aspectj.annotation” package.

Spring AspectJ AOP implementation provides the following annotations.

1. @Aspect
2. @Pointcut
3. @Before
4. @After
5. @AfterReturning
6. @Around
7. @AfterThrowing

Note: To activate all the AOP AspectJ annotations in spring applications


we have to use the following tag in the Spring configuration file.

<aop:aspectj-autoproxy/>

EX:
Account.java
package com.durgasoft.beans;

public class Account {


private String accNo;
private String accHolderName;
private String accType;
private double balance;

public String getAccNo() {


return accNo;
}

public void setAccNo(String accNo) {


this.accNo = accNo;
}

public String getAccHolderName() {


return accHolderName;
}

public void setAccHolderName(String accHolderName) {


this.accHolderName = accHolderName;
}

public String getAccType() {


return accType;
}

public void setAccType(String accType) {


this.accType = accType;
}

public double getBalance() {


return balance;
}

public void setBalance(double balance) {


this.balance = balance;
}
}

TransactionService.java
package com.durgasoft.service;

import com.durgasoft.beans.Account;
import com.durgasoft.exceptions.InsufficientFundsException;

public interface TransactionService {


public String withdraw(Account account, int withdrawAmount)throws
InsufficientFundsException;
}

TransactionServiceImpl.java
package com.durgasoft.service;

import com.durgasoft.beans.Account;
import com.durgasoft.exceptions.InsufficientFundsException;

public class TransactionServiceImpl implements TransactionService{

@Override
public String withdraw(Account account, int withdrawAmount) throws
InsufficientFundsException {
System.out.println("from withdraw() method , Transaction
Started");
String status = "";
if(account.getBalance() > withdrawAmount){
double totalbalance = account.getBalance() -
withdrawAmount;
account.setBalance(totalbalance);
System.out.println("From withdraw() method, transaction
Completed");
status = "SUCCESS";
}else{
status = "FAILURE";
throw new InsufficientFundsException("Funds Are Not
Sufficient in Your Account");
}
return status;
}
}

InsufficientFundsException.java
package com.durgasoft.exceptions;

public class InsufficientFundsException extends Exception{


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

TransactionAspect.java
package com.durgasoft.aspects;

import com.durgasoft.beans.Account;
import com.durgasoft.exceptions.InsufficientFundsException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

@Aspect
public class TransactionAspect {
@Before("execution(*
com.durgasoft.service.TransactionService.*(..))")
public void before(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
Account account = (Account) args[0];
System.out.println("Before Advice : Initial Balance :
"+account.getBalance());
}
@After("execution(*
com.durgasoft.service.TransactionService.*(..))")
public void after(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
Account account = (Account) args[0];
System.out.println("After Advice : Total Balance :
"+account.getBalance());
}
@AfterReturning(pointcut = "execution(*
com.durgasoft.service.TransactionService.*(..))", returning =
"results")
public void afterReturning(JoinPoint joinPoint, String results){
Object[] args = joinPoint.getArgs();
Account account = (Account) args[0];
System.out.println("After Returning Advice : Transaction
Status : "+results);
}

@Around("execution(*
com.durgasoft.service.TransactionService.*(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("Around Advice : Before
"+proceedingJoinPoint.getSignature().getName()+" Method Execution");
String status = "";
try {
status = (String) proceedingJoinPoint.proceed();
} catch (Throwable e) {

}
System.out.println("Around Advice : After : Transaction Status
: "+status);
}
@AfterThrowing(pointcut = "execution(*
com.durgasoft.service.TransactionService.*(..))", throwing =
"exception")
public void afterThrowing(JoinPoint joinPoint,
InsufficientFundsException exception){

System.out.println("After Throwing Advice : Exception :


"+exception.getClass().getName()+" In the Transaction :
"+exception.getMessage());
}

Main.java
package com.durgasoft;

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

public class Main {


public static void main(String[] args) {
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("SpringConfig.xml");
Account account = (Account)
applicationContext.getBean("account");
TransactionService transactionService = (TransactionService)
applicationContext.getBean("transactionService");
try {
transactionService.withdraw(account, 50000);
} catch (InsufficientFundsException e) {

}
}
}

SpringConfig.xml
<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/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
http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd">

<aop:aspectj-autoproxy/>
<bean id="account" class="com.durgasoft.beans.Account">
<property name="accNo" value="abc123"/>
<property name="accHolderName" value="Durga"/>
<property name="accType" value="Savings"/>
<property name="balance" value="25000"/>
</bean>
<bean id="transactionService"
class="com.durgasoft.service.TransactionServiceImpl"/>
<bean id="transactionAspect"
class="com.durgasoft.aspects.TransactionAspect"/>
</beans>

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.durgasoft</groupId>
<artifactId>springaopapp06</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.9</version>
</dependency>

<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectj-tools</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.19</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.19</version>
</dependency>
</dependencies>

</project>

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

You might also like