AOP

1. Dependency:


// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop
implementation 'org.springframework.boot:spring-boot-starter-aop:3.2.2'

 

2. MyLogic:

package com.luv2code.aopdemo.dao;

public interface AccountDao {

void addAccount();

}


package com.luv2code.aopdemo.dao;

import org.springframework.stereotype.Repository;

@Repository
public class AccountDaoImpl implements AccountDao {

@Override
public void addAccount() {
System.out.println(getClass() + " : Doing my DB work: adding ac account");
}

}


3. Aspect itself:

package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyDemoLoggingAspect {

@Before("execution(public void addAccount())")
public void beforeAddAccountAdvice() {
System.out.println("======>>> Executing @Before advice on addAccount()");
}

}


--------------------------------------------------------------------------------------------------------------------------------

                                                                Pointcut

Pointcut: A predicate expression for where advice should be applied

package com.luv2code.aopdemo.dao;

public interface MembershipDao {

void addAccount();

}


package com.luv2code.aopdemo.dao;

import org.springframework.stereotype.Repository;

@Repository
public class MembershipDaoImpl implements MembershipDao {

@Override
public void addAccount() {
System.out.println(getClass() + " : Doing my DB work: adding a membership account");
}

}


package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyDemoLoggingAspect {

@Before("execution(public void addAccount())")
public void beforeAddAccountAdvice() {
System.out.println("======>>> Executing @Before advice on addAccount()");
}

}


---now let's put pointcut

package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyDemoLoggingAspect {

@Before("execution(public void com.luv2code.aopdemo.dao.AccountDao.addAccount())")
public void beforeAddAccountAdvice() {
System.out.println("======>>> Executing @Before advice on addAccount()");
}

}


--- pointcut with wildcards:

package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyDemoLoggingAspect {

@Before("execution(public void add*())")
public void beforeAddAccountAdvice() {
System.out.println("======>>> Executing @Before advice on addAccount()");
}

}

---

package com.luv2code.aopdemo.dao;

public interface MembershipDao {

boolean addSillyMember();

}


package com.luv2code.aopdemo.dao;

import org.springframework.stereotype.Repository;

@Repository
public class MembershipDaoImpl implements MembershipDao {

@Override
public boolean addSillyMember() {
System.out.println(getClass() + " : Doing my DB work: adding a membership account");
return true;
}

}


package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyDemoLoggingAspect {

@Before("execution(* add*())")
public void beforeAddAccountAdvice() {
System.out.println("======>>> Executing @Before advice on addAccount()");
}

}


--------------------------------------------------------------------------------------------------------------------------------

                                                             Parameter Pattern Wildcard

() - matches a method with no arguments

(*) - matches a method with one argument of any type

(..) - matches a method with 0 or more arguments of any type


package com.luv2code.aopdemo.dao;

import lombok.Data;

@Data
public class Account {

private String name;
private String level;

}


package com.luv2code.aopdemo.dao;

public interface AccountDao {

void addAccount(Account account);

}


package com.luv2code.aopdemo.dao;

import org.springframework.stereotype.Repository;

@Repository
public class AccountDaoImpl implements AccountDao {

@Override
public void addAccount(Account account) {
System.out.println(getClass() + " : Doing my DB work: adding ac account");
}

}


package com.luv2code.aopdemo;

import com.luv2code.aopdemo.dao.Account;
import com.luv2code.aopdemo.dao.AccountDao;
import com.luv2code.aopdemo.dao.MembershipDao;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@RequiredArgsConstructor
public class AopdemoApplication implements CommandLineRunner {

private final AccountDao accountDao;
private final MembershipDao membershipDao;

public static void main(String[] args) {
SpringApplication.run(AopdemoApplication.class, args);
}

@Override
public void run(String... args) throws Exception {
demoTheBeforeAdvice(accountDao, membershipDao);
}

private void demoTheBeforeAdvice(AccountDao accountDao, MembershipDao membershipDao) {
Account account = new Account();
accountDao.addAccount(account);
membershipDao.addSillyMember();
}

}


package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyDemoLoggingAspect {

@Before("execution(* add*(com.luv2code.aopdemo.dao.Account))")
public void beforeAddAccountAdvice() {
System.out.println("======>>> Executing @Before advice on addAccount()");
}

}


-- Match any method in a Package:

package com.luv2code.aopdemo.dao;

import lombok.Data;

@Data
public class Account {

private String name;
private String level;

}


package com.luv2code.aopdemo.dao;

public interface AccountDao {

void addAccount(Account account, boolean vipFlag);

boolean doWork();
}


package com.luv2code.aopdemo.dao;

import org.springframework.stereotype.Repository;

@Repository
public class AccountDaoImpl implements AccountDao {

@Override
public void addAccount(Account account, boolean vipFlag) {
System.out.println(getClass() + " : Doing my DB work: adding an account");
}

@Override
public boolean doWork() {
System.out.println(getClass() + " : Do work");
return false;
}

}


package com.luv2code.aopdemo.dao;

public interface MembershipDao {

boolean addSillyMember();

void goToSleep();
}


package com.luv2code.aopdemo.dao;

import org.springframework.stereotype.Repository;

@Repository
public class MembershipDaoImpl implements MembershipDao {

@Override
public boolean addSillyMember() {
System.out.println(getClass() + " : Doing my DB work: adding a membership account");
return true;
}

@Override
public void goToSleep() {
System.out.println(getClass() + " : I'm going to sleep now...");
}

}


package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyDemoLoggingAspect {

@Before("execution(* com.luv2code.aopdemo.dao.*.*(..))")
public void beforeAddAccountAdvice() {
System.out.println("======>>> Executing @Before advice on addAccount()");
}

}


package com.luv2code.aopdemo;

import com.luv2code.aopdemo.dao.Account;
import com.luv2code.aopdemo.dao.AccountDao;
import com.luv2code.aopdemo.dao.MembershipDao;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@RequiredArgsConstructor
public class AopdemoApplication implements CommandLineRunner {

private final AccountDao accountDao;
private final MembershipDao membershipDao;

public static void main(String[] args) {
SpringApplication.run(AopdemoApplication.class, args);
}

@Override
public void run(String... args) throws Exception {
demoTheBeforeAdvice(accountDao, membershipDao);
}

private void demoTheBeforeAdvice(AccountDao accountDao, MembershipDao membershipDao) {
// call the business method
Account account = new Account();
accountDao.addAccount(account, true);
accountDao.doWork();

// call the membership business method
membershipDao.addSillyMember();
membershipDao.goToSleep();
}

}


--------------------------------------------------------------------------------------------------------------------------------

                                                                Pointcut Declaration

package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyDemoLoggingAspect {

@Pointcut("execution(* com.luv2code.aopdemo.dao.*.*(..))")
private void forDaoPackage() {}

@Before("forDaoPackage()")
public void beforeAddAccountAdvice() {
System.out.println("======>>> Executing @Before advice on addAccount()");
}

}


---

package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyDemoLoggingAspect {

@Pointcut("execution(* com.luv2code.aopdemo.dao.*.*(..))")
private void forDaoPackage() {}

@Before("forDaoPackage()")
public void beforeAddAccountAdvice() {
System.out.println("======>>> Executing @Before advice on addAccount()");
}

@Before("forDaoPackage()")
public void performApiAnalytics() {
System.out.println("======>>> Performing API analytics");
}

}


--- Combining pointcuts

package com.luv2code.aopdemo.dao;

public interface AccountDao {

void addAccount(Account account, boolean vipFlag);

boolean doWork();

String getName();

void setName(String name);

String getServiceCode();

void setServiceCode(String serviceCode);

}


package com.luv2code.aopdemo.dao;

import lombok.Data;
import org.springframework.stereotype.Repository;

@Repository
public class AccountDaoImpl implements AccountDao {

private String name;
private String serviceCode;

public String getName() {
System.out.println(getClass() + " : in getName()");
return name;
}

public void setName(String name) {
System.out.println(getClass() + " : in setName()");
this.name = name;
}

public String getServiceCode() {
System.out.println(getClass() + " : in getServiceCode()");
return serviceCode;
}

public void setServiceCode(String serviceCode) {
System.out.println(getClass() + " : in setServiceCode()");
this.serviceCode = serviceCode;
}

@Override
public void addAccount(Account account, boolean vipFlag) {
System.out.println(getClass() + " : Doing my DB work: adding an account");
}

@Override
public boolean doWork() {
System.out.println(getClass() + " : Do work");
return false;
}

}


