The proxy pattern
This is an important design pattern that I understand to add some pre-business logic and post-business logic before and after calling the methods of the actual business logic objects. For example, a student has a method to go to class. Before calling this method, it needs to check whether the clothes are in accordance with the school regulations, check whether the school bag and stationery items are in order and so on.
JDK dynamic proxy
The following is a simple dynamic proxy implementation process. Dynamic proxies must first write an interface for the object to be proxied, so that subsequent proxy objects can hang on to this interface.
package Chapter2;
public interface Student {
void goToSchool(a);
}
Copy the code
The implementation class StudentImpl
public class StudentImpl implements Student{
String studentName;
StudentImpl(String name){
this.studentName = name;
}
@Override
public void goToSchool(a) {
System.out.println(this.studentName + " is on the way to school...."); }}Copy the code
Implementing proxy classes
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class StudentProxy implements InvocationHandler {
StudentImpl realStudent = null;
public Object bind(StudentImpl student){
this.realStudent = student;
return Proxy.newProxyInstance(realStudent.getClass().getClassLoader(),
student.getClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("checking uniforms...");
System.out.println("checking bag...");
Object ret = method.invoke(realStudent);
System.out.println("finished...");
returnret; }}Copy the code
The bind method binds an actual object to a proxy object. The newProxyInstance method takes the first argument to the class loader of the actual object, the second argument to the interface on which the proxy object will hang, in this case the Student interface, and the third argument to the proxy class that defines the implementation method logic. So here’s this. The proxy class must override a method: invoke Here defines the implementation method logic of the proxy class.
Here is the test class code
public class StudentJdkTest {
public static void main(String[] args) {
StudentImpl realStudent = new StudentImpl("Henry");
StudentProxy studentProxy = newStudentProxy(); Student student = (Student) studentProxy.bind(realStudent); student.goToSchool(); }}Copy the code
Output result:
checking uniforms...
checking bag...
Henry is on the way to school....
finished...
Copy the code
CGLIB dynamic proxy
In some cases, the JDK dynamic proxy becomes unusable when the interface cannot be generated, and a third-party proxy is needed, CGLIB being a good choice.
Implementing proxy classes
package Chapter2;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class StudentProxyCGLIB implements MethodInterceptor {
public Object getProxy(Class cls, String name){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(cls);
enhancer.setCallback(this);
Class[] argumentTypes = new Class[1];
Object[] arguments = new Object[1];
argumentTypes[0] = String.class;
arguments[0] = name;
return enhancer.create(argumentTypes,arguments);
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("checking uniforms...");
System.out.println("checking bag...");
Object ret = methodProxy.invokeSuper(o, null);
System.out.println("finished...");
returnret; }}Copy the code
CGLIB sets up the superclass proxy via enhancer with the callback class this. Test class code
package Chapter2;
public class StudentCDLIBTest {
public static void main(String[] args) {
StudentProxyCGLIB studentProxyCGLIB = new StudentProxyCGLIB();
StudentImpl student = (StudentImpl) studentProxyCGLIB.getProxy(StudentImpl.class, "Henry"); student.goToSchool(); }}Copy the code
Same as above.