实现动态代理需要解决的问题
- 如何根据加载到内存中的被代理类,动态的创建一个代理类及其对象?
- 当通过被代理类的对象调用方法a时,如何动态的去调用被代理类中的同名方法a?
实现过程
1.创建代理类和被代理类要实现的接口:
2.创建被代理类,继承接口,实现其中的方法
3.创建代理工厂类,实现一个能够返回代理对象的方法:getProxyInstance(),传入的参数是被代理类。将此方法声明为static,可直接通过类来调用此方法。
在此方法中需要创建一个类实现InvocationHandler接口,实现其中的抽象方法的具体实现invoke()方法,该方法体现动态的性质,当我们通过代理类的对象调用方法a时,就会自动调用invoke()方法,创建代理类 对象的时候会传入一个MyInvocationHandler类型的对象,使得调用代理类方法的时候,里面自动的找参数对应对象中的方法,都是封装好的。
4.使用代理类来调用被代理类中的方法
整体代码
package com.gdx.java1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author gdx
* @create 2021-03-13 21:24
* 动态代理举例
*/
interface Human{
String getBrief();
void eat(String food);
}
//被代理类
class SuperMan implements Human{
@Override
public String getBrief() {
return null;
}
@Override
public void eat(String food) {
System.out.println("喜欢吃食物"+food);
}
}
//代理工厂类
class ProxyFactory{
//调用此方法返回一个代理类的对象
public static Object getProxyInstance(Object obj){//obj是被代理类的对象
MyInvocationHandler handler=new MyInvocationHandler();
handler.bind(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),handler);
}
}
class MyInvocationHandler implements InvocationHandler{
//需要使用被代理类的对象进行赋值
private Object obj;
public void bind(Object obj){
this.obj=obj;
}
//当我们通过代理类的对象调用方法a时,就会自动调用如下的方法:invoke()
//将被代理类将要执行的方法a的功能声明在invoke中
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//method:即为代理类对象要调用的方法,此方法也就作为了被代理类对象要调用的方法
//obj:被代理类对象
Object returnValue=method.invoke(obj,args);
//上述方法的返回值就作为当前类中invoke()方法的返回值。
return returnValue;
}
}
public class ProxyTest {
public static void main(String[] args) {
SuperMan superMan = new SuperMan();
//proxyInstance:代理类的对象,动态创建代理类对象
Human proxyInstance = (Human)ProxyFactory.getProxyInstance(superMan);
//当通过代理类对象调用同名方法时,会自动调用被代理类中的同名方法
String brief = proxyInstance.getBrief();
System.out.println(brief);
proxyInstance.eat("牛奶面包");
}
}