ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring AOP
    Framework/SPRING 2019. 8. 23. 06:32

    1. Overview

    AOP is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. It does so by adding additional behavior to existing code without modification of the code itself.

    1.1 Code Tangling, Scattering, and Cross-Cutting Concerns

     

    Problems Without AOP or Modularization are Code Tangling and Code Scattering.

    1.1.1 cross-cutting concern

    A cross-cutting concern is a concern that can affect the whole application and should be centralized in one location in code as possible, such as transaction management, authentication, logging, security, and so on.

    1.1.2 Code Tangling

    Code tangling means mixing crosscutting concerns and business logic, which in turn leads to tight coupling. Let's look at the following diagram to understand code tangling:

    The preceding diagram illustrates how we mix transactions and security code along with our business logic in our service implementation. With such implementation, code reusability is reduced, maintenance is degraded, and the single responsibility principle is violated.

    1.1.3 Code Scattering

    Concerns are dispersed over many modules

    1.2 Usage

    • Logging and Tracing
    • Transaction Management
    • Security
    • Caching
    • Error Handling
    • Performance Monitoring

    2. Description

    Below are the core concepts of Spring AOP implementation.

    2.1 Aspect

    An aspect is a class that implements enterprise application concerns that cut across multiple classes, such as transaction management. And also it's a combination of the pointcut and the advice. Aspects can be a normal class configured through Spring XML configuration or Using Spring AspectJ integration to define a class as Aspect using @Asepct annotation. Aspect can be reused at multiple locations.

    2.2 Advice

    Advice is actions taken for a particular join point. 

    2.2.1 Before Advice

    it executes before a join point

    2.2.2 After Returning Advice

    it executes after a join point completes normally.

    2.2.3 After Throwing Advice

    it executes if a method exits by throwing an exception.

    2.2.4 After (finally) Advice

    it executes after a join point regardless of join point exit whether normally or exceptional return. 

    2.2.5 Around Advice

    It executes before and after a join point

    2.3 Pointcut

    This is predicate helps match an Advice to be applied by an Aspect at a particular JoinPoint. The Advice is often associated with a Pointcut expression and runs at any JoinPoint matched by the Pointcut.

    Pointcut JoinPoints
    execution(public * * (..)) public method
    execution(* set*(..)) all methods named prefix 'set'
    execution(* get*(..)) all methods named prefix 'get'
    execution(* com.xyz.service.AccountService.*(..)) all methods of AccountService interface
    execution(* com.xyz.service.*.*(..)) all mehods of service package
    execution(* com.xyz.service..*.*(..)) all methods of service package and nested package
    within(com.xyz.service.*) all join point of service package(include classes)
    within(com.xyz.service..*) all join point of service package and nested package(include classes)
    bean(*Repository) all beans of postfix 'Repository'
    bean(*) all beans
    bean(account*) all beans of prefix 'account'
    bean(*dataSource) || bean(*DataSource) all beans of postfix 'dataSource' or 'DataSource'

    2.3.1 Pointcut Designators

    • execution
    • within
    • this
    • target
    • args
    • @target
    • @args
    • @within
    • @annotation

    2.3.2 Pointcut Expression Language

    execution(modifier-pattern? return-type-pattern declaring-type-pattern? 
    		  method-name-pattern(param-pattern) throws-patterns?)

    2.4 Target Object

    They are the object being advised by one or more aspects. It is also known as a proxied object in spring because Spring AOP is implemented using runtime proxies. 

    2.5 JoinPoint

    A join point is a specific point in the application such as method execution, exception handling, changing object variable values, etc. In Spring AOP a join point is always the execution of a method.

    2.6 AOP proxy

    Spring AOP implementation uses JDK dynamic proxy or CGLIB to create the Proxy classes with target classes and advice invocations, these are called AOP proxy classes.

    2.7 Weaving

    It is the process of linking aspects with other objects to create advised proxy objects. It is also known as a proxied object in spring object in spring because Spring AOP is implemented using runtime proxies.

    3. Example

    This is a sample code of the annotation approach and using spring-boot-starter-aop.

    @Component
    @Aspect
    public class PerfAspect {
    
    @Around("execution(* com.saelobi..*.EventService.*(..))")
        public Object logPerf(ProceedingJoinPoint pjp) throws Throwable{
        long begin = System.currentTimeMillis();
        Object retVal = pjp.proceed(); // wrapping method invoking
        System.out.println(System.currentTimeMillis() - begin);
        return retVal;
      }
    }

    @Aspect annotation denotes this class is an Aspect class and also using @component assign it to spring bean pool. and @Around means wrapping target methods which match pointcut expression which is using execution pointcut designator(PCD).

    public interface EventService {
    
        void createEvent();
    
        void publishEvent();
    
        void deleteEvent();
    }
    @Component
    public class SimpleEventService implements EventService {
    
        @Override
        public void createEvent() {
            try {
                Thread.sleep(1000);
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Created an event");
        }
    
        @Override
        public void publishEvent() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e){
                e.printStackTrace();;
            }
            System.out.println("Published an event");
        }
    
        public void deleteEvent() {
            System.out.println("Delete an event");
        }
    }
    @Service
    public class AppRunner implements ApplicationRunner {
    
        @Autowired
        EventService eventService;
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            eventService.createEvent();
            eventService.publishEvent();
            eventService.deleteEvent();
        }
    }
    Created an event
    1003
    Published an event
    1000
    Delete an event
    0

     

    Also using @annotation PCD, you can weave specific join point as below. Only methods attached @PerLogging annotation are weaved with PerfAspect.

    @Component
    @Aspect
    public class PerfAspect {
    
    @Around("@annotation(PerLogging)")
    public Object logPerf(ProceedingJoinPoint pjp) throws Throwable{
        long begin = System.currentTimeMillis();
        Object retVal = pjp.proceed(); 
        System.out.println(System.currentTimeMillis() - begin);
        return retVal;
      }
    }
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.CLASS)
    public @interface PerLogging {
    }
    @Component
    public class SimpleEventService implements EventService {
    
        @PerLogging
        @Override
        public void createEvent() {
            try {
                Thread.sleep(1000);
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Created an event");
        }
    
        @Override
        public void publishEvent() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e){
                e.printStackTrace();;
            }
            System.out.println("Published an event");
        }
    
        @PerLogging
        @Override
        public void deleteEvent() {
            System.out.println("Delete an event");
        }
    }
    Created an event
    1003
    Published an event
    Delete an event
    0

     

    Also, all of the specific beans can be weaved using bean PCD as below. You can see only SimpleEventService's methods are weaved.

    @Component
    @Aspect
    public class PerfAspect {
    
    @Around("bean(simpleEventService)")
      public Object logPerf(ProceedingJoinPoint pjp) throws Throwable{
        long begin = System.currentTimeMillis();
        Object retVal = pjp.proceed(); // 메서드 호출 자체를 감쌈
        System.out.println(System.currentTimeMillis() - begin);
        return retVal;
      }
    }
    @Component
    public class SimpleEventService implements EventService {
    
        @Override
        public void createEvent() {
            try {
                Thread.sleep(1000);
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Created an event");
        }
    
        @Override
        public void publishEvent() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e){
                e.printStackTrace();;
            }
            System.out.println("Published an event");
        }
        
        @Override
        public void deleteEvent() {
            System.out.println("Delete an event");
        }
    }
    @Service
    public class AppRunner implements ApplicationRunner {
    
        @Autowired
        EventService eventService;
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            eventService.createEvent();
            eventService.publishEvent();
            eventService.deleteEvent();
        }
    }
    Created an event
    1002
    Published an event
    1001
    Delete an event
    0

     

    4. References

    https://howtodoinjava.com/spring-aop-tutorial/

    https://mossgreen.github.io/Spring-Certification-Spring-AOP/

    https://www.baeldung.com/spring-aop-vs-aspectj

    https://www.dineshonjava.com/spring-aop-tutorial-with-example-aspect-advice-pointcut-joinpoint/

    https://www.baeldung.com/spring-aop-pointcut-tutorial

    https://www.slideshare.net/taemonz/spring-framework-aop-23721816

    https://engkimbs.tistory.com/746

    https://www.baeldung.com/spring-aop-pointcut-tutorial

    https://www.researchgate.net/figure/Code-scattering-and-code-tangling_fig2_327338379

    https://www.oreilly.com/library/view/hands-on-high-performance/9781788838382/21d99753-67b4-40e3-b662-7d6f3267458e.xhtml

    https://howtodoinjava.com/spring-aop-tutorial/

    https://m.blog.naver.com/PostView.nhn?blogId=tlsdlf5&logNo=220691336157&proxyReferer=https%3A%2F%2Fwww.google.com%2F

    'Framework > SPRING' 카테고리의 다른 글

    Spring Bean Scopes  (0) 2019.09.29
    DispatcherServlet in Spring  (0) 2019.09.28
    Spring Security  (0) 2019.09.20
    Transaction Management  (0) 2019.09.17
    Spring Session  (0) 2019.08.27

    댓글

Designed by Tistory.