Spring custom enhancement method

Custom enhancement methods, also known as notification methods, are Java methods annotated with @ Before, @ AfterRunning, @ AfterThrowing, @ After or @ Around annotations.  

@Before

Pre enhancement (also known as pre notification): in the target methodimplementPrevious implementation

@After

Post enhancement (also known as post notification): executed after target method execution,Whether or not an exception occurred during the target method run. Be careful:Post enhancement failed to get target method execution resultsAvailable in return enhancement

@AfterRunning

Return enhancement (also known as return notification): intargetAfter the method is executed normally, you can get theresults of enforcement

@AfterThrowing

Exception enhancement (also known as exception notification): target methodAfter throwing an exceptionExecute, you can access the exception object, and you can specify which exception occurs before the enhanced code is executed

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect//Declare a class as a tangent class
@Component// Store class objects in containers
public class CalculatorAspect {

	//Preamplifier
	@Before("execution(int div(int , int ))")
	public void before(JoinPoint jp) {
		
		Object target=jp.getTarget();
		Object[] params = jp.getArgs();

		System.out.println(target.getClass().getName()+": The mul method begins.");
		System.out.println(target.getClass().getName()+": Parameters of the mul method:  ["+params[0]+","+params[1]+"]");
	}
	
	//Return enhancement 
	@AfterReturning(value="execution(int div(..))" ,returning="a")
	public void afterRrturning(JoinPoint jp,Object a) {
		Object object = jp.getTarget();
		String name = jp.getSignature().getName();
		System.out.println(object.getClass().getName()+"Result of the "+name+" method :"+a);
	}	

	//Post enhancement
	@After("execution(int div(int  , int ))")
	public void after(JoinPoint jp) {
		Object object = jp.getTarget();
		String name = jp.getSignature().getName();
		System.out.println(object.getClass().getName()+"the"+name+"method ends");
	}
	
	//Abnormal enhancement
	@AfterThrowing(value="execution(int div(..))" ,throwing="ex")
	public void afterThrowing(JoinPoint jp, RuntimeException ex) {
		Object object = jp.getTarget();
		String name = jp.getSignature().getName();
		System.out.println(object.getClass().getName() + " the "+ name+ " have a exception : " + ex.getMessage());
		
	}
}

Be careful:

The data type of ex variable is Exception, the subclass of RuntimeException in case of ArithmeticException Exception, so the afterThrowing method can be executed in case of Exception in the target method; if the data type of ex is NullPointerException, the afterThrowing method will not be executed in case of Exception in the target method.

@Before,@After,@AfterReturning,@AfterThrowing

The call here is the div method in the proxy object. The execution process of this method is as follows: ① execute pre enhancement; ② execute the div method of the target object; ③ execute post enhancement; ④ execute return enhancement; ⑤ if the previous method is abnormal, the return enhancement will not be executed but the exception enhancement will be executed directly.

import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zzu.calculator.ICalculatorService;

public class Test {

	public static void main(String[] args) {
		//Create a collection (IOC container) and place the bean s in spring.xml in the container 
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");//
		ICalculatorService calculatorService =applicationContext.getBean(ICalculatorService.class);
		//ICalculatorService calculatorService = new CalculatorService();
		System.out.println(calculatorService.getClass().getName());
		int result = calculatorService.div(6, 2);
		System.out.println("div---->"+result);
	}	
}

Operation result:

When an exception occurs to the called method

@Around

Surround enhancement: Enhanced processing can be woven into the target method before and after implementation

AspectJ Five types of enhanced annotations are supported, except@Before,@After,@AfterReturning and@AfterThrowing In addition, there is an enhanced annotation——@Around,stay@Around Can be realized in the modified method@Before,@After,@AfterReturning and@AfterThrowing The enhanced effect can realize the whole process of dynamic agent, and the code is as follows: 

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect//Declare a class as a tangent class
@Component// Store class objects in containers
public class CalculatorAspect {

	@Around("execution(int div(..))")
	public Object around(ProceedingJoinPoint jp) {
		Object result=null;
		Object object=jp.getTarget();
		String name = jp.getSignature().getName();
		Object[] params = jp.getArgs();
		try {
			try {
				//Preamplifier
				System.out.println(object.getClass().getName()+": The "+name+" method begins.");
				System.out.println(object.getClass().getName()+": Parameters of the "+name+" method:  ["+params[0]+","+params[1]+"]");
				result = jp.proceed(); //Execute method in target object
			} finally {
				//Post enhancement
				System.out.println(object.getClass().getName()+"the"+name+"method ends");
			}
			//Return enhancement
			System.out.println(object.getClass().getName()+"Result of the "+name+" method :"+result);
		} catch (Throwable e) {
			//Abnormal enhancement
			System.out.println(object.getClass().getName() + " the "+ name+ " have a exception : " + e.getMessage());
		}
		return result;
	}
}

Execute test class:

import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zzu.calculator.ICalculatorService;

public class Test {

	public static void main(String[] args) {
		//Create a collection (IOC container) and place the bean s in spring.xml in the container 
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");//
		ICalculatorService calculatorService =applicationContext.getBean(ICalculatorService.class);
		System.out.println(calculatorService.getClass().getName());
		int result = calculatorService.div(6, 2);
		System.out.println("div---->"+result);
	}
	
}

Run results:

Be careful:

1. Methods decorated with @ Before, @ After, @ AfterRunning and @ AfterThrowing can obtain the information of the target method (method name, parameter list, etc.) by declaring parameter variables of JoinPoint type; methods decorated with @ Around must declare parameters of ProceedingJoinPoint type, which can decide whether to execute the target method or not.

2. The methods decorated with @ Before, @ After, @ AfterRunning and @ AfterThrowing have no return value, while the methods decorated with @ Around must have a return value, which is the return value of the target method.

 

 

 

Keywords: Spring xml calculator Java

Added by davidmuir on Wed, 23 Oct 2019 21:41:17 +0300