- Programming technique based on concept of an Aspect.
 - An aspect encapsulate cross-cutting logic - "Cross-Cutting Concerns".
 - "Concern" means logic/functionality - like logging, security.
 - Apply the Proxy design pattern.
 
- Aspect can be reused at multiple locations.
 - Same aspect/class can be applied on any class based on configuration.
 
- Code for Aspect is defined in a single class
- Much better than being scattered everywhere.
 - Promoted code reuse and easier to change.
 
 - Business code in the application is cleaner
- Only applied to business functionality.
 - Reduces code complexity.
 
 - Configurable
- Based on configuration, apply Aspects selectively to different parts of the application.
 - No need to make changes to main application code.
 
 
- Most common
- logging, security, transactions
 
 - Audit logging
- who, what, when, where
 
 - Exception handling
- log exception and notify DevOps team via SMS/Email
 
 - API Management
- how many times has a method been called by user.
 - analytics: what are peak times? what is average load? who is top user?
 
 
- Reusable modules
 - Resolve code tangling
 - Resolve code scatter
 - Applied selectively based on configuration
 
- Too many aspects and app flow is hard to follow
 - Minor performance cost for aspect execution (run-time weaving)
 
- Aspect: module of code for a cross-cutting concern (logging, security etc)
 - Advice: What action is taken and when it should be applied
- Before advice: run before method
 - After finally advice: run after the method (finally)
 - After returning advice: run after the method (success execution)
 - After throwing advice: run after the method (if exception thrown)
 - Around advice: run before and after the method
 
 - Join Point: When to apply code during program execution
- We can read the method arguments using JoinPoints.
 - Example - Access and display method signature
 
@Before("execution(public void addAccount())") public void beforeAddAccountAdvice(JoinPoint joinPoint) { MethodSignature methodSig = (MethodSignature) joinPoint.getSignature(); System.out.println(methodSig); }
- Example - Access and display method signature
 
@Before("execution(public void addAccount(com.ysingh.springaop.expression.model.Account, ..))") public void beforeAddAccountAdvice(JoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); for(Object arg : args) { System.out.println(arg); } }
 - Pointcut: A predicate expression for where advice should be applied
- Expression Language:
execution(modifiers? return-type declaring-type? method-name(param) throws?)
- ? - They are optional and we can skip if we don't need them.
 - For Param:
- () - matches a method with no arguments
 - (*) - matches a method with one argument of any return type
 - (..) - matches a method with 0 or more arguments of any return type
 
 - Example - Match on method names:
- Match only addAccount method in AccountDAO class
 
@Before("execution(public void com.ysingh.springaop.dao.AccountDAO.addAccount())")
- Match only addAccount method in any class
 
@Before("execution(public void addAccount())")
- Match methods starting with add in any class
 
@Before("execution(public void add*())")
 - Example - Match on return type:
- Match any return type
 
@Before("execution(public * add*())")
 - Example
 
 - Declaration
- Benefit
- Easily reuse the pointcut expressions
 - Update pointcut in one location
 - Can also share and combine the pointcut expressions
 
 - Example
- Match DAO Package
 
@Pointcut("execution(* com.ysingh.springaop.dao.*.*(..))") private void forDaoPackage() {}
 - Example
 
 - Benefit
 
 - Expression Language:
execution(modifiers? return-type declaring-type? method-name(param) throws?)
 
- Spring AOP only supports
- Method-level join points
 - Run-time code weaving (slower than AspectJ)
 
 - AspectJ supports
- join points: method-level, constructor, field
 - weaving: compile-time, post compile-time and load-time