package com.luv2code.aopdemo.dao;

public interface MembershipDao {

boolean addSillyMember();

void goToSleep();
}


package com.luv2code.aopdemo.dao;

import org.springframework.stereotype.Repository;

@Repository
public class MembershipDaoImpl implements MembershipDao {

@Override
public boolean addSillyMember() {
System.out.println(getClass() + " : Doing my DB work: adding a membership account");
return true;
}

@Override
public void goToSleep() {
System.out.println(getClass() + " : I'm going to sleep now...");
}

}


package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyDemoLoggingAspect {

@Pointcut("execution(* com.luv2code.aopdemo.dao.*.*(..))")
private void forDaoPackage() {
}

// create a pointcut for getter methods
@Pointcut("execution(* com.luv2code.aopdemo.dao.*.get*(..))")
private void getter() {
}

// create a pointcut for setter methods
@Pointcut("execution(* com.luv2code.aopdemo.dao.*.set*(..))")
private void setter() {
}

// create a pointcut include / exclude getter/setter
@Pointcut("forDaoPackage() && !(getter() || setter())")
private void forDaoPackageNoGetterSetter() {
}

@Before("forDaoPackageNoGetterSetter()")
public void beforeAddAccountAdvice() {
System.out.println("======>>> Executing @Before advice on addAccount()");
}

@Before("forDaoPackageNoGetterSetter()")
public void performApiAnalytics() {
System.out.println("======>>> Performing API analytics");
}

}


package com.luv2code.aopdemo;

import com.luv2code.aopdemo.dao.Account;
import com.luv2code.aopdemo.dao.AccountDao;
import com.luv2code.aopdemo.dao.MembershipDao;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@RequiredArgsConstructor
public class AopdemoApplication implements CommandLineRunner {

private final AccountDao accountDao;
private final MembershipDao membershipDao;

public static void main(String[] args) {
SpringApplication.run(AopdemoApplication.class, args);
}

@Override
public void run(String... args) throws Exception {
demoTheBeforeAdvice(accountDao, membershipDao);
}

private void demoTheBeforeAdvice(AccountDao accountDao, MembershipDao membershipDao) {
// call the business method
Account account = new Account();
accountDao.addAccount(account, true);
accountDao.doWork();

//call the accountdao getter/setter methods
accountDao.setName("foobar");
accountDao.setServiceCode("silver");

String name = accountDao.getName();
String code = accountDao.getServiceCode();

// call the membership business method
membershipDao.addSillyMember();
membershipDao.goToSleep();
}

}


--------------------------------------------------------------------------------------------------------------------------------

                                                                Aspect Ordering

package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
public class LuvAopExpressions {

@Pointcut("execution(* com.luv2code.aopdemo.dao.*.*(..))")
public void forDaoPackage() {
}

// create a pointcut for getter methods
@Pointcut("execution(* com.luv2code.aopdemo.dao.*.get*(..))")
public void getter() {
}

// create a pointcut for setter methods
@Pointcut("execution(* com.luv2code.aopdemo.dao.*.set*(..))")
public void setter() {
}

// create a pointcut include / exclude getter/setter
@Pointcut("forDaoPackage() && !(getter() || setter())")
public void forDaoPackageNoGetterSetter() {
}

}


package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Order(3)
@Component
public class MyApiAnalyticsAspect {

@Before("com.luv2code.aopdemo.aspect.LuvAopExpressions.forDaoPackageNoGetterSetter()")
public void performApiAnalytics() {
System.out.println("======>>> Performing API analytics");
}

}


package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Order(1)
@Component
public class MyCloudLogAsyncAspect {

@Before("com.luv2code.aopdemo.aspect.LuvAopExpressions.forDaoPackageNoGetterSetter()")
public void logToCloudAsync() {
System.out.println("======>>> Logging to cloud in async fashion");
}

}


