Proxy mode (static proxy, dynamic proxy, Cglib proxy)

Proxy mode (Proxy)

Basic introduction to proxy mode

  1. Proxy mode: provide one for an objectsubstituteTo control access to this object.The target object is accessed through the proxy objectThe advantages of this are :Based on the realization of the target object, additional functional operations can be enhanced, that is, the function of the target object can be expanded

  2. The object being proxied can beRemote objectCreate expensive objects or objects that require security control

  3. There are different forms of agency mode, there are three main typesStatic proxy, dynamic proxy (JDK proxy, interface proxy) and Cglib proxy(You can dynamically create objects in memory without implementing interfaces, it belongs to the category of dynamic agents).

  4. Schematic diagram of proxy mode
    Insert picture description here

Static proxy

Basic introduction to static code mode

When using a static proxy, you need to define an interface or a parent class. The proxy object (that is, the target object) and the proxy object implement the same interface or inherit the same parent class.

Applications

  • Specific requirements
  1. Define an interface: ITeacherDao

  2. The target object TeacherDAO implements the interface ITeacherDAO

  3. Using static proxy mode, you need to implement ITeacherDAO in the proxy object TeacherDAOProxy

  4. When calling, the target object is called by calling the method of the proxy object.

  5. special reminder: The proxy object and the target object should be realizedSame interfaceAnd then by callingThe same methodTo call the method of the target object

  • Idea analysis diagram (class diagram)
    Insert picture description here
    TeacherDao (target class) aggregates to the proxy class (TeacherDaoProxy) through the interface

  • Code

Client .java: client

public class Client {
    
    

	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		//创建目标对象(被代理对象)
		TeacherDao teacherDao = new TeacherDao();
		
		//创建代理对象, 同时将被代理对象传递给代理对象
		TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);
	
		//通过代理对象,调用到被代理对象的方法
		//即:执行的是代理对象的方法,代理对象再去调用目标对象的方法 
		teacherDaoProxy.teach();
	}

}

ITeacherDao.java: proxy interface

//接口
public interface ITeacherDao {
    
    	
	void teach(); // 授课的方法
}

TeacherDao.java: target class

public class TeacherDao implements ITeacherDao {
    
    

	@Override
	public void teach() {
    
    
		// TODO Auto-generated method stub
		System.out.println(" 老师授课中  。。。。。");
	}

}

TeacherDaoProxy.java: proxy class

//代理对象,静态代理
public class TeacherDaoProxy implements ITeacherDao{
    
    
	
	private ITeacherDao target; // 目标对象,通过接口来聚合
		
	//构造器
	public TeacherDaoProxy(ITeacherDao target) {
    
    
		this.target = target;
	}

	@Override
	public void teach() {
    
    
		// TODO Auto-generated method stub
		System.out.println("开始代理  完成某些操作。。。。。 ");//方法
		target.teach();
		System.out.println("提交。。。。。");//方法
	}

}

Advantages and disadvantages of static proxy

  1. Advantages: Without modifying the function of the target object, the target function can be extended through the proxy object

  2. Disadvantages: becauseThe proxy object needs to implement the same interface as the target object, so there will be many proxy classes

  3. Once the interface adds methods, the target object and proxy object must be maintained

Dynamic proxy

Basic introduction to dynamic proxy mode

  1. The proxy object does not need to implement the interface, but the target object must implement the interface, Otherwise you cannot use dynamic proxy

  2. Generation of proxy objects,It uses the JDK API, Dynamically build proxy objects in memory

  3. Dynamic proxy is also called: JDK proxy, interface proxy

API for generating proxy objects in JDK

  1. The package of the proxy class: java.lang.reflect.Proxy

  2. JDK implementation of the proxy only needs to use the newProxyInstance method, but the method needs to receive three parameters. The complete writing is:

 static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )

Dynamic proxy application examples

  • Application example requirements

Improve the previous static proxy into a dynamic proxy mode (ie: JDK proxy mode)

  • Idea diagram (class diagram)

Insert picture description here

  • Code

Client

public class Client {
    
    

	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		//创建目标对象
		ITeacherDao target = new TeacherDao();
		
		//给目标对象,创建代理对象, 可以转成 ITeacherDao
		ITeacherDao proxyInstance = (ITeacherDao)new ProxyFactory(target).getProxyInstance();
	
		// proxyInstance=class com.sun.proxy.$Proxy0 内存中动态生成了代理对象
		System.out.println("proxyInstance=" + proxyInstance.getClass());
		
		//通过代理对象,调用目标对象的方法
		//proxyInstance.teach();
		
		proxyInstance.sayHello(" tom ");
	}

}

interface:

//接口
public interface ITeacherDao {
    
    

	void teach(); // 授课方法
	void sayHello(String name);
}

Target class

public class TeacherDao implements ITeacherDao {
    
    

	@Override
	public void teach() {
    
    
		// TODO Auto-generated method stub
		System.out.println(" 老师授课中.... ");
	}

	@Override
	public void sayHello(String name) {
    
    
		// TODO Auto-generated method stub
		System.out.println("hello " + name);
	}
	
}

Proxy class

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyFactory {
    
    

	//维护一个目标对象 , Object
	private Object target;

	//构造器 , 对target 进行初始化
	public ProxyFactory(Object target) {
    
    
		
		this.target = target;
	} 
	
	//给目标对象 生成一个代理对象
	public Object getProxyInstance() {
    
    
		
		//说明
		/*
		 *  public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
                                          
            //1. ClassLoader loader : 指定当前目标对象使用的类加载器, 获取加载器的方法固定
            //2. Class<?>[] interfaces: 目标对象实现的接口类型,使用泛型方法确认类型
            //3. InvocationHandler h : 事情处理,执行目标对象的方法时,会触发事情处理器方法, 会把当前执行的目标对象方法作为参数传入
		 */
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), 
				new InvocationHandler() {
    
    
					
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
						// TODO Auto-generated method stub
						System.out.println("JDK代理开始~~");
						//反射机制调用目标对象的方法
						Object returnVal = method.invoke(target, args);
						System.out.println("JDK代理提交");
						return returnVal;
					}
				}); 
	}
	
	
}

Cglib proxy

Basic introduction to Cglib proxy mode

  1. Both static proxy and JDK proxy mode require the target object to implement an interface, but sometimesThe target object is just a single object, And does not implement any interface. At this time, you can use the target object subclass to implement the proxy-this is the Cglib proxy

  2. The Cglib agent is also called a subclass agent. It builds a subclass object in memory to extend the function of the target object. Some books also attribute Cglib agent to dynamic agent

  3. Cglib is a powerful high-performance code generation package that can extend java classes and implement java interfaces during runtime. It is widely used by many AOP frameworks, such as Spring AOP, to implement method interception

  4. How to choose the proxy mode in AOP programming:
    4.1. The target object needs to implement the interface, use JDK to proxy
    4.2. The target object does not need to implement the interface, use Cglib to proxy

  5. The bottom layer of the Cglib package is to convert bytecode and generate new classes by using bytecode processing framework ASM

Cglib proxy mode implementation steps

  1. Need to introduce the jar file of cglib
    Insert picture description here

  2. Build subclasses dynamically in memory. Note that the proxy class cannot be final, otherwise an error
    java.lang.IllegalArgumentException:

  3. If the method of the target object is final/static, it will not be intercepted, that is, the additional business methods of the target object will not be executed.

Cglib proxy mode application example

 Application example requirements
Realize the previous case with Cglib proxy mode
 Idea diagram (class diagram)
Insert picture description here
 Code realization + Debug source code [to be debug]

Client:

public class Client {
    
    

	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		//创建目标对象
		TeacherDao target = new TeacherDao();
		//获取到代理对象,并且将目标对象传递给代理对象
		TeacherDao proxyInstance = (TeacherDao)new ProxyFactory(target).getProxyInstance();

		//执行代理对象的方法,触发intecept 方法,从而实现 对目标对象的调用
		String res = proxyInstance.teach();
		System.out.println("res=" + res);
	}

}

Proxy class

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class ProxyFactory implements MethodInterceptor {
    
    

	//维护一个目标对象
	private Object target;
	
	//构造器,传入一个被代理的对象
	public ProxyFactory(Object target) {
    
    
		this.target = target;
	}

	//返回一个代理对象:  是 target 对象的代理对象
	public Object getProxyInstance() {
    
    
		//1. 创建一个工具类
		Enhancer enhancer = new Enhancer();
		//2. 设置父类
		enhancer.setSuperclass(target.getClass());
		//3. 设置回调函数
		enhancer.setCallback(this);
		//4. 创建子类对象,即代理对象
		return enhancer.create();
		
	}
	

	//重写  intercept 方法,会调用目标对象的方法
	@Override
	public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
    
    
		// TODO Auto-generated method stub
		System.out.println("Cglib代理模式 ~~ 开始");
		Object returnVal = method.invoke(target, args);
		System.out.println("Cglib代理模式 ~~ 提交");
		return returnVal;
	}

}

Target class

public class TeacherDao {
    
    

	public String teach() {
    
    
		System.out.println(" 老师授课中  , 我是cglib代理,不需要实现接口 ");
		return "hello";
	}
}

Introduction to several common proxy modes-several variants

  1. Firewall proxy The
    internal network penetrates the firewall through a proxy to achieve access to the public network.

  2. Caching proxy For
    example: when requesting resources such as image files, first go to the caching proxy to fetch it, if the resource is fetched, then ok, if the resource is not fetched, then fetch it from the public network or database, and then cache.

  3. Remote agent
    The local representative of the remote object,It can call the remote object as a local object. Remote agents communicate information with real remote objects through the network.

  4. Synchronization agent: mainly used in multi-threaded programming to complete synchronization work between multiple threads
    Synchronous agent: mainly used in multi-threaded programming to complete synchronization work between multiple threads

Guess you like

Origin blog.csdn.net/weixin_46168350/article/details/111087989