Illustrate the use of AOP programming in Java's Spring framework

  • 2020-05-09 18:39:01
  • OfStack

1. What is AOP

AOP is short for Aspect Oriented Programming, which means aspect oriented programming, and AOP is actually a continuation of the GoF design pattern.

2. Some terms about Spring AOP:
  A, cut surface (Aspect) : in Spring AOP, cut surface can be implemented using a generic class or in a generic class using the @Aspect annotation (@AspectJ style)
B, join point (Joinpoint) : in Spring AOP, a join point represents the execution of a method
C, notification (Advice) : an action performed on a particular join point on the cut surface (Joinpoint). There are various types of notifications, including "around", "before "and "after". Many of the AOP frameworks, including Spring, use the interceptor as a notification model and maintain a chain of interceptors centered around the join point
D, pointcut (Pointcut) : defines one or a group of methods that generate advice when these methods are executed. Spring USES AspectJ pointcut syntax by default.

3. Notification type
A, prenotification (@Before) : a notification executed before a join point (join point), but this notification cannot prevent the execution before the join point (unless it throws an exception)
B, post-return notification (@AfterReturning) : a notification that is executed after a join point (join point) has completed normally: for example, a method returns normally without throwing any exceptions
C, notification after an exception is thrown (@AfterThrowing) : notification that is executed when a method throws an exception and exits
D, after notification (@After) : notification that is executed when a join point exits (either normal return or abnormal exit)
E, surround notification (@Around) : a notification that surrounds a join point (join point), such as a method call. This is the most powerful type of notification that wraps around a notification to complete custom behavior before and after a method call, and it also chooses whether to continue executing join points or simply return their own return values or throw an exception to end execution
 
4. AOP configuration in the @AspectJ style

The Spring AOP configuration comes in two styles:
A, XML style = implement Spring AOP in declarative form
B, AspectJ style = implementation of Spring AOP in the form of annotations

5, the instance,

Cut class TestAspect


package com.spring.aop; 
/** 
 *  section  
 */ 
public class TestAspect { 
 
  public void doAfter(JoinPoint jp) { 
    System.out.println("log Ending method: " 
        + jp.getTarget().getClass().getName() + "." 
        + jp.getSignature().getName()); 
  } 
 
  public Object doAround(ProceedingJoinPoint pjp) throws Throwable { 
    long time = System.currentTimeMillis(); 
    Object retVal = pjp.proceed(); 
    time = System.currentTimeMillis() - time; 
    System.out.println("process time: " + time + " ms"); 
    return retVal; 
  } 
 
  public void doBefore(JoinPoint jp) { 
    System.out.println("log Begining method: " 
        + jp.getTarget().getClass().getName() + "." 
        + jp.getSignature().getName()); 
  } 
 
  public void doThrowing(JoinPoint jp, Throwable ex) { 
    System.out.println("method " + jp.getTarget().getClass().getName() 
        + "." + jp.getSignature().getName() + " throw exception"); 
    System.out.println(ex.getMessage()); 
  } 
 
  private void sendEx(String ex) { 
    //TODO  Send SMS or email reminders  
  } 
}  


package com.spring.service; 
/** 
 *  interface A 
 */ 
public interface AService { 
   
  public void fooA(String _msg); 
 
  public void barA(); 
} 

package com.spring.service; 
/** 
 * interface A The implementation of the class  
 */ 
public class AServiceImpl implements AService { 
 
  public void barA() { 
    System.out.println("AServiceImpl.barA()"); 
  } 
 
  public void fooA(String _msg) { 
    System.out.println("AServiceImpl.fooA(msg:"+_msg+")"); 
  } 
} 

package com.spring.service; 
 
/** 
 *  Service class B 
 */ 
public class BServiceImpl { 
 
  public void barB(String _msg, int _type) { 
    System.out.println("BServiceImpl.barB(msg:"+_msg+" type:"+_type+")"); 
    if(_type == 1) 
      throw new IllegalArgumentException(" Abnormal test "); 
  } 
 
  public void fooB() { 
    System.out.println("BServiceImpl.fooB()"); 
  } 
 
} 

ApplicationContext


<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:aop="http://www.springframework.org/schema/aop" 
  xsi:schemaLocation=" 
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
      http://www.springframework.org/schema/aop 
      http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" 
  default-autowire="autodetect"> 
  <aop:config> 
    <aop:aspect id="TestAspect" ref="aspectBean"> 
      <!-- configuration com.spring.service All methods of all classes or interfaces under the package --> 
      <aop:pointcut id="businessService" 
        expression="execution(* com.spring.service.*.*(..))" /> 
      <aop:before pointcut-ref="businessService" method="doBefore"/> 
      <aop:after pointcut-ref="businessService" method="doAfter"/> 
      <aop:around pointcut-ref="businessService" method="doAround"/> 
      <aop:after-throwing pointcut-ref="businessService" method="doThrowing" throwing="ex"/> 
    </aop:aspect> 
  </aop:config> 
   
  <bean id="aspectBean" class="com.spring.aop.TestAspect" /> 
  <bean id="aService" class="com.spring.service.AServiceImpl"></bean> 
  <bean id="bService" class="com.spring.service.BServiceImpl"></bean> 
 
</beans> 

  test class AOPTest


public class AOPTest extends AbstractDependencyInjectionSpringContextTests { 
   
  private AService aService; 
   
  private BServiceImpl bService; 
   
  protected String[] getConfigLocations() { 
    String[] configs = new String[] { "/applicationContext.xml"}; 
    return configs; 
  } 
   
   
  /** 
   *  Test normal call  
   */ 
  public void testCall() 
  { 
    System.out.println("SpringTest JUnit test"); 
    aService.fooA("JUnit test fooA"); 
    aService.barA(); 
    bService.fooB(); 
    bService.barB("JUnit test barB",0); 
  } 
   
  /** 
   *  test After-Throwing 
   */ 
  public void testThrow() 
  { 
    try { 
      bService.barB("JUnit call barB",1); 
    } catch (IllegalArgumentException e) { 
       
    } 
  } 
   
  public void setAService(AService service) { 
    aService = service; 
  } 
   
  public void setBService(BServiceImpl service) { 
    bService = service; 
  } 
} 

 
The results are as follows:


log Begining method: com.spring.service.AServiceImpl.fooA 
AServiceImpl.fooA(msg:JUnit test fooA) 
log Ending method: com.spring.service.AServiceImpl.fooA 
process time: 0 ms 
log Begining method: com.spring.service.AServiceImpl.barA 
AServiceImpl.barA() 
log Ending method: com.spring.service.AServiceImpl.barA 
process time: 0 ms 
log Begining method: com.spring.service.BServiceImpl.fooB 
BServiceImpl.fooB() 
log Ending method: com.spring.service.BServiceImpl.fooB 
process time: 0 ms 
log Begining method: com.spring.service.BServiceImpl.barB 
BServiceImpl.barB(msg:JUnit test barB type:0) 
log Ending method: com.spring.service.BServiceImpl.barB 
process time: 0 ms 
 
log Begining method: com.spring.service.BServiceImpl.barB 
BServiceImpl.barB(msg:JUnit call barB type:1) 
log Ending method: com.spring.service.BServiceImpl.barB 
method com.spring.service.BServiceImpl.barB throw exception 
 Abnormal test  


Related articles: