aop of spring (five notices)

Posted by phpcodec on Sun, 24 Oct 2021 20:01:56 +0200

1. Key concepts in AOP  

Join point: a specific point in the process of program execution, such as method call or exception throw

Target: the object to be notified (represented)
Note 1: complete the specific business logic

Advice: an action performed on a specific connection point. At the same time, advice is also a specific implementation of program code, such as a code that implements logging (also known as processing in some books)
Note 2: finish section programming

Proxy: object created after notification is applied to the target object (proxy = target + notification)
Example: surgeon + nurse
Note 3: only the proxy object has AOP function, and the AOP code is written in the notification method

Pointcut: a collection of join points that defines which join points the notification should apply to
(Pointcut is also understood as a condition that determines when the container combines notifications and targets into a proxy to return to the external program)
 
Adapter (Advisor): adapter = advice + pointcut

The picture is easy to understand:

2. Core points of AOP (notification, implementation interface and application scenario)

Notification type    Implementation interface                                               Application scenario

Before advice     realization org.springframework.aop.MethodBeforeAdvice Interface     Add system log before buying books and comments

Post notification    realization org.springframework.aop.AfterReturningAdvice Interface   Book rebate

Around Advice     realization org.aopalliance.intercept.MethodInterceptor Interface    Similar to interceptors, it will include pointcuts, and the target class will execute code before and after

Exception notification    realization org.springframework.aop.ThrowsAdvice Interface           If an exception occurs, execute the system prompt, and then handle it. Take abnormal price as an example

Filter notifications (adapter)    realization org.springframework.aop.support.RegexpMethodPointcutAdvisor Interface   Deal with book rebate bug

1, Preparation and tools used

Interface class IBookBiz:

package com.lgs.aop.biz;

public interface IBookBiz {
	// Purchase books
	public boolean buy(String userName, String bookName, Double price);

	// Publish book reviews
	public void comment(String userName, String comments);
}

Implementation class BookBizImpl of interface class IBookBiz:

package com.lgs.aop.biz;

import com.lgs.aop.exception.PriceException;

public class BookBizImpl implements IBookBiz {

	public BookBizImpl() {
		super();
	}

	//Buy books
	public boolean buy(String userName, String bookName, Double price) {
		// Simulate book purchase through the output mode of the console
		// If the data is negative, an exception will be thrown
		if (null == price || price <= 0) {
			throw new PriceException("book price exception");
		}
		//Who bought the book and how much did it cost
		System.out.println(userName + " buy " + bookName + ", spend " + price);
		return true;
	}
	
	//comment
	public void comment(String userName, String comments) {
		// Simulate publishing book reviews through the output of the console
		System.out.println(userName + " say:" + comments);
	}

}

Runtime exception PriceException class required for exception notification:

package com.lgs.aop.exception;

public class PriceException extends RuntimeException {

	public PriceException() {
		super();
	}

	public PriceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
	}

	public PriceException(String message, Throwable cause) {
		super(message, cause);
	}

	public PriceException(String message) {
		super(message);
	}

	public PriceException(Throwable cause) {
		super(cause);
	}
	
}

spring-context.xml configuration file:

<?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"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

<!-- This file configures all the information contained in the entire project JavaBean,The purpose is spring Unified management of the project -->

<!-- <bean name="userBiz1" class="com.lgs.ioc.biz.impl.UserBizImpl1"></bean> -->
<bean name="userBiz2" class="com.lgs.ioc.biz.impl.UserBizImpl1"></bean>
<bean name="userBiz1" class="com.lgs.ioc.biz.impl.UserBizImpl2"></bean>

<bean name="personAction" class="com.lgs.ioc.web.PersonAction">
	<property name="userBiz" ref="userBiz2"></property>
</bean>

<bean name="userAction1" class="com.lgs.ioc.web.UserAction1">
	<property name="userBiz" ref="userBiz1"></property>
</bean>
<bean name="userAction2" class="com.lgs.ioc.web.UserAction2">
	<property name="userBiz" ref="userBiz1"></property>
