-
Spring AOPFramework/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
'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