您的位置:首页 > 编程语言 > Java开发

JAVA反射(三)之动态代理

2017-11-17 22:43 225 查看

什么是动态代理

我所理解的动态代理是:在程序运行过程中,在内存中动态委托一个代理对象,来执行目标对象的方法,并且可以增强目标方法;

为什么要用动态代理

为什么要用动态代理:Java属于静态语言,所以在编译之后不能对类中的方法和属性修改,而利用动态代理可以在程序运行中可以增强某些目标对象的方法,以及实现一些过滤功能;

Proxy的获取以及参数的含义

java.lang.reflect.Proxy 类:可以看出Proxy对象在reflect包下,所以,肯定和反射有关系

用Proxy获取动态代理对象

Object objProxy = Proxy.newProxyInstance(
loader,//目标对象的类加载器
interfaces,//与目标对象共同实现的接口
h//InvocationHandler接口,或者InvocationHandler的实现类,用于实现代理,下面详细讲
);


InvocationHandler接口

每个代理实例都有一个关联的调用处理程序。

*在代理实例上调用方法时,该方法

*调用被编码并分派到{@code invoke}

*其调用处理程序的方法。

此接口只有一个方法

public Object invoke(//代理该方法被调用的代理实例

Object proxy, //代理对象

Method method, //目标方法的字节码对象

Object[] args//目标方法的参数列表
);


实现动态代理的步骤

1.获取动态代理

Object objProxy = Proxy.newProxyInstance(classLoder,interfaces,h);


2.用代理对象操作目标对象的方法

objProxy .method();


用一个demo来实现步骤



package com.tangbaobao.reflect;

/**
* @author 唐学俊
* @version
4000
创建时间:2017年11月17日 下午3:14:42
* 共有接口
*/
public interface TargetInterface {
public void method1();

public String method2();

public int method3(int a);

}


package com.tangbaobao.reflect;
/**
* @author 唐学俊
* @version 创建时间:2017年11月17日 下午3:15:25
* 目标对象实现类
*/
public class Target implements TargetInterface{

@Override
public void method1() {
System.out.println("method1 running....");
}

@Override
public String method2() {
System.out.println("method2 running");
return "method2";
}

@Override
public int method3(int a) {
System.out.println("method3 running ....");
return a;
}

}


package com.tangbaobao.reflect;

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

import org.junit.jupiter.api.Test;

/**
* @author 唐学俊
* @version 创建时间:2017年11月17日 下午3:17:02
* 测试方法
*/
public class ProxyTest {
@Test
public void test1() {
// 获取动态代理对象objProxy
TargetInterface objProxy = (TargetInterface) Proxy.newProxyInstance(
Target.class.getClassLoader(), // 类加载器
new Class[] { TargetInterface.class },
new InvocationHandler() {
@Override
//invok代表执行代理对象的方法
//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);
}
}


运行结果



package com.tangbaobao.reflect;

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

/**
* @author 唐学俊
* @version 创建时间:2017年11月17日 下午3:50:50
*
*/
public class ProxyTest2 {
public static void main(String[] args) {
Target  target = new Target();
//代理对象
TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {

@Override
//invoke执行几次,看代理对象调用方法几次
//代理对象调用接口方法都是调用invoke
//proxy代理对象
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

System.out.println("参数列表:"+args);
Object invoke = method.invoke(target, args);

return invoke;
}
}
);
proxy.method1();//调用invoke
proxy.method2();//调用invoke
int method3 = proxy.method3(100);
System.out.println(method3);
}
}


总结

动态代理是一种设计模式:可以增强方法,实现过滤…
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: