Introduction to Spring AOP and dynamic proxy of JDK

Keywords: Java Spring AOP

1. What is AOP

        The full name of AOP is aspect oriented programming, that is, aspect oriented programming. It is a supplement to object-oriented programming (OOP). At present, it has become a more mature programming method.

        In the traditional business processing code, transactions, logging and other operations are usually carried out. Although using OOP can achieve code reuse through combination or inheritance, if you want to implement a function (such as logging), the same code will still be scattered in various methods. In this way, if you want to turn off a function or modify it, you must modify all relevant methods. This not only increases the workload of developers, but also improves the error rate of code.

        In order to solve this problem, the idea of AOP came into being. AOP adopts a horizontal extraction mechanism to extract the repeated code scattered in various methods, and then apply the extracted code to the place to be executed when the program is compiled or run. It is obviously impossible to adopt the horizontal extraction mechanism and the traditional OOP idea, because OOP can only realize the vertical reuse of parent-child relationship. Although AOP is a new programming idea, it is not a substitute for OOP. It is only an extension and supplement of OOP.

        AOP   When writing business logic, developers can concentrate on the core business without paying too much attention to the implementation of other business logic, which not only improves the development efficiency, but also enhances the maintainability of the code.
        At present, there are two most popular AOP frameworks: spring   AOP and AspectJ. Spring   AOP is implemented in pure Java without special compilation process and class loader. Enhanced code is woven into the target class through proxy during operation. AspectJ is an AOP framework based on Java language, from spring   Starting with 2.0, spring   AOP introduces support for AspectJ, which extends the Java language and provides a special compiler to provide horizontal code weaving at compile time.

2.AOP terminology

Aspect: in practical applications, aspect usually refers to the encapsulated class used to horizontally insert system functions (such as transactions, logs, etc.). To be recognized as aspect by Spring container, it needs to be specified through < bean > element in configuration file.

Joinpoint: at a certain stage during program execution, it is actually an operation of an object, such as method call or exception throw. In Spring AOP, a join point is a method call.

Pointcut: it refers to the intersection of the aspect and the program flow, that is, the connection points that need to be processed. Usually in programs, pointcuts refer to class or method names. If a notification is to be applied to all methods starting with add, all methods that meet this rule are pointcuts.

Advice: the enhanced processing performed by the AOP framework at a specific pointcut, that is, the program code to be executed at the defined pointcut. It can be understood as the method in the aspect class, which is the concrete implementation of the aspect.

Target object: refers to all notified objects, also known as enhanced objects. If the AOP framework adopts a dynamic AOP implementation, the object is a proxy object.

Proxy: an object created dynamically after the notification is applied to the target object.

Weaving: the process of inserting slice code into the target object to generate a proxy object.

3. Dynamic agent of JDK

1. Create a web project, import the JAR package required by the Spring framework into the project lib directory, and publish it to the class path.

2. In the src directory, create a package (for example, yjf.jdk I created), and create the interface UserDao.java under the package

package yjf.jdk;

public interface UserDao {
	public void addUser();
	public void deleteUser();
}

3. In the yjf.jdk package, create the class UserDaoImpl.java implemented by the UserDao interface to implement the methods in the interface respectively

package yjf.jdk;

public class UserDaoImpl implements UserDao {
	public void addUser(){
		System.out.println("Add user");
	}
	public void deleteUser(){
		System.out.println("delete user");
	}
		
}

4. Create another package under the src directory (for example, the yjf.aspect package I created), and create the aspect class MyAspect.java under the package. In this class, define a method to check the simulation permission and a method to simulate logging. These two methods are notifications in the aspect

package yjf.aspect;

public class MyAspect {
	public void check_Permissions(){
		System.out.println("Simulate check permissions......");
	}
	public void log(){
		System.out.println("Simulation log......");
	}
}

5. Under the yjf.jdk package, create the Proxy class JdkProxy, which needs to implement the InvocationHandler interface and write the Proxy method. In the Proxy method, it needs to implement the dynamic Proxy through the Proxy class

package yjf.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import yjf.aspect.*;
/* JDK proxy class */
public class JdkProxy implements InvocationHandler {
	//Declare the target class interface
	private UserDao userDao;
	//Create proxy method
	public Object createProxy(UserDao userDao){
		this.userDao = userDao;
		//1. Class loader
		ClassLoader classLoader = JdkProxy.class.getClassLoader();
		//2. All interfaces implemented by the proxy object
		Class[] clazz = userDao.getClass().getInterfaces();
		//3. Use proxy class to enhance and return the object after proxy
		return Proxy.newProxyInstance(classLoader, clazz, this);
	}
	/*
	 * All method calls of dynamic proxy classes are handled by the invoke () method
	 * proxy Object after being represented
	 * method Method information to be executed (reflection)
	 * asgs Parameters required to execute the method
	 * 
	 * */
	@Override
	public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
		//Declaration section
		MyAspect myAspect = new MyAspect();
		//Pre enhancement
		myAspect.check_Permissions();
		//Call the method on the target class and pass in the parameters
		Object obj = method.invoke(userDao, args);
		//Hou Zengqiang
		myAspect.log();
		return obj;
	}

}

6. in the yjf.jdk package, create the test class JdkTest, create the proxy object and the target object in this class, then get the object enhanced by the target object userDao from the proxy object, and finally call the add and delete method in the object.

package yjf.jdk;

public class JdkTest {
	public static void main(String[] args){
		//Create proxy object
		JdkProxy jdkProxy = new JdkProxy();
		//Create target object
		UserDao userDao = new UserDaoImpl();
		//Gets the enhanced target object from the proxy object
		UserDao userDao1 = (UserDao) jdkProxy.createProxy(userDao);
		//Execution method
		userDao1.addUser();
		userDao1.deleteUser();
	}
}

The operation result is:

Simulate check permissions......
Add user
 Simulation log......
Simulate check permissions......
delete user
 Simulation log......

It can be seen that the methods of adding and deleting users in the userDao instance have been successfully called, and the functions of checking permissions and logging permissions have been added before and after the call. This is JDK dynamic agent.

Posted by plsanders on Tue, 21 Sep 2021 00:19:39 -0700