zoukankan      html  css  js  c++  java
  • Java动态代理

    1.首先,什么是代理(中介)

    目标对象/被代理对象 ------- 房主:真正有租房子方法的人

    代理对象 -------------------- 黑中介:有租房子的方法(负责调用房主的租房子方法)

    执行代理对象方法的对象 ---- 租房的人

    流程:我们要租房----->中介(租房的方法)------>房主(租房的方法)

    抽象:调用对象----->代理对象------>目标对象


    使用代理的好处:可以在执行目标对象方法的前后执行自己的加工或其它逻辑。类似黑中介在原租房费上要再加钱,本来目标方法返回值房价是1000,黑中介可以返回值房价+300,就是1300了。


    2.动态代理

    动态代理:刚刚上图中的代理对象不需要手动编写了,不需要一一编写与目标对象相同的方法,这个过程,在运行时的内存中动态生成代理对象。------字节码对象级别的代理对象

    动态代理的API:

    在jdk的API中存在一个Proxy中存在一个生成动态代理的的方法newProxyInstance

    static Object

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

    返回值:Object就是代理对象

    参数:loader:代表与目标对象相同的类加载器-------目标对                                     象.getClass().getClassLoader()

    interfaces:代表与目标对象实现的所有的接口字节码对象数组

    h:具体的代理的操作,InvocationHandler接口

    注意:JDK的Proxy方式实现的动态代理 目标对象必须有接口 没有接口不能实现jdk版动态代理

    举个使用的例子:

    目标接口:

    public interface TargetInterface {
    
    	public void method1();
    	public String method2();
    	public int method3(int x);
    }

    目标对象Target.java:

    public class Target implements TargetInterface{
    	@Override
     public void method1() {
    System.out.println("method1 running...");}@Overridepublic String method2() {System.out.println("method2 running...");return "method2";}@Overridepublic int method3(int x) {return x;}}
    
    使用ProxyTest.java:
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    import org.junit.Test;
    
    public class ProxyTest {
    
    	@Test
    	public void test1(){
    		//获得动态的代理对象----在运行时 在内存中动态的为Target创建一个虚拟的代理对象
    		//objProxy是代理对象 根据参数确定到底是谁的代理对象
    		TargetInterface objProxy = (TargetInterface) Proxy.newProxyInstance(
    				Target.class.getClassLoader(), //与目标对象相同的类加载器
    				new Class[]{TargetInterface.class}, //接口
    				new InvocationHandler() {
    					//invoke 代表的是执行代理对象的方法
    					@Override
    					//method:代表目标对象的方法字节码对象
    					//args:代表目标对象的响应的方法的参数
    					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    						System.out.println("目标方法前的逻辑");
    						//执行目标对象的方法
    						Object invoke = method.invoke(new Target(), args);
    						System.out.println("目标方法后的逻辑");
    						return invoke;
    					}
    				}
    			);
    		
    		objProxy.method1();
    		String method2 = objProxy.method2();
    		System.out.println(method2);
    		
    	}
    	
    }


  • 相关阅读:
    Mysql之正则匹配
    定时任务之elastic-job概述
    清晰讲解LSB、MSB和大小端模式及网络字节序
    极光消息推送多环境配置
    基于TSUNG对MQTT进行压力测试-测试结果
    基于TSUNG对MQTT进行压力测试-基础概念温习
    阻塞式/非阻塞式与同步/异步的区别
    干货!Jenkins下配置findbugs、pmd及checkstyle实现代码自动检测
    jar包
    java环境变量及Eclipse自动编译问题
  • 原文地址:https://www.cnblogs.com/chz-blogs/p/9380930.html
Copyright © 2011-2022 走看看