A brief introduction to dynamic proxy
Dynamic proxies are essentially the process by which the JVM dynamically creates and loads the class bytecode at runtime.
Advantages: Appropriate enhancements to the target method without modifying the source code.
Purpose: To achieve loose coupling between program functions.
Two kinds of implementation of dynamic proxy
JDK proxy: dynamic proxy technology based on interfaces (disadvantages, target objects must have interfaces, without which dynamic proxy implementation cannot be completed)
Cglib proxy: Dynamic proxy technology based on superclass
The difference between the two is shown in the figure below:
1. Implementation based on JDK
Target interface class:
public interface TargetInterface {
public void save();
public void print(String str);
}
Copy the code
The target class:
public class Target implements TargetInterface{
public void save() {
System.out.println("save running...");
}
public void print(String str) {
System.out.println(str);
}
}
Copy the code
Strengthen the class:
Public class Advice {public void before() {system.out.println (" prepackage "); } public void after() {system.out.println (" after "); }}Copy the code
The test class:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; Public class ProxyTest {public static void main(String[] args) {// Final Target Target = new Target(); Final Advice = new Advice(); TargetInterface proxyInstance = (TargetInterface)Proxy.newProxyInstance( target.getClass().getClassLoader(), // The target object classloader target.getClass().getinterfaces (), // the target object's same interface array of bytecode objects new InvocationHandler() {// Calls any method of the proxy object, Invoke (Object proxy, Method Method, Object[] args) throws Throwable{advice.before(); Object invoke = method.invoke(target, args); // Execute the target method advice.after(); // Add system.out.println (); return invoke; }}); // Test proxyinstance.save (); Proxyinstance. print("JDK dynamic proxy "); }}Copy the code
Run screenshot:
2. Implementation based on Cglib
Import Jar packages. If you are a Maven project, add the following configuration to the pom.xml file:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> < version > 4.2.4. RELEASE < / version > < / dependency >Copy the code
The target class:
public class Target {
public void save() {
System.out.println("save running...");
}
public void print(String str) {
System.out.println(str);
}
}
Copy the code
Strengthen the class:
Public class Advice {public void before() {system.out.println (" prepackage "); } public void after() {system.out.println (" after "); }}Copy the code
The test class:
import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class ProxyTest { public static void main(String[] args) { final Target target = new Target(); final Advice advice = new Advice(); Enhancer = new Enhancer(); // Set the parent class(Target) enhancer.setsuperclass (target.class); SetCallback (new MethodInterceptor() {public Object Intercept (Object o, Method Method, Object[] obj, MethodProxy methodProxy) throws Throwable{ advice.before(); Object invoke = method.invoke(target, obj); advice.after(); System.out.println(); return invoke; }}); Target proxy = (Target)enhancer. Create (); // Test proxy method proxy.save(); Proxy. print(" Dynamic programming based on Cglib "); }}Copy the code
Run screenshot:
Why have cglib based implementation
With JDK dynamic proxy implementations, the biggest limitation is that the object being enhanced must implement the interface, and the enhanced methods can only be those declared in the interface. But in real projects, there may always be a need to enhance objects that don’t implement a business interface, and JDK dynamic proxies won’t be able to do that.