🖍️
Developer Note
  • Welcome
  • Git
    • Eslint & Prettier & Stylelint & Husky
  • Programming Language
    • JavaScript
      • Script Async vs Defer
      • Module
      • Const VS Let VS Var
      • Promise
      • Event Loop
      • Execution Context
      • Hoisting
      • Closure
      • Event Buddling and Capturing
      • Garbage Collection
      • This
      • Routing
      • Debounce and Throttle
      • Web Component
      • Iterator
      • Syntax
      • String
      • Array
      • Object
      • Proxy & Reflect
      • ProtoType
      • Class
      • Immutability
      • Typeof & Instanceof
      • Npm (Node package manager)
    • TypeScript
      • Utility Type
      • Type vs Interface
      • Any vs Unknown vs Never
      • Void and undefined
      • Strict Mode
      • Namespace
      • Enum
      • Module
      • Generic
    • Python
      • Local Development
      • Uv
      • Asyncio & Event loop
      • Context Manager
      • Iterator & Generator
      • Fast API
      • Pydantic & Data Class
    • Java
      • Compilation and Execution
      • Data Type
      • Enumeration
      • Data Structure
      • Try Catch
      • InputStream and OutputStream
      • Concurrent
      • Unicode Block
      • Build Tools
      • Servlet
      • Java 8
  • Coding Pattern
    • MVC vs MVVM
    • OOP vs Functional
    • Error Handling
    • MVC vs Flux
    • Imperative vs Declarative
    • Design Pattern
  • Web Communication
    • REST API
      • Web Hook
      • CORS issue
    • HTTPS
    • GraphQL
      • REST API vs GraphQL
      • Implementation (NodeJS + React)
    • Server-Sent Event
    • Web Socket
    • IP
    • Domain Name System (DNS)
  • Frontend
    • Progressive Web App (PWA)
    • Single Page & Multiple Page Application
    • Search Engine Optimiaztion (SEO)
    • Web bundling & Micro-frontend
      • Webpack
        • Using Webpack to build React Application
        • Using Webpack to build react library
      • Vite
      • Using rollup to build react library
      • Implementing micro frontend
    • Web Security
      • CSRF & Nonce
      • XSS
      • Click hijacking
    • Cypress
    • CSS
      • Core
        • Box Model
        • Inline vs Block
        • Flexbox & Grid
        • Pseudo Class
        • Position
      • Tailwind CSS
        • Shadcn
      • CSS In JS
        • Material UI
    • React
      • Core
        • Component Pattern
        • React Lazy & Suspense
        • React Portal
        • Error Boundary
        • Rendering Methods
        • Environment Variable
        • Conditional CSS
        • Memo
        • Forward Reference
        • High Order Component (HOC) & Custom Hook
        • TypeScript
      • State Management
        • Redux
        • Recoil
        • Zustand
      • Routing
        • React Router Dom
      • Data Fetching
        • Axios & Hook
        • React Query
        • Orval
      • Table
        • React Table
      • Form & Validation
        • React Hook Form
        • Zod
      • NextJS
        • Page Router
        • App Router
      • React Native
    • Angular
    • Svelte
      • Svelte Kit
  • Backend
    • Cache
      • Browser Cache
      • Web Browser Storage
      • Proxy
      • Redis
    • Rate limit
    • Monitoring
      • Logging
      • Distributed Tracing
    • Load Test
    • Encryption
    • Authentication
      • Password Protection
      • Cookie & Session
      • JSON Web Token
      • SSO
        • OAuth 2.0
        • OpenID Connect (OIDC)
        • SAML
    • Payment
      • Pre-built
      • Custom
    • File Handling
      • Upload & Download (Front-end)
      • Stream & Buffer
    • Microservice
      • API Gateway
      • Service Discovery
      • Load Balancer
      • Circuit Breaker
      • Message Broker
      • BulkHead & Zipkin
    • Elastic Search
    • Database
      • SQL
        • Group By vs Distinct
        • Index
        • N + 1 problem
        • Normalization
        • Foreign Key
        • Relationship
        • Union & Join
        • User Defined Type
      • NOSQL (MongoDB)
      • Transaction
      • Sharding
      • Lock (Concurrency Control)
    • NodeJS
      • NodeJS vs Java Spring
      • ExpressJS
      • NestJS
        • Swagger
        • Class Validator & Validation Pipe
        • Passport (Authentication)
      • Path Module
      • Database Connection
        • Integrating with MYSQL
        • Sequalize
        • Integrating with MongoDB
        • Prisma
        • MikroORM
        • Mongoose
      • Streaming
      • Worker Thread
      • Passport JS
      • JSON Web Token
      • Socket IO
      • Bull MQ
      • Pino (Logging)
      • Yeoman
    • Spring
      • Spring MVC
      • Spring REST
      • Spring Actuator
      • Aspect Oriented Programming (AOP)
      • Controller Advice
      • Filter
      • Interceptor
      • Concurrent
      • Spring Security
      • Spring Boot
      • Spring Cloud
        • Resilience 4j
      • Quartz vs Spring Batch
      • JPA and Hibernate
      • HATEOS
      • Swagger
      • Unit Test (Java Spring)
      • Unit Test (Spring boot)
  • DevOp
    • Docker
    • Kubernetes
      • Helm
    • Nginx
    • File System
    • Cloud
      • AWS
        • EC2 (Virtual Machine)
        • Network
        • IAM
          • Role-Service Binding
        • Database
        • Route 53
        • S3
        • Message Queue
        • Application Service
        • Serverless Framework
        • Data Analysis
        • Machine Learning
        • Monitoring
        • Security
      • Azure
        • Identity
        • Compute Resource
        • Networking
        • Storage
        • Monitoring
      • Google Cloud
        • IAM
          • Workload Identity Federation
        • Compute Engine
        • VPC Network
        • Storage
        • Kubernetes Engine
        • App Engine
        • Cloud function
        • Cloud Run
        • Infra as Code
        • Pub/Sub
    • Deployment Strategy
    • Jenkins
    • Examples
      • Deploy NextJS on GCP
      • Deploy Spring on Azure
      • Deploy React on Azure
  • Domain Knowledge
    • Web 3
      • Blockchain
      • Cryptocurrency
    • AI
      • Prompt
      • Chain & Agent
      • LangChain
      • Chunking
      • Search
      • Side Products
Powered by GitBook
On this page
  • Introduction
  • Terminology
  • Point Cut
  • Advice

Was this helpful?

  1. Backend
  2. Spring

Aspect Oriented Programming (AOP)

PreviousSpring ActuatorNextController Advice

Last updated 1 year ago

Was this helpful?

Introduction

  • Spring AOP allows developers to separate the implementation of these cross-cutting concerns (applying to different classes) from the business logic of the application, making the code more modular and easier to understand.

  • If we call want to add some common logic, such as logging, security to the method, it is not ideal to add it directly into method, as there are much methods in the application

  • Moreover, it is very time-wasting to update the method one by one if we need to update the common logic

  • So that, we separate the common logic into aspect class and define which method which timing should apply

  • We can modify the configuration by updating few lines easily instead of modifying the method one by one when updated the common logic

Terminology

  • Advice: the action that perform before getting the result from method

  • Point Cut: the expression that declare the condition of triggering the advice

  • Join Point: To get back the method name of method and the relative parameters

  • Order: To declare which aspect java class will be executed first

Point Cut

  • The expression format: Modifier(Optional) , Return type , Path of class, method(params)

  • (*) means any, method name(..) means any type and number of params

@Aspect
public class AopExpression {
    @Pointcut("execution(public void com.luv2code.dao.*.add*(..))")
    public void forDaoPackageAdd(){}

    @Pointcut("execution(* com.luv2code.dao.*.get*())")
    public void forDaoPackageGet(){}

    @Pointcut("execution(* com.luv2code.dao.*.set*(..))")
    public void forDaoPackageSet(){}

    @Pointcut("execution(* *(..))")
    public void forAllPackageAllMethod(){}

    @Pointcut("forAllPackageAllMethod() && !(forDaoPackageSet() || forDaoPackageSet() )")
    public void forAllPackageAllMethodWithoutGetSet(){}

    @Pointcut("execution(* com.luv2code.dao.*.find*(..))")
    public void forDaoPackageFind(){}
}

Advice

  • There are 5 types of advice

  • Before: before the method is executed

  • After: after the method is executed

  • AfterReturning: after the method is executed successfully, we can obtain the result and do some stuff which can change the result

  • AfterThrowing: after the method is executed with exception, we can obtain the exception

  • Around: The advice will be executed before and after the method execution, and also can handle the exception by return the default value to the main program

@Aspect
@Component
@Order(-1)
public class myDemoLoggingAspect {
    private static Logger myLogger = Logger.getLogger(myDemoLoggingAspect.class.getName());

    @Around("com.luv2code.aspect.AopExpression.forDaoPackageFind()")
    public Object aroundFindAccountAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        String method = proceedingJoinPoint.getSignature().toString();
        Object result = null;
        try {
            myLogger.info(" Execute Around Method " + method);
            long begin = System.currentTimeMillis();
            result = proceedingJoinPoint.proceed();
            long end = System.currentTimeMillis();
            long duration = end - begin;
            myLogger.info("Duration: " + duration);
        }
        catch(Exception e){
            myLogger.warning(" handle the exception on around aspect");
            throw e;
//            List<Account>  accountList = new ArrayList<>();
//            accountList.add(new Account("Test","Gold"));
//            result = accountList;
        }
        return result;
 //       return null;
    }


    @After("com.luv2code.aspect.AopExpression.forDaoPackageFind()")
    public void afterFindAccountAdvice(JoinPoint joinPoint){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        myLogger.info("After Find Method Signature: " + methodSignature);
    }

    @AfterReturning(pointcut = "com.luv2code.aspect.AopExpression.forDaoPackageFind()", returning = "result")
    public void afterReturningFindAccountAdvice(JoinPoint joinPoint, List<Account> result){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        myLogger.info("After Returning Find Method Signature: "+ methodSignature);
        result.stream().forEach(eachResult -> myLogger.info(eachResult.getLevel() + "    " + eachResult.getName()));
        result.remove(0);
    }

    @AfterThrowing(pointcut = "com.luv2code.aspect.AopExpression.forDaoPackageFind()", throwing = "throwException")
    public void afterThrowingFindAccountAdvice(JoinPoint joinPoint, Throwable throwException){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        myLogger.info("After Returning Find Method Signature: " + methodSignature +"  And Exception is  " +  throwException.getMessage());
    }




    @Before("com.luv2code.aspect.AopExpression.forAllPackageAllMethod()")
    public void performLogging(JoinPoint joinPoint){

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        myLogger.info("perform Logging");
        myLogger.info("Method Signature   " + methodSignature);

        Object [] args = joinPoint.getArgs();

        Arrays.stream(args).forEach((arg)-> myLogger.info("arg: "+ arg));
    }