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.