什么是代理呢,就好比经纪人和演员的关系,有些事情不用演员做,经纪人就直接动手了,也就是说在不访问被代理类的情况下去调用其相关方法。
Java代理分为静态代理和动态代理
静态代理就是和被代理类实现统一接口,然后调用其方法,如果我们在编译时就知道是代理哪个对象 就可以使用静态代理
首先创建一个接口Animal
/**
* @author chunying
*/
public interface Animal {
void eat();
void run();
}
然后是实现类Cat
/**
* @author chunying
*/
//被代理类
public class Cat implements Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void run() {
System.out.println("喵喵叫");
}
}
静态代理类
/**
* @author chunying
*/
public class StaticProxy implements Animal{
private Animal animal;
public StaticProxy(Animal animal) {
this.animal = animal;
}
@Override
public void eat() {
animal.eat();
}
@Override
public void run() {
animal.run();
}
}
测试
@Test
public void fun3() {
Cat c = new Cat();
StaticProxy staticProxy = new StaticProxy(c);
staticProxy.eat();
staticProxy.run();
}
最终输出
猫吃鱼
喵喵叫
接下来看动态代理
Animal 和 Cat不变
代理对象需要实现InvocationHandler接口 实现方法invoke
/**
* @author chunying
*/
public class MyInvocationHandler implements InvocationHandler{
private Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
method.invoke(target, args);
return null;
}
}
我们在执行被代理类的方法时 最终都是调用了这个方法,所以可以在这个类中对方法进行一些扩展
测试
@Test
public void fun2() {
Cat cat = new Cat();
Class<?>[] interfaces = cat.getClass().getInterfaces();
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(cat);
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Animal proxy = (Animal)Proxy.newProxyInstance(classLoader, interfaces, myInvocationHandler);
proxy.eat();
proxy.run();
}
最终输出是一样的 这里我们创建了一个代理对象,调用了Proxy.newProxyInstance()
这个方法有三个参数,第一个是指定的类加载器,第二个是指明被代理类实现的接口,第三个这是一个方法委托类,我们通过代理调用被代理类的方法时,就可以将方法名和方法参数都委托给这个委托类。
所以有了类加载器,实现的方法,代理的对象,这样执行一个被代理类的方法就很简单了。

本文深入讲解Java代理模式,包括静态代理和动态代理的概念、实现方式及应用场景。通过具体示例,展示如何创建代理对象,调用被代理类的方法,并进行方法的扩展。

被折叠的 条评论
为什么被折叠?



