Java高级之动态代理
动态代理的实现
1.创建接口
2.创建被代理类,需要重写接口类
3.创建代理类和代理类对象
测试
Java动态代理是Java反射机制的一种应用,它可以在运行时动态生成代理类,实现对原对象的代理。Java动态代理主要利用 java.lang.reflect包中的 Proxy类和 InvocationHandler接口来实现。通过这种方式,我们可以为对象添加额外的行为,而无需修改其源代码。
动态代理的实现
动态代理的实现需要三部分,第一部分是接口和被代理类,被代理类实现了接口的功能,第二部分是代理类对象,由ProxyFactory类的getProxyInstance方法创建。
关键类和接口
InvocationHandler接口: 这是一个接口,必须实现其invoke方法,代理对象的所有方法调用都会转发到这个方法。
Proxy类: 这是一个用来创建代理对象的类,提供了静态方法newProxyInstance来生成代理对象。
1.创建接口
public interface Human{
public String getBelief();
void eat(String food);
}
2.创建被代理类,需要重写接口类
public class SuperMan implements Human{
public String getBelief() {
return "I am a supermannnnnn!!!!";
}
public void eat(String food) {
System.out.println("I love to eat" + food);
}
}
3.创建代理类和代理类对象
想要实现动态代理,要解决两个问题:
问题一 如何根据加载到内存中的被代理类(SuperMan),动态地创建一个代理类以及代理类对象
问题二 当通过代理类的对象调用方法时,如何动态的去调用被代理类(SuperMan)中的同名方法
Proxy类
public class ProxyFactory{
//调用getProxyInstance 返回一个代理类的对象(解决问题一)
public static Object getProxyInstance(Object obj){ //obj:被代理类的对象 根据obj(被代理类)动态的创建一个代理类
MyInvocationHandler handler = new MyInvocationHandler();
//newProxyInstance():第一个参数是classLoader,用来创建实例,第二个参数是getInterfaces,用来获取被代理类的接口
//handler用来调用被代理类的方法。
handler.bind(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),handler);
}
}
InvocationHandler接口:
public class MyInvocationHandler implements InvocationHandler{
private Object obj; //需要使用被代理类的对象赋值
public void bind(Object obj){
this.obj = obj;
}
//当我们通过代理类对象调用方法a时,就会通过Proxy.newProxyInstance()方法的最后一个参数,调用到这里的invoke方法,通过反射,来调用被代理类的方法
//将被代理类要执行的方法a的功能声明在invoke中
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//method即为代理类对象调用的方法,也作为了被代理类对象要调用的方法
//obj:被代理类的对象
Object invoke = method.invoke(obj, args);
//上述方法的返回值作为当前类中invoke的返回值
return invoke;
}
}
当我们通过代理类对象调用方法a时,就会通过Proxy.newProxyInstance()方法的最后一个参数,调用到这里的invoke方法,通过反射,来调用被代理类的方法。如果需要新增一些功能,需要在InvocationHandler接口的实现类中编写。
测试
public class ProxyTest {
public static void main(String[] args) {
SuperMan superMan = new SuperMan();
//通过ProxyFactory的getProxyInstance方法创建代理类的对象
Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan);
//调用方法时,会自动调用被代理类的同名方法
String belief = proxyInstance.getBelief();
System.out.println(belief);
proxyInstance.eat("apple");
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。