</bean>
<bean name="userAction3" class="com.lgs.ioc.web.UserAction3">
	<property name="userBiz" ref="userBiz1"></property>
</bean>

<bean name="paramAction" class="com.lgs.ioc.web.ParamAction">
<!-- 	<property name="name" value="Lu Xun"></property>
	<property name="age" value="34"></property>
	<property name="hobby">
		<list>
			<value>study medicine</value>
			<value>vernacular literature</value>
			<value>writer</value>
		</list>
	</property> -->
	<constructor-arg name="name" value="Wu Zetian"></constructor-arg>
	<constructor-arg name="age" value="22"></constructor-arg>
	<constructor-arg name="hobby">
		<list>
			<value>dance</value>
			<value>sing</value>
			<value>Be emperor</value>
		</list>
	</constructor-arg>
</bean>

<!-- aop -->

<!-- target -->
<bean name="bookBiz" class="com.lgs.aop.biz.BookBizImpl"></bean>
<!-- Before advice  -->
<bean name="myBefore" class="com.lgs.aop.advice.MyMethodBeforeAdvice"></bean>
<!-- Post notification -->
<bean name="myAfter" class="com.lgs.aop.advice.MyAfterReturningAdvice"></bean>
<!-- Around Advice  -->
<bean name="myFilterAdvice" class="com.lgs.aop.advice.MyMethodInterceptor"></bean>
<!-- Exception notification -->
<bean name="myExceptionAdvice" class="com.lgs.aop.advice.MyThrowsAdvice"></bean>

<!-- Filter notifications -->
<!-- org.springframework.aop.support.RegexpMethodPointcutAdvisor This class is fixed   myAfter2: Post notifications are filtered -->
<bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="myAfter2">
	<!-- Which notification to filter? Select post notification to filter  -->
	<property name="advice" ref="myAfter"></property>
	<!-- .*buy:[.*]Any character 0~n One, in order to buy Ending method -->
	<property name="patterns">
		<list>
			<!-- Filtered out buy method -->
			<value>.*buy</value>
		</list>
		</property>
</bean>

<!-- Generate proxy (target object)+(notification) -->
<!--  org.springframework.aop.framework.ProxyFactoryBean: Agent factory   proxyFactoryBean: Proxy object-->
	<bean class="org.springframework.aop.framework.ProxyFactoryBean"
		id="proxyFactoryBean">
		<property name="target" ref="bookBiz"></property>
		<!-- List of interfaces to be implemented by agents produced by the agent factory -->
		<property name="proxyInterfaces">
			<list>
				<value>com.lgs.aop.biz.IBookBiz</value>
			</list>
		</property>
		<!-- Proxy notification list -->
		<property name="interceptorNames">
			<list>
				<value>myBefore</value>
				<!-- <value>myAfter</value> -->
				<value>myAfter2</value>
				<value>myFilterAdvice</value>
				<value>myExceptionAdvice</value>
			</list>
		</property>
	</bean>

</beans>

Test class AopTest.java: (the test classes of several notification cases are basically the same, and I will show the screenshots if there are changes)

package com.lgs.aop.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.lgs.aop.biz.IBookBiz;

public class AopTest {
	public static void main(String[] args) {
//		Get the spring-Context.xml configuration file
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
//		Get the implementation class according to the id of the bean
//		IBookBiz bookBiz = (IBookBiz) applicationContext.getBean("bookBiz");
//		Call pre notification
		IBookBiz bookBiz = (IBookBiz) applicationContext.getBean("proxyFactoryBean");
//		Buy books
		bookBiz.buy("Diga", "<The power of light", 33d);
//		comment
		bookBiz.comment("Diga", "My source of strength");
	}
}

2, Advance notice

Pre notification MyMethodBeforeAdvice (to implement MethodBeforeAdvice interface):

package com.lgs.aop.advice;
import java.util.Arrays;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
/**
 * Before advice 
 */
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
/**
 * Implementation interface
 * target: Target object
 * method: Method of triggered target object
 * args: Parameters carried by the target method of the target object
 */
	public void before(Method method, Object[] args, Object target) throws Throwable {
		String targetName = target.getClass().getName();
		String methodName = method.getName();
		String params = Arrays.toString(args);
		String msg = "[Syslog]: calling->"+targetName+"."+methodName+",Parameters carried:"+params;
		System.out.println(msg);
	}
}

Before using the pre notification, you need to configure and make some changes (the configuration and changes are as follows) spring-context.xml

Operation results:

Secretly

3, Post notification

Post notification MyAfterReturningAdvice (to implement the AfterReturningAdvice interface): there is one more parameter than the pre, and the return value is

package com.lgs.aop.advice;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.springframework.aop.AfterReturningAdvice;
/**
 * Post notification
 */
public class MyAfterReturningAdvice implements AfterReturningAdvice {
	public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
		String targetName = target.getClass().getName();
		String methodName = method.getName();
		String params = Arrays.toString(args);
		String msg = "[Rebate notice: rebate 3 yuan]: calling->" + targetName + "." + methodName + ",Parameters carried:" + params + ";Return value of the method called by the target object:"
				+ returnValue;
		System.out.println(msg);
	}
}

Configure spring-context.xml

Call test AopTest.java   The operation results are as follows

Secretly

4, Surround Notifications: include pre + Post notifications

Surround notification MythodInterceptor (to implement MethodInterceptor interface):

package com.lgs.aop.advice;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
 * Around Advice  
 */
public class MyMethodInterceptor implements MethodInterceptor {
	public Object invoke(MethodInvocation invocation) throws Throwable {
		Object target = invocation.getThis();
		Method method = invocation.getMethod();
		Object[] args = invocation.getArguments();
		// a.jsp window.open(b.jsp)
		// b. JSP XXX - > return object - > b.jsp window. Close(); window.getArguments;
		String targetName = target.getClass().getName();
		String methodName = method.getName();
		String params = Arrays.toString(args);
		String msg = "[Surround notification]: calling->" + targetName + "." + methodName + ",Parameters carried:" + params;
		System.out.println(msg);
		//invocation can execute the business method of the target object being proxied
		//Filter chain.dofilter: release
		Object returnValue = invocation.proceed();
		String msg2 = "[Surround notification]: return value of the method called by the target object:" + returnValue;
		System.out.println(msg2);
		return returnValue;
	}
}

Configure spring-context.xml

Call test AopTest.java   The operation results are as follows

5, Exception notification

If an exception occurs, the program will be terminated directly and data rollback will not be performed  

Exception notification MyThrowsAdvice (to implement the ThrowsAdvice interface): (either succeed at the same time or fail at the same time)

package com.lgs.aop.advice;
import org.springframework.aop.ThrowsAdvice;
import com.lgs.aop.exception.PriceException;
/**
 * Exception notification
 */
public class MyThrowsAdvice implements ThrowsAdvice {
	public void afterThrowing( PriceException ex ) {
		System.out.println("Price input error, purchase failed, please re-enter!!!");
	}
}

Configure spring-context.xml

  Modify the test class AopTest.java to create exception data (- 33d)

package com.lgs.aop.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.lgs.aop.biz.IBookBiz;

public class AopTest {
	public static void main(String[] args) {
//		Get the spring-Context.xml configuration file
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
//		Get the implementation class according to the id of the bean
//		IBookBiz bookBiz = (IBookBiz) applicationContext.getBean("bookBiz");
//		Call pre notification
		IBookBiz bookBiz = (IBookBiz) applicationContext.getBean("proxyFactoryBean");
//		Buy books
		bookBiz.buy("Diga", "<The power of light", -33d);
//		comment
//		bookBiz.comment("diga", "my source of strength");
	}
}

  The operation results are as follows (there will be a prompt and a solution will appear)

6, Filter notifications

Filter Notifications: not every method needs notifications. All methods need to be filtered

Configure spring-context.xml (filter notifications instead of post notifications)  

Operation results:

OK! That's it   Hope to help you.  

Topics: Java Spring AOP