package com.luv2code.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Order(2)
@Component
public class MyDemoLoggingAspect {

@Before("com.luv2code.aopdemo.aspect.LuvAopExpressions.forDaoPackageNoGetterSetter()")
public void beforeAddAccountAdvice() {
System.out.println("======>>> Executing @Before advice on addAccount()");
}

}


--------------------------------------------------------------------------------------------------------------------------------

                                                        Read method arguments with JoinPoints

package com.luv2code.aopdemo.aspect;

import com.luv2code.aopdemo.dao.Account;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Order(2)
@Component
public class MyDemoLoggingAspect {

@Before("com.luv2code.aopdemo.aspect.LuvAopExpressions.forDaoPackageNoGetterSetter()")
public void beforeAddAccountAdvice(JoinPoint joinPoint) {
System.out.println("======>>> Executing @Before advice on addAccount()");

// display the method signature
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
System.out.println("Method signature : " + methodSignature);

// display method arguments
Object[] args = joinPoint.getArgs();
for (Object a : args) {
System.out.println(a);
if (a instanceof Account) {
Account account = (Account) a;
System.out.println("account name: " + account.getName());
System.out.println("account level: " + account.getLevel());
}
}
}

}


--------------------------------------------------------------------------------------------------------------------------------

                                                        @AfterReturning Advice


package com.luv2code.aopdemo.aspect;

import com.luv2code.aopdemo.dao.Account;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.List;

@Aspect
@Order(2)
@Component
public class MyDemoLoggingAspect {

// add a new advice for @AfterReturning on the findAccounts method

@AfterReturning(pointcut = "execution(* com.luv2code.aopdemo.dao.AccountDao.findAccounts(..))", returning = "result")
public void afterReturningFindAccountsAdvice(JoinPoint joinPoint, List<Account> result) {
// print out which method are advising on
String method = joinPoint.getSignature().toShortString();
System.out.println("============>>>>>>>>> Executing @AfterReturning on method: " + method);

// print out the result of the method call
System.out.println("============>>>>>>>>> result is: " + result);
}

@Before("com.luv2code.aopdemo.aspect.LuvAopExpressions.forDaoPackageNoGetterSetter()")
public void beforeAddAccountAdvice(JoinPoint joinPoint) {
System.out.println("======>>> Executing @Before advice on addAccount()");

// display the method signature
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
System.out.println("Method signature : " + methodSignature);

// display method arguments
Object[] args = joinPoint.getArgs();
for (Object a : args) {
System.out.println(a);
if (a instanceof Account) {
Account account = (Account) a;
System.out.println("account name: " + account.getName());
System.out.println("account level: " + account.getLevel());
}
}
}

}


package com.luv2code.aopdemo;

import com.luv2code.aopdemo.dao.Account;
import com.luv2code.aopdemo.dao.AccountDao;
import com.luv2code.aopdemo.dao.MembershipDao;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.List;

@SpringBootApplication
@RequiredArgsConstructor
public class AopdemoApplication implements CommandLineRunner {

private final AccountDao accountDao;
private final MembershipDao membershipDao;

public static void main(String[] args) {
SpringApplication.run(AopdemoApplication.class, args);
}

@Override
public void run(String... args) throws Exception {
// demoTheBeforeAdvice(accountDao, membershipDao);
demoTheAfterAdvice(accountDao);
}

private void demoTheBeforeAdvice(AccountDao accountDao, MembershipDao membershipDao) {
// call the business method
Account account = new Account();
account.setName("Private account");
account.setLevel("Highest level");
accountDao.addAccount(account, true);
accountDao.doWork();

//call the accountdao getter/setter methods
accountDao.setName("foobar");
accountDao.setServiceCode("silver");

String name = accountDao.getName();
String code = accountDao.getServiceCode();

// call the membership business method
membershipDao.addSillyMember();
membershipDao.goToSleep();
}

private void demoTheAfterAdvice(AccountDao accountDao) {
List<Account> accounts = accountDao.findAccounts();
System.out.println("-------------- demoTheAfterAdvice method start");
System.out.println(accounts);
System.out.println("-------------- demoTheAfterAdvice method finish");
}

}


---- Modify data

package com.luv2code.aopdemo.aspect;

import com.luv2code.aopdemo.dao.Account;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.List;

@Aspect
@Order(2)
@Component
public class MyDemoLoggingAspect {

// add a new advice for @AfterReturning on the findAccounts method

@AfterReturning(pointcut = "execution(* com.luv2code.aopdemo.dao.AccountDao.findAccounts(..))", returning = "result")
public void afterReturningFindAccountsAdvice(JoinPoint joinPoint, List<Account> result) {
// print out which method are advising on
String method = joinPoint.getSignature().toShortString();
System.out.println("============>>>>>>>>> Executing @AfterReturning on method: " + method);

// print out the result of the method call
System.out.println("============>>>>>>>>> result is: " + result);

// let's post process the data
convertAccountNamesToUpperCase(result);
}

private void convertAccountNamesToUpperCase(List<Account> accounts) {
for (Account account : accounts) {
account.setName(account.getName().toUpperCase());
}
}

@Before("com.luv2code.aopdemo.aspect.LuvAopExpressions.forDaoPackageNoGetterSetter()")
public void beforeAddAccountAdvice(JoinPoint joinPoint) {
System.out.println("======>>> Executing @Before advice on addAccount()");

// display the method signature
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
System.out.println("Method signature : " + methodSignature);

// display method arguments
Object[] args = joinPoint.getArgs();
for (Object a : args) {
System.out.println(a);
if (a instanceof Account) {
Account account = (Account) a;
System.out.println("account name: " + account.getName());
System.out.println("account level: " + account.getLevel());
}
}
}

}


--------------------------------------------------------------------------------------------------------------------------------

                                                                @AfterThrowing Advice

package com.luv2code.aopdemo.dao;

import java.util.List;

public interface AccountDao {

List<Account> findAccounts();

List<Account> findAccounts(boolean tripWire);

void addAccount(Account account, boolean vipFlag);

boolean doWork();

String getName();

void setName(String name);

String getServiceCode();

void setServiceCode(String serviceCode);

}


package com.luv2code.aopdemo.dao;

import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class AccountDaoImpl implements AccountDao {

private String name;
private String serviceCode;

public String getName() {
System.out.println(getClass() + " : in getName()");
return name;
}

public void setName(String name) {
System.out.println(getClass() + " : in setName()");
this.name = name;
}

public String getServiceCode() {
System.out.println(getClass() + " : in getServiceCode()");
return serviceCode;
}

public void setServiceCode(String serviceCode) {
System.out.println(getClass() + " : in setServiceCode()");
this.serviceCode = serviceCode;
}

@Override
public List<Account> findAccounts() {
return findAccounts(false);
}

@Override
public List<Account> findAccounts(boolean tripWire) {
if (tripWire)
throw new RuntimeException("Something went wrong");

return List.of(new Account("John", "Silver"),
new Account("Madhu", "Platinum"),
new Account("Luca", "Gold"));
}

@Override
public void addAccount(Account account, boolean vipFlag) {
System.out.println(getClass() + " : Doing my DB work: adding an account");
}

@Override
public boolean doWork() {
System.out.println(getClass() + " : Do work");
return false;
}

}


package com.luv2code.aopdemo.aspect;

import com.luv2code.aopdemo.dao.Account;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.List;

@Aspect
@Order(2)
@Component
public class MyDemoLoggingAspect {

@AfterThrowing(pointcut = "execution(* com.luv2code.aopdemo.dao.AccountDao.findAccounts(..))", throwing = "ex")
public void afterThrowingFindAccountsAdvice(JoinPoint joinPoint, Throwable ex) {
// print out which method we are advising on
String method = joinPoint.getSignature().toShortString();
System.out.println("===========>>>>>> Executing @AfterThrowing on method: " + method);

// log the execution
System.out.println("===========>>>>>> Exception is : " + ex);
}

@AfterReturning(pointcut = "execution(* com.luv2code.aopdemo.dao.AccountDao.findAccounts(..))", returning = "result")
public void afterReturningFindAccountsAdvice(JoinPoint joinPoint, List<Account> result) {
// print out which method are advising on
String method = joinPoint.getSignature().toShortString();
System.out.println("============>>>>>>>>> Executing @AfterReturning on method: " + method);

// print out the result of the method call
System.out.println("============>>>>>>>>> result is: " + result);

// let's post process the data
convertAccountNamesToUpperCase(result);
}

private void convertAccountNamesToUpperCase(List<Account> accounts) {
for (Account account : accounts) {
account.setName(account.getName().toUpperCase());
}
}

@Before("com.luv2code.aopdemo.aspect.LuvAopExpressions.forDaoPackageNoGetterSetter()")
public void beforeAddAccountAdvice(JoinPoint joinPoint) {
System.out.println("======>>> Executing @Before advice on addAccount()");

// display the method signature
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
System.out.println("Method signature : " + methodSignature);

// display method arguments
Object[] args = joinPoint.getArgs();
for (Object a : args) {
System.out.println(a);
if (a instanceof Account) {
Account account = (Account) a;
System.out.println("account name: " + account.getName());
System.out.println("account level: " + account.getLevel());
}
}
}

}


--------------------------------------------------------------------------------------------------------------------------------

                                                                        @After

package com.luv2code.aopdemo.aspect;

import com.luv2code.aopdemo.dao.Account;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.List;

@Aspect
@Order(2)
@Component
public class MyDemoLoggingAspect {

@After("execution(* com.luv2code.aopdemo.dao.AccountDao.findAccounts(..))")
public void afterFinallyFindAccountsAdvice(JoinPoint joinPoint) {
// print out which method we are advising on
String method = joinPoint.getSignature().toShortString();
System.out.println("===========>>>>>> Executing @After (finally) on method: " + method);
}

@AfterThrowing(pointcut = "execution(* com.luv2code.aopdemo.dao.AccountDao.findAccounts(..))", throwing = "ex")
public void afterThrowingFindAccountsAdvice(JoinPoint joinPoint, Throwable ex) {
// print out which method we are advising on
String method = joinPoint.getSignature().toShortString();
System.out.println("===========>>>>>> Executing @AfterThrowing on method: " + method);

// log the execution
System.out.println("===========>>>>>> Exception is : " + ex);
}

@AfterReturning(pointcut = "execution(* com.luv2code.aopdemo.dao.AccountDao.findAccounts(..))", returning = "result")
public void afterReturningFindAccountsAdvice(JoinPoint joinPoint, List<Account> result) {
// print out which method are advising on
String method = joinPoint.getSignature().toShortString();
System.out.println("============>>>>>>>>> Executing @AfterReturning on method: " + method);

// print out the result of the method call
System.out.println("============>>>>>>>>> result is: " + result);

// let's post process the data
convertAccountNamesToUpperCase(result);
}

private void convertAccountNamesToUpperCase(List<Account> accounts) {
for (Account account : accounts) {
account.setName(account.getName().toUpperCase());
}
}

@Before("com.luv2code.aopdemo.aspect.LuvAopExpressions.forDaoPackageNoGetterSetter()")
public void beforeAddAccountAdvice(JoinPoint joinPoint) {
System.out.println("======>>> Executing @Before advice on addAccount()");

// display the method signature
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
System.out.println("Method signature : " + methodSignature);

// display method arguments
Object[] args = joinPoint.getArgs();
for (Object a : args) {
System.out.println(a);
if (a instanceof Account) {
Account account = (Account) a;
System.out.println("account name: " + account.getName());
System.out.println("account level: " + account.getLevel());
}
}
}

}


--------------------------------------------------------------------------------------------------------------------------------

                                                                        @Around advice
























--------------------------------------------------------------------------------------------------------------------------------

package az.azerconnect.sales.salesprocess.aop;

import az.azerconnect.sales.salesprocess.model.OfferChangeFail;
import az.azerconnect.sales.salesprocess.service.OfferChangeFailService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

import static az.azerconnect.sales.salesprocess.constants.ApplicationConstants.TRACK_ID;
import static az.azerconnect.sales.salesprocess.dto.enums.FailTypeEnum.SALE_NEW_NUMBER_CHECK_IN_FAIL;
import static az.azerconnect.sales.salesprocess.dto.enums.FailTypeEnum.SALE_NEW_NUMBER_FINALIZE_FAIL;
import static az.azerconnect.sales.salesprocess.dto.enums.FailTypeEnum.TRANSFER_OWNERSHIP_CHECK_IN_FAIL;
import static az.azerconnect.sales.salesprocess.dto.enums.FailTypeEnum.TRANSFER_OWNERSHIP_FINALIZE_FAIL;

@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class FailAOP {

private final OfferChangeFailService offerChangeFailService;

@AfterThrowing(
value = "execution(* az.azerconnect.sales.salesprocess.service.impl.SalesProcessServiceImpl.checkIn(..))",
throwing = "ex")
public void afterThrowingCheckInNewNumberException(JoinPoint joinPoint, Exception ex) {
log.info("ms-sales-process.FailAOP.afterThrowingCheckInNewNumberException start");
OfferChangeFail offerChangeFail = new OfferChangeFail();
offerChangeFail.setReason(ex.getMessage());
offerChangeFail.setOperationType(SALE_NEW_NUMBER_CHECK_IN_FAIL);
offerChangeFail.setTrackId(MDC.get(TRACK_ID));
offerChangeFail.setData(joinPoint.getArgs()[3]);
offerChangeFailService.save(offerChangeFail);
log.info("ms-sales-process.FailAOP.afterThrowingCheckInNewNumberException finish");
}

@AfterThrowing(
value = "execution(* az.azerconnect.sales.salesprocess.service.impl.SalesProcessServiceImpl.formalize(..))",
throwing = "ex")
public void afterThrowingFinalizeNewNumberException(JoinPoint joinPoint, Exception ex) {
log.info("ms-sales-process.FailAOP.afterThrowingFinalizeNewNumberException start");
OfferChangeFail offerChangeFail = new OfferChangeFail();
offerChangeFail.setReason(ex.getMessage());
offerChangeFail.setOperationType(SALE_NEW_NUMBER_FINALIZE_FAIL);
offerChangeFail.setTrackId(MDC.get(TRACK_ID));
offerChangeFail.setData(joinPoint.getArgs()[3]);
offerChangeFailService.save(offerChangeFail);
log.info("ms-sales-process.FailAOP.afterThrowingFinalizeNewNumberException finish");
}

@AfterThrowing(
value = "execution(* az.azerconnect.sales.salesprocess.service.impl.TransferOwnershipServiceImpl.checkIn(..))",
throwing = "ex")
public void afterThrowingCheckInTransferOwnershipException(JoinPoint joinPoint, Exception ex) {
log.info("ms-sales-process.FailAOP.afterThrowingCheckInTransferOwnershipException start");
OfferChangeFail offerChangeFail = new OfferChangeFail();
offerChangeFail.setReason(ex.getMessage());
offerChangeFail.setOperationType(TRANSFER_OWNERSHIP_CHECK_IN_FAIL);
offerChangeFail.setTrackId(MDC.get(TRACK_ID));
offerChangeFail.setData(joinPoint.getArgs()[3]);
offerChangeFailService.save(offerChangeFail);
log.info("ms-sales-process.FailAOP.afterThrowingCheckInTransferOwnershipException finish");
}

@AfterThrowing(
value = "execution(* az.azerconnect.sales.salesprocess.service.impl.TransferOwnershipServiceImpl.finalize(..))",
throwing = "ex")
public void afterThrowingFinalizeTransferOwnershipException(JoinPoint joinPoint, Exception ex) {
log.info("ms-sales-process.FailAOP.afterThrowingFinalizeTransferOwnershipException start");
OfferChangeFail offerChangeFail = new OfferChangeFail();
offerChangeFail.setReason(ex.getMessage());
offerChangeFail.setOperationType(TRANSFER_OWNERSHIP_FINALIZE_FAIL);
offerChangeFail.setTrackId(MDC.get(TRACK_ID));
offerChangeFail.setData(joinPoint.getArgs()[1]);
offerChangeFailService.save(offerChangeFail);
log.info("ms-sales-process.FailAOP.afterThrowingFinalizeTransferOwnershipException finish");
}

}


---

package az.azerconnect.sales.salesprocess.aop;

import az.azerconnect.sales.salesprocess.model.OfferChangeFail;
import az.azerconnect.sales.salesprocess.service.OfferChangeFailService;
import az.azerconnect.sales.salesprocess.service.impl.SalesProcessServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

import static az.azerconnect.sales.salesprocess.constants.ApplicationConstants.TRACK_ID;
import static az.azerconnect.sales.salesprocess.dto.enums.FailTypeEnum.SALE_NEW_NUMBER_CHECK_IN_FAIL;
import static az.azerconnect.sales.salesprocess.dto.enums.FailTypeEnum.SALE_NEW_NUMBER_FINALIZE_FAIL;
import static az.azerconnect.sales.salesprocess.dto.enums.FailTypeEnum.TRANSFER_OWNERSHIP_CHECK_IN_FAIL;
import static az.azerconnect.sales.salesprocess.dto.enums.FailTypeEnum.TRANSFER_OWNERSHIP_FINALIZE_FAIL;

@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class FailAOP {

private final OfferChangeFailService offerChangeFailService;

@AfterThrowing(
value = "execution(* az.azerconnect.sales.salesprocess.service.impl.SalesProcessServiceImpl.checkIn(..)) || " +
"execution(* az.azerconnect.sales.salesprocess.service.impl.SalesProcessServiceImpl.formalize(..)) || " +
"execution(* az.azerconnect.sales.salesprocess.service.impl.TransferOwnershipServiceImpl.checkIn(..)) || " +
"execution(* az.azerconnect.sales.salesprocess.service.impl.TransferOwnershipServiceImpl.finalize(..))",
throwing = "ex")
public void afterThrowingException(JoinPoint joinPoint, Exception ex) {
log.info("ms-sales-process.FailAOP.afterThrowingException start");
OfferChangeFail offerChangeFail = new OfferChangeFail();
offerChangeFail.setReason(ex.getMessage());
offerChangeFail.setTrackId(MDC.get(TRACK_ID));
if (joinPoint.getSignature().toShortString().contains("checkIn")) {
offerChangeFail.setOperationType(joinPoint.getTarget().getClass() == SalesProcessServiceImpl.class ?
SALE_NEW_NUMBER_CHECK_IN_FAIL : TRANSFER_OWNERSHIP_CHECK_IN_FAIL);
offerChangeFail.setData(joinPoint.getArgs()[3]);
} else if (joinPoint.getSignature().toShortString().contains("formalize")) {
offerChangeFail.setOperationType(SALE_NEW_NUMBER_FINALIZE_FAIL);
offerChangeFail.setData(joinPoint.getArgs()[3]);
} else {
offerChangeFail.setOperationType(TRANSFER_OWNERSHIP_FINALIZE_FAIL);
offerChangeFail.setData(joinPoint.getArgs()[1]);
}
offerChangeFailService.save(offerChangeFail);
log.info("ms-sales-process.FailAOP.afterThrowingException finish");
}

}




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

Creating our own annotation:


package az.etibarli.transactional.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Parvin {
}


package az.etibarli.transactional.configs.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

private static final Logger LOGGER = LoggerFactory.getLogger(LoggingAspect.class);

@Pointcut("within(az.etibarli.transactional.service.GreetingService+)")
public void anyGreetingServiceMethod() {}

@Pointcut("@annotation(az.etibarli.transactional.annotations.Parvin)")
public void anyAnnotation() {}

@Pointcut("execution(String getGreeting(String))")
public void anyGreeting() {}

@Before("anyGreetingServiceMethod()")
public void beforeAnyGreetingServiceMethod() {
LOGGER.info("====BEFORE====");
}

@Before("anyAnnotation()")
public void forFoo2() {
LOGGER.info("=====PUSH=====");
}

@Before("anyGreeting()")
public void forAnyGreeting() {
LOGGER.info("GREETING");
}

}


package az.etibarli.transactional.test;

import az.etibarli.transactional.annotations.Parvin;
import org.springframework.stereotype.Service;

@Service
public class TestService {

@Parvin
public void foo2() {
System.out.println("foo2 in TestService");
}

public String getGreeting(String s) {
return s;
}

}










































































Комментарии

Популярные сообщения из этого блога

Lesson1: JDK, JVM, JRE

SE_21_Lesson_11: Inheritance, Polymorphism

SE_21_Lesson_9: Initialization Blocks, Wrapper types